Print Screen alle 5 Sek



  • Waldii schrieb:

    warum fenster? will ja vom ganzen desktop den screen speichern!

    Dann nimmst du als Fenster einfach NULL. Siehe auch im Forum VCL/CLX --> FAQ --> Screenshot.



  • 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.


Anmelden zum Antworten