Print Screen alle 5 Sek
-
hi, hab ne konsolenanwendung erstellt die alle 5 sekunden einen screenshoot in eine .bmp datei speichern soll, ich verwende da einen timer! aber leider wird CaptureScreen nie aufgerufen...warum?
#include <windows.h> #include <stdio.h> #include <iostream> #include <fstream> using namespace std; UINT_PTR nTimerId=0; LPVOID pBits=NULL; static HBITMAP hDesktopCompatibleBitmap=NULL; static HDC hDesktopCompatibleDC=NULL; static HDC hDesktopDC=NULL; static HWND hDesktopWnd=NULL; #define BITSPERPIXEL 32 void SaveBitmap(char *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; LPVOID pBuf=NULL; BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; do{ hdc=GetDC(NULL); ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); if(bmpInfo.bmiHeader.biSizeImage<=0) bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; if((pBuf=malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) { MessageBox(NULL,"Unable to Allocate Bitmap Memory","Error",MB_OK|MB_ICONERROR); break; } bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS); if((fp=fopen(szFilename,"wb"))==NULL) { MessageBox(NULL,"Unable to Create Bitmap File","Error",MB_OK|MB_ICONERROR); break; } bmpFileHeader.bfReserved1=0; bmpFileHeader.bfReserved2=0; bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; bmpFileHeader.bfType='MB'; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); }while(false); if(hdc) ReleaseDC(NULL,hdc); if(pBuf) free(pBuf); if(fp) fclose(fp); } static void CALLBACK CaptureScreen(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { OPENFILENAME ofn; char szFileName[512]; strcpy(szFileName,"C:\\ScreenShot.bmp"); int nWidth=GetSystemMetrics(SM_CXSCREEN); int nHeight=GetSystemMetrics(SM_CYSCREEN); HDC hBmpFileDC=CreateCompatibleDC(hDesktopDC); HBITMAP hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight); HBITMAP hOldBitmap = (HBITMAP) SelectObject(hBmpFileDC,hBmpFileBitmap); BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); SelectObject(hBmpFileDC,hOldBitmap); SaveBitmap(ofn.lpstrFile,hBmpFileBitmap); DeleteDC(hBmpFileDC); DeleteObject(hBmpFileBitmap); SetCursor(LoadCursor(NULL,IDC_ARROW)); } int main() { BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biBitCount=BITSPERPIXEL; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biWidth=GetSystemMetrics(SM_CXSCREEN); bmpInfo.bmiHeader.biHeight=GetSystemMetrics(SM_CYSCREEN); bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biSizeImage=abs(bmpInfo.bmiHeader.biHeight)*bmpInfo.bmiHeader.biWidth*bmpInfo.bmiHeader.biBitCount/8; hDesktopWnd=GetDesktopWindow(); hDesktopDC=GetDC(hDesktopWnd); hDesktopCompatibleDC=CreateCompatibleDC(hDesktopDC); hDesktopCompatibleBitmap=CreateDIBSection(hDesktopDC,&bmpInfo,DIB_RGB_COLORS,&pBits,NULL,0); if(hDesktopCompatibleDC==NULL || hDesktopCompatibleBitmap == NULL) { MessageBox(NULL,"Unable to Create Desktop Compatible DC/Bitmap","Error",MB_OK|MB_ICONERROR); return -1; } SelectObject(hDesktopCompatibleDC,hDesktopCompatibleBitmap); nTimerId=SetTimer(NULL,12345,5000,CaptureScreen); //Timer set to 5000 ms. cin.get(); return 0; }
-
Weil du keine Message-Loop hast.
-
warum brauch ich ne message loop und wie soll sie aussehen?
ich hab ja ein cin.get(); dabei...da sollte doch bis ich keine taste druecke die timerfunktion aufgerufen werden???
-
Weil SetTimer() dafür sorgt das an dein Fenster WM_TIMER Nachrichten gesendet werden. In der MessageLoop wird dann erkannt das deine Callback-Funktion aufgerufen werden soll.
msdn: "Creating a message loop":
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/usingmessagesandmessagequeues.asp...oder in jedem WinAPI-Tutorial so ziemlich auf der erste Seite

...da du aber eigentlich eine Win32-Konsolenanwendung machen willst und kein Fenster: Wieso nimmst du nen WinAPI Timer? bzw. wozu brauchst du den überhaupt? - Macht dein Tool zwischendurch noch was anderes?
-
hm da nimm ich doch lieber einen thread mit 5 sek sleep!
cu
-
Du kannst einfach einen Timer mit Timer-Proc erstellen, das sollte am einfachsten sein.
PS: Was soll denn bitte das ?!
:do{ // [...] }while(false);
-
das ist ja mal nen geiles Konstrukt 
-
CodeFinder schrieb:
Du kannst einfach einen Timer mit Timer-Proc erstellen, das sollte am einfachsten sein.
sowas:
nTimerId=SetTimer(NULL,12345,1000,&(TIMERPROC)CaptureScreen); //Timer set to 500 ms.das ohne message loop sollte ja funktionieren?
cu
-
Joar mehr oder weniger...also bei Deinen Casts stehen mir die Haare zu Berge


nTimerId = SetTimer(NULL, 12345, 1000, CaptureScreen);
-
nTimerId = SetTimer(NULL, 12345, 1000, CaptureScreen); C/C++ Code: nTimerId = SetTimer(NULL, 12345, 1000, CaptureScreen);braucht doch trotzdem ne message loop?
-
*msdn zitier aus den Remarks zu SetTimer()*
MSDN schrieb:
When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.