【问题标题】:deleting HBITMAP causes an access violation at runtime删除 HBITMAP 会导致运行时访问冲突
【发布时间】:2011-01-29 21:54:21
【问题描述】:

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

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;' 行导致运行时错误:访问冲突。我想我不能就这样删除它吗?

因为位图占用大量空间,如果我不摆脱它,最终会导致巨大的内存泄漏。我的问题是:发布 HBITMAP 的 DC 是否可以解决这个问题,或者即使在我发布了 DC 之后它仍然存在?如果是后者,我该如何正确摆脱HBITMAP?

【问题讨论】:

    标签: c++ windows winapi graphics gdi+


    【解决方案1】:

    delete 只能用于释放通过new 分配的东西。

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

    严格来说,您应该将选择位图时的SelectObject 的结果保存到设备上下文中,并将其传递给对SelectObject 的另一个调用,以确保在您调用时设备上下文不使用该位图DeleteObject。如果您不这样做,事情通常会奏效,尤其是当您无论如何都要释放设备上下文时,但这样做是最安全的。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-05
        • 1970-01-01
        • 1970-01-01
        • 2015-08-29
        • 2012-01-12
        相关资源
        最近更新 更多