удаление HBITMAP вызывает нарушение прав доступа во время выполнения - PullRequest
3 голосов
/ 21 марта 2010

У меня есть следующий код, чтобы сделать снимок экрана с окном и получить в нем цвет определенного пикселя:

void ProcessScreenshot(HWND hwnd){

HDC WinDC;
HDC CopyDC;
HBITMAP hBitmap;
RECT rt;

GetClientRect (hwnd, &rt);
WinDC = GetDC (hwnd);
CopyDC = CreateCompatibleDC (WinDC);

//Create a bitmap compatible with the DC
hBitmap = CreateCompatibleBitmap (WinDC,
    rt.right - rt.left, //width
    rt.bottom - rt.top);//height

SelectObject (CopyDC, hBitmap);

BitBlt (CopyDC,   //destination
    0,0,
    rt.right - rt.left, //width
    rt.bottom - rt.top, //height
    WinDC,    //source
    0, 0,
    SRCCOPY);       

COLORREF col = ::GetPixel(CopyDC,145,293);

// Do some stuff with the pixel colour.... 

delete hBitmap;

ReleaseDC(hwnd, WinDC);
ReleaseDC(hwnd, CopyDC);

}

строка 'delete hBitmap;'вызывает ошибку времени выполнения: нарушение прав доступа.Я думаю, я не могу просто так его удалить?

Поскольку растровые изображения занимают много места, если я от этого не избавлюсь, я получу огромную утечку памяти.Мой вопрос таков: освобождение DC от HBITMAP связано с этим, или оно остается неизменным даже после того, как я выпустил DC?Если позже дело обстоит так, как мне правильно избавиться от HBITMAP?

Ответы [ 2 ]

8 голосов
/ 21 марта 2010

Вы должны уничтожать объекты GDI с DeleteObject, а не delete. Последний используется только для освобождения объектов, выделенных с помощью new.

3 голосов
/ 21 марта 2010

delete следует использовать только для освобождения объектов, выделенных с помощью new.

HBITMAP - дескриптор растрового изображения, и вам необходимо освободить связанный объект с помощью функции GDI DeleteObject.

Строго говоря, вы должны сохранить результат SelectObject от того момента, когда вы выбрали растровое изображение в контексте устройства, и передать его другому вызову SelectObject, чтобы гарантировать, что растровое изображение не используется контекстом устройства, когда выЗвоните DeleteObject.Ситуация часто работает, если вы этого не делаете, особенно если вы все равно собираетесь выпустить контекст устройства, но это безопаснее всего сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...