C++ BitBlt内存泄漏

C++ BitBlt内存泄漏,c++,winapi,memory-leaks,bitmap,bitblt,C++,Winapi,Memory Leaks,Bitmap,Bitblt,我正在使用BitBlt在按钮上显示位图。对于大多数情况来说,这很好,但是内存泄漏会导致程序在一段时间后崩溃。我做错了什么 int Springboard::DrawBasicButtons(DRAWITEMSTRUCT* pdis, HINSTANCE hInstance){ RECT rect; static HBITMAP hCurrIcon, hIconoff, hIconon; rect = pdis->rcItem; HFONT font = C

我正在使用BitBlt在按钮上显示位图。对于大多数情况来说,这很好,但是内存泄漏会导致程序在一段时间后崩溃。我做错了什么

int Springboard::DrawBasicButtons(DRAWITEMSTRUCT* pdis, HINSTANCE hInstance){
    RECT rect;
    static HBITMAP hCurrIcon, hIconoff, hIconon;
    rect = pdis->rcItem;

    HFONT font = CreateFont(13, 0, 0, 0, 300, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Arial");
    TCHAR Txtstr[MAX_PATH];
    BOOL isText = FALSE;
    int textsize;

    if (IDC_HOLD == pdis->CtlID) {
        hIconoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(BASIC_HOLDOFF));
        hIconon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(BASIC_HOLDON));
        _tcscpy( Txtstr, _T("Hold      "));
        isText = TRUE;
        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hIconon;
        else hCurrIcon = hIconoff;
    }

    HDC hdc = CreateCompatibleDC(pdis->hDC);
    SelectObject(hdc, hCurrIcon);

    BitBlt(pdis->hDC,0, 0,ICON_WIDTH,ICON_HEIGHT, hdc, 0, 0, SRCCOPY);

    if(isText == TRUE){
        textsize = _tcslen(Txtstr);
        SetTextColor(pdis->hDC, RGB(230,230,230));
        HFONT hFontOld = (HFONT) SelectObject(pdis->hDC, font);
        DrawText(pdis->hDC, Txtstr, textsize, &pdis->rcItem, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
        SelectObject( pdis->hDC, hFontOld );
    }

    DeleteDC(hdc);
    DeleteBitmap(hCurrIcon);
    DeleteBitmap(hIconoff);
    DeleteBitmap(hIconon);
    font = NULL;

    return(RET_OK);
}

在调用
DeleteDC()
之前,需要将旧对象选择回
HDC


另外,您似乎没有清理由
CreateFont()

返回的
HFONT
,在调用
deleteddc()
之前,您需要将旧对象选择回
HDC


此外,您似乎没有清理由
CreateFont()

返回的
HFONT
,在上面的示例中,您选择了一个对象[~line 21,22]:

   HDC hdc = CreateCompatibleDC(pdis->hDC);
                                  SelectObject(hdc, hCurrIcon);  // (*1)
稍后,您选择了一个对象

`(if (isText == TRUE))`

     HFONT hFontOld = (HFONT) SelectObject(pdis->hDC, font);
      DrawText(pdis->hDC, Txtstr, textsize, &pdis->rcItem, DT_SINGLELINE |  DT_VCENTER | DT_RIGHT);
并恢复了上一个。反对

    SelectObject( pdis->hDC, hFontOld );
但您从未还原过第一个SelectObject()
见上文备注*1 您以前没有保存上一个(默认)对象


在上面的示例中,您选择了一个对象[~第21、22行]:

   HDC hdc = CreateCompatibleDC(pdis->hDC);
                                  SelectObject(hdc, hCurrIcon);  // (*1)
稍后,您选择了一个对象

`(if (isText == TRUE))`

     HFONT hFontOld = (HFONT) SelectObject(pdis->hDC, font);
      DrawText(pdis->hDC, Txtstr, textsize, &pdis->rcItem, DT_SINGLELINE |  DT_VCENTER | DT_RIGHT);
并恢复了上一个。反对

    SelectObject( pdis->hDC, hFontOld );
但您从未还原过第一个SelectObject()
见上文备注*1 您以前没有保存上一个(默认)对象

马格努斯狼疮(c)1993年

试试这个:

移动hiconoff=。。。和hiconon=。。。在if语句之外和之上。在函数结束时,它们将以任何方式被删除。您可以在修复错误后找出优化方案

在第一次运行时,hiconon和hiconoff没有设置为任何值。不要仅仅因为它们是静态数据就假定它们为空。

尝试以下方法:

移动hiconoff=。。。和hiconon=。。。在if语句之外和之上。在函数结束时,它们将以任何方式被删除。您可以在修复错误后找出优化方案


在第一次运行时,hiconon和hiconoff没有设置为任何值。不要因为它们是静态数据就假定它们为空。

可以通过阅读代码来解决这个问题,但是为了让您学会一点自给自足,我建议您开始检查错误。您调用的函数报告它们是否成功。第一步是检查。当一个失败时,问问自己为什么?通过阅读代码可以解决这个问题,但是为了让你学会一点自给自足,我建议你开始检查错误。您调用的函数报告它们是否成功。第一步是检查。当一个人失败时,问问自己为什么?