winapi — C ++ Снимок экрана не удался после сотен повторений в Windows: утечка памяти?

Я использую функцию, которая захватывает экран, используя 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, тогда ошибка заняла больше времени для вызова.

Я настоящий новичок, и я не знаю, где может появиться ошибка, но это выглядело бы как проблема с памятью, верно?

0

Решение

Как было указано в комментариях, вы протекаете HBITMAPа также оригинал HBITMAP это было уже в HDC прежде чем ты позвонил SelectObject(), Всякий раз, когда вы используете 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;
}
3

Другие решения