使用GetLastError()== 6重复调用CreateCompatibleBitmap()最终失败

Cru*_*mmy 3 c++ winapi

我有一个程序,每秒拍摄一次屏幕截图并计算屏幕的平均颜色.但是,经过约45分钟的跑步,我的支票 if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, nScreenWith, nScreenHeight)) == NULL)

开始回来了true.一个GetLastError()回复的电话6,虽然我似乎无法找到任何关于这意味着什么的文件.

为什么数千次调用此函数的工作正常,然后突然每次调用失败?

这是我的整个功能:

COLORREF ScreenColourCapture::getScreenColour() {
    // Most of this is adapted from http://www.cplusplus.com/forum/beginner/25138/
    LPBITMAPINFO lpbi = NULL;
    HBITMAP OffscrBmp = NULL;
    HDC OffscrDC = NULL;
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HDC bitmapDC = CreateCompatibleDC(0);
    HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), nScreenWidth, nScreenHeight);
    SelectObject(bitmapDC, hBmp);
    BitBlt(bitmapDC, 0, 0, nScreenWidth, nScreenHeight, GetDC(0), 0, 0, SRCCOPY);
    if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, nScreenWidth, nScreenHeight)) == NULL) {
        int error = GetLastError();
        logging->error("CreateCompatibleBitmap failed!");
        return 0;
    }
    if ((OffscrDC = CreateCompatibleDC(bitmapDC)) == NULL) {
        logging->error("CreateCompatibleDC failed!");
        return 0;
    }
    HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp);
    BitBlt(OffscrDC, 0, 0, nScreenWidth, nScreenHeight, bitmapDC, 0, 0, SRCCOPY);
    if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER)+256 * sizeof(RGBQUAD)])) == NULL)
        return 0;
    ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER));
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    SelectObject(OffscrDC, OldBmp);

    // First, call GetDIBits with no pixel array. This way it will populate bitmapinfo for us. Then
    // call it with the pixel array and the now populated lpbi.
    GetDIBits(OffscrDC, OffscrBmp, 0, nScreenHeight, NULL, lpbi, DIB_RGB_COLORS);
    LPVOID lpvBits = new char[lpbi->bmiHeader.biSizeImage];
    GetDIBits(OffscrDC, OffscrBmp, 0, nScreenHeight, lpvBits, lpbi, DIB_RGB_COLORS);

    // Pass BMP data off for computation
    COLORREF averageColour = getMeanColourFromPixels((BYTE *)lpvBits, lpbi);

    // Wrap things up
    delete[] lpvBits;
    delete[] lpbi;
    DeleteObject(hBmp);
    DeleteObject(OldBmp);
    DeleteObject(OffscrBmp);
    ReleaseDC(GetDesktopWindow(), bitmapDC);
    DeleteDC(OffscrDC);

    return averageColour;
}
Run Code Online (Sandbox Code Playgroud)

其余的代码在这里,它的价值是什么:https://github.com/crummy/screenglow/tree/master/ConsoleApplication1

Igo*_*nik 10

您必须HDC在销毁之前取消选择位图,否则您将泄漏它.它是这样的:

HBITMAP hBmp = CreateCompatibleBitmap(...);
HBITMAP previousBitmap = (HBITMAP)SelectObject(bitmapDC, hBmp);
// ...
SelectObject(bitmapDC, previousBitmap);
DeleteObject(hBmp);
Run Code Online (Sandbox Code Playgroud)

此外,您调用GetDC(0)但不保存返回值,因此您不能ReleaseDC.此外,bitmapDCCreateCompatibleDC,创建,应删除DeleteObject,而不是ReleaseDC.