1

BitBltメソッドを使用して画面をキャプチャし、 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];
}

ここでは、関数はピクセル配列の最初の値のみを返します。
実際、それはうまく機能します。

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

しかし、これをループしようとすると、数百ラウンド (私の場合は 900 を少し超える) 後にエラーが生成されAccess violation reading locationます。

widthまた、 と の値を減らすとheight、エラーの呼び出しに時間がかかることにも気付きました。

私は真の初心者で、どこでエラーが発生するかわかりませんが、メモリの問題のように見えますよね?

4

1 に答える 1

4

コメントで述べたように、あなたはあなたの と、あなたが呼び出す前にすでにあっHBITMAPたオリジナルを漏らしています。を使用するときはいつでも、常に元の値を復元する必要があります (所有していません)。HBITMAPHDCSelectObject()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 に答える