bitblt failed on Windows 10 version 1703 (15063.13

2019-08-04 06:20发布

using Visual Studio 2017, vc141, the following code should got a screenshot from front game window but now it return a black and blank image.

only issue with games(tried OpenGL and Vulkan, ogl return black, vulkan return white)

before upgrade to windows 10 1703, it works on windows 10 1607 and windows 7 sp1

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

code:

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;
    /*...*/
}

and still black even PrintWindow(at least we got a titlebar)

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

I send this program to my friend (without any modify, his OS=win7 x64), but he got the correct result.

so what should I do?

1条回答
Summer. ? 凉城
2楼-- · 2019-08-04 06:45

GDI is a very old technology and is slowly getting deprecated. The more reliable method to capture desktop on Windows 10 would be through Desktop Duplication API.

查看更多
登录 后发表回答