在Windows 10版本1703(15063.138)上bitblt失败

使用Visual Studio 2017,vc141,下面的代码应该从前面的游戏窗口获得截图,但现在它返回一个黑色和空白的图像。

只发行游戏(试过OpenGL和Vulkan,ogl返回黑色,vulkan返回白色)

在升级到Windows 10 1703之前,它适用于Windows 10 1607和Windows 7 sp1

#include  #include  #include  

码:

 BOOL ScreenShot(cv::Mat *img, HWND hWnd = NULL) { HBITMAP hBitmap; HDC hdcSys = GetDC(hWnd); HDC hdcMem = CreateCompatibleDC(hdcSys); void *ptrBitmapPixels; BITMAPINFO bi; HDC hdc; RECT rect; if (!GetWindowRect(hWnd, &rect) || (hWnd == NULL)) { return FALSE; } ZeroMemory(&bi, sizeof(BITMAPINFO)); LONG lWidth = rect.right - rect.left; LONG lHeight = rect.bottom - rect.top; bi.bmiHeader.biSize = sizeof(BITMAPINFO); bi.bmiHeader.biWidth = lWidth; bi.bmiHeader.biHeight = -lHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; hdc = GetDC(hWnd); hBitmap = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &ptrBitmapPixels, NULL, 0); SelectObject(hdcMem, hBitmap); *img = cv::Mat(lHeight, lWidth, CV_8UC4, ptrBitmapPixels, 0); BitBlt(hdcMem, 0, 0, lWidth, lHeight, hdcSys, 0, 0, SRCCOPY); //DeleteObject(hBitmap); DeleteDC(hdcMem); ReleaseDC(hWnd, hdcSys); ReleaseDC(hWnd, hdc); return TRUE; } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { /*...*/ HotKeyId = GlobalAddAtom(L"DBKGNDSCREENSHOT"); RegisterHotKey(hWnd, HotKeyId, NULL, VK_F10); /*...*/ } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { /*...*/ case WM_HOTKEY: if (wParam == HotKeyId) { cv::Mat t; HWND MainHWND; MainHWND = GetForegroundWindow(); ScreenShot(&t, MainHWND); cv::imshow("1", t); } break; /*...*/ } 

甚至还是黑色PrintWindow(至少我们有一个标题栏)

 PrintWindow(hWnd, hdcMem, 0); //BitBlt(hdcMem, 0, 0, lWidth, lHeight, hdcSys, 0, 0, SRCCOPY); 

我把这个程序发送给我的朋友(没有任何修改,他的操作系统= win7 x64),但他得到了正确的结果。

所以我该怎么做?

GDI是一项非常古老的技术,并且正逐渐被弃用。 在Windows 10上捕获桌面的更可靠方法是通过桌面复制API 。

Interesting Posts