window capture



  • Habe in CodeProject einen schönen Beitrag über den Festhalten eines Bildschirm-Inhalts gefunden, allerdings nur in C#.

    Wie würde man das in C++ realisieren, wenn der Handler bekannt ist?



  • Meinst du mit 'Handler' einen DC ?

    Naja egal...Guck mal hier.

    An den HDC des Displays kommst du auf jeden Fall so:

    // Dreh- und Angelpunkt ist hier natürlich hWnd:
    HDC   hDC;
    RECT  rcWindow;
    int   iWidth,
          iHeight;
    hDC = GetWindowDC(hWnd);
    GetWindowRect(hWnd, &rcWindow);
    iWidth  = rcWindow.right - rcWindow.left;         
    iHeight = rcWindow.bottom - rcWindow.top;
    
    dc2bitmap(hDC, iWidth, iHeight, TEXT("Bitmap.bmp"));
    
    ReleaseDC(hWnd, hDC);
    


  • Nein, der den Handler, der sich auf die Applikation bezieht.

    HWMD hwnd;

    Bin im übrigen ein Stück weitergekommen. Mit diesen Funktionen lässt, sich, wenn man den Handler hat (wie er OpenProcess odgl. gegeben wird), der Inhalt des Bildes abspeichern.
    Eine unschöne Einschränkung: Das Window muss während des Aufrufs in den Vordergrund gesetzt werden.

    #include <windows.h>
    #include <iostream>
    #include <string.h>
    #include  <conio.h>
    #include <tchar.h>
    #include <process.h>
    #include <fstream>
    
    using namespace std;
    
    HBITMAP CopyScreenToBitmap(LPRECT lpRect)
    {
    	HDC         hScrDC, hMemDC;         // screen DC and memory DC     
    //	HBITMAP     hBitmap; //, 
    //	HBITMAP     hBitmap;
    //	HBITMAP     hOldBitmap;    // handles to deice-dependent bitmaps     
    	int         nX, nY, nX2, nY2;       // coordinates of rectangle to grab     
    	int         nWidth, nHeight;        // DIB width and height     
    	int         xScrn, yScrn;           // screen resolution      
    
    	HGDIOBJ     hOldBitmap , hBitmap;
    
    		// check for an empty rectangle 
        if (IsRectEmpty(lpRect))       
    	   return NULL;      
    	   // create a DC for the screen and create     
    	   // a memory DC compatible to screen DC          
    
       hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);     
       hMemDC = CreateCompatibleDC(hScrDC);      // get points of rectangle to grab  
    
       nX = lpRect->left;     
       nY = lpRect->top;     
       nX2 = lpRect->right;     
       nY2 = lpRect->bottom;      // get screen resolution      
    
       xScrn = GetDeviceCaps(hScrDC, HORZRES);     
       yScrn = GetDeviceCaps(hScrDC, VERTRES);      
    
       //make sure bitmap rectangle is visible      
    
       if (nX < 0)         
    	  nX = 0;     
    
       if (nY < 0)         
          nY = 0;     
    
       if (nX2 > xScrn)         
          nX2 = xScrn;     
    
       if (nY2 > yScrn)         
          nY2 = yScrn;      
    
       nWidth = nX2 - nX;     
       nHeight = nY2 - nY;      
    
       // create a bitmap compatible with the screen DC     
    
       hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);      
    
       // select new bitmap into memory DC     
    
       hOldBitmap =   SelectObject (hMemDC, hBitmap);      
    
       // bitblt screen DC to memory DC     
    
       BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);     
    
       // select old bitmap back into memory DC and get handle to     
       // bitmap of the screen          
    
       hBitmap = SelectObject(hMemDC, hOldBitmap);      
    
       // clean up      
    
       DeleteDC(hScrDC);     
       DeleteDC(hMemDC);      
    
       // return handle to the bitmap      
    
       return (HBITMAP)hBitmap; 
    
    }
    
    HBITMAP CopyWindowToBitmap(HWND hWnd)
    {
    	HBITMAP     hBitmap = NULL;  // handle to device-dependent bitmap      
    	// check for a valid window handle      
    	if (!hWnd)         
    	    return NULL; 
    
        RECT    rectWnd; 
    
      ::GetWindowRect(hWnd, &rectWnd);  
        hBitmap = CopyScreenToBitmap(&rectWnd);
    
    	return hBitmap; 
    }
    
    BOOL SaveBitmap(char *name,HBITMAP bitmap)
    {
    	HDC hdcScreen;		// Device context of the screen
    	HWND hwndScreen;	// Desktop window handle
    	int i;				// Counts the number of scanlines
    	BYTE *bits;			// Pointer to the bitmap's bits
    	BITMAPINFOHEADER *info;	// Info structure about this bitmap
    	HANDLE fp;			// A file handle
    	BITMAPFILEHEADER finfo;	// File info header
    	long ctsize,imgsize,pixels;// Various sizes needed to build the file
    	DWORD dw;			// Doubleword return code
    	char *ptr;			// Pointer used to write the opening BM
    
    	hwndScreen=GetDesktopWindow();
    	hdcScreen = GetDC( hwndScreen );
    
    	info = (BITMAPINFOHEADER*)GlobalAlloc(GMEM_FIXED,sizeof(BITMAPFILEHEADER)+(1024*sizeof(RGBQUAD)));
    	info->biSize = sizeof(BITMAPINFOHEADER);
    	info->biBitCount = 0;
    
    	i = GetDIBits( hdcScreen, // handle of device context 
    			bitmap, // handle of bitmap 
    			0,			// first scan line to set in destination bitmap 
    			0,		// number of scan lines to copy 
    			NULL, // address of array for bitmap bits 
    			(BITMAPINFO*)info,		// address of structure with bitmap data 
    			DIB_RGB_COLORS // RGB or palette index
    			 );
    
    	if( (info->biBitCount!=4) &&
    		(info->biBitCount!=8) &&
    		(info->biBitCount!=24) )
    		info->biBitCount=24;
    	info->biCompression=BI_RGB;
    
    	pixels=info->biWidth*info->biHeight;
    	switch(info->biBitCount)
    	{
    		case 4:ctsize=16;imgsize=pixels/2;break;
    		case 8:ctsize=256;imgsize=pixels;break;
    		case 16:ctsize=0;imgsize=pixels*2;break;
    		case 24:ctsize=0;imgsize=pixels*3;break;
    		case 32:ctsize=0;imgsize=pixels*4;break;
    		default:
    			ReleaseDC( hwndScreen,hdcScreen );
    			return FALSE;
    	}
    
    	bits = (unsigned char*)GlobalAlloc(GMEM_FIXED,imgsize);
    
    	i = GetDIBits( hdcScreen, // handle of device context 
    			bitmap, // handle of bitmap 
    			0,			// first scan line to set in destination bitmap 
    			info->biHeight,		// number of scan lines to copy 
    			bits, // address of array for bitmap bits 
    			(BITMAPINFO*)info,		// address of structure with bitmap data 
    			DIB_RGB_COLORS // RGB or palette index
    			 );
    
    	ptr = (char *)&finfo.bfType;
    	ptr[0]='B';
    	ptr[1]='M';
    
    	finfo.bfOffBits=sizeof(BITMAPFILEHEADER)+
    		sizeof(BITMAPINFOHEADER)+
    		(sizeof(RGBQUAD)*ctsize);
    	finfo.bfSize=finfo.bfOffBits+imgsize;
    	finfo.bfReserved1=0;
        finfo.bfReserved2=0;       
    
    	fp = CreateFile(name,// pointer to name of the file 
    		GENERIC_WRITE, // access (read-write) mode 
    		0, // share mode 
    		NULL, // pointer to security attributes 
    		CREATE_ALWAYS,// how to create
    		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,// file attributes 
    		NULL // handle to file with attributes to copy 
    		);
    
    	WriteFile(fp,&finfo,sizeof(BITMAPFILEHEADER),&dw,NULL);
    	WriteFile(fp,info,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*ctsize,&dw,NULL);
    	WriteFile(fp,bits,imgsize,&dw,NULL);
    	CloseHandle(fp);
    	GlobalFree(info);
    	GlobalFree(bits);
    
    	ReleaseDC( hwndScreen,hdcScreen );
    	return TRUE;
    }
    

    Frage: Kann man den Windwos-Inhalt nicht auch dann einlesen, wenn es im Hintergrund läuft?


Anmelden zum Antworten