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?