При использовании Visual Studio 2017, vc141, следующий код должен получить скриншот из фронтального игрового окна, но теперь он возвращает черно-пустое изображение.
только проблема с играми (пробовал OpenGL и Vulkan, огл вернуть черный, вулкан вернуть белый)
перед обновлением до windows 10 1703 работает на windows 10 1607 и windows 7 sp1
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
код:
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 дублирования рабочего стола.
Других решений пока нет …