If more than one monitor is connected to the PC (for example, a laptop with an additional screen connected via D-SUB or HDMI), how to capture the screen exactly on the one on which the cursor is now? Or can you somehow capture all monitors at once into an individual buffer for each?
Capturing an image of the main desktop is done as follows:
unsigned int Screen::GetMetrics(unsigned int *width, unsigned int *height){ *width = GetSystemMetrics(SM_CXSCREEN); *width-= (*width%4); *height = GetSystemMetrics(SM_CYSCREEN); *height-= (*height%4); return (*width * *height * 3); } unsigned int Screen::Grab(unsigned char **frame, unsigned int *timing){ // Defining screen dimensions unsigned int start = GetTickCount(); unsigned int width, height, size = GetMetrics(&width, &height); unsigned char *framebuf = nullptr; if( size ){ // Creating contexts HDC ScreenDC = GetDC(0); HDC MemoryDC = CreateCompatibleDC(ScreenDC); // Lock object (for multithread use) WaitForSingleObject(M_Screen, INFINITE); // Filling image header struct BitmapInfo.bmiHeader.biWidth = width; BitmapInfo.bmiHeader.biHeight = -height; BitmapInfo.bmiHeader.biSizeImage = width * height * BitmapInfo.bmiHeader.biBitCount / 8; HBITMAP hBitmap = CreateDIBSection(ScreenDC,&BitmapInfo,DIB_RGB_COLORS,(void**)&framebuf,0,0); SelectObject(MemoryDC, hBitmap); BitBlt(MemoryDC, 0, 0, width, height, ScreenDC, 0, 0, SRCCOPY); // Get cursor info CURSORINFO CursorInfo; CursorInfo.cbSize = sizeof(CursorInfo); if( GetCursorInfo(&CursorInfo) ){ ICONINFO IconInfo; GetIconInfo(CursorInfo.hCursor, &IconInfo); DeleteObject(IconInfo.hbmColor); DeleteObject(IconInfo.hbmMask); DrawIcon(MemoryDC, CursorInfo.ptScreenPos.x - IconInfo.xHotspot, CursorInfo.ptScreenPos.y - IconInfo.yHotspot, CursorInfo.hCursor); } ReleaseDC(NULL,ScreenDC); DeleteDC(MemoryDC); // Writing data and clearing buffers memcpy(*frame, framebuf, size); DeleteObject(hBitmap); ReleaseMutex(M_Screen); } // if need to know capture elapsed time if( timing != nullptr){*timing = GetTickCount() - start;} return size; }