1

I use a function which captures a screen using the BitBlt mehtod and can then return a HBITMAP.

int screenCapture() {
    int width = 1000;
    int height = 700;

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);

    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = width;
    bitmap.bmiHeader.biHeight = -height;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 24;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = 0;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap);
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
    ReleaseDC(HWND_DESKTOP, hdc);
    DeleteDC(hdcTemp);
    return (int)bitPointer[0];
}

Here, the function only returns the first value of the pixels array.
Actually, it works fine.

for (int i = 0; i >= 0; i++) {
        cout << i << ": " << screenCapture() << endl;
    }

But when I try to loop this, an error is generated after a few hundred rounds (a little over 900 for me), an Access violation reading location error.

I also noticed that if I reduced the values of width and height, then the error took longer to be called.

I am a true beginner and I do not know where the error may come, but it would look like a memory problem, right?

4

1 回答 1

4

正如评论中所述,您正在泄漏您的HBITMAP,以及在您调用之前HBITMAP已经存在的原件。无论何时使用,都必须始终恢复原始值(您不拥有它)。HDCSelectObject()SelectObject()

并且不要忘记进行错误检查!

尝试这个:

int screenCapture()
{
    int result = -1;

    int width = 1000;
    int height = 700;

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    if (hdc != NULL)
    {
        hdcTemp = CreateCompatibleDC(hdc);
        if (hdcTemp != NULL)
        {
            BITMAPINFO bitmap;
            bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
            bitmap.bmiHeader.biWidth = width;
            bitmap.bmiHeader.biHeight = -height;
            bitmap.bmiHeader.biPlanes = 1;
            bitmap.bmiHeader.biBitCount = 24;
            bitmap.bmiHeader.biCompression = BI_RGB;
            bitmap.bmiHeader.biSizeImage = 0;
            bitmap.bmiHeader.biClrUsed = 0;
            bitmap.bmiHeader.biClrImportant = 0;

            HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)&bitPointer, NULL, NULL);
            if (hBitmap != NULL)
            {
                HBITMAP hPrevBitmap = SelectObject(hdcTemp, hBitmap);

                BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
                result = (int) bitPointer[0];

                SelectObject(hdcTemp, hPrevBitmap);
                DeleteObject(hBitmap);
            }

            DeleteDC(hdcTemp);
       }

       ReleaseDC(HWND_DESKTOP, hdc);
    }

    return result;
}
于 2014-10-03T20:54:53.237 回答