删除HBITMAP会在运行时导致访问冲突

时间:2010-03-20 22:30:28

标签: c++ windows winapi graphics gdi+

我有以下代码来截取窗口的截图,并获取其中特定像素的颜色:

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);

}

第'行删除hBitmap;'导致运行时错误:访问冲突。我想我不能像那样删除它吗?

因为位图占用了大量空间,如果我没有摆脱它,我将最终导致巨大的内存泄漏。我的问题是:释放DC的HBITMAP是否处理了这个问题,或者即使在我发布DC之后它仍然存在?如果是后一种情况,我该如何正确摆脱HBITMAP?

2 个答案:

答案 0 :(得分:8)

您必须使用DeleteObject而非delete销毁GDI对象。后者仅用于释放使用new分配的对象。

答案 1 :(得分:3)

delete只应用于解除通过new分配的内容。

HBITMAP是位图句柄,您需要使用GDI函数DeleteObject释放关联对象。

严格来说,您应该将SelectObject的结果从选择位图时保存到设备上下文中,并将其传递给另一个SelectObject调用,以确保设备不使用该位图拨打DeleteObject时的上下文。如果您不这样做,事情通常会起作用,特别是如果您即将发布设备上下文,但这样做是最安全的。