BitBlt Memory leak

941 views Asked by At

I am using BitBlt to display Bitmaps on my buttons. For most of it, it is fine, but there is a memory leak which causes the program to crash after a while. What am I doing wrong with this ?

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

There are 3 answers

0
Artem Razin On BEST ANSWER

You need to select old objects back into the HDC before calling DeleteDC().

Also, it seems you are not cleaning up a HFONT returned by CreateFont().

0
user7457230 On

In the example above you have selected an Object [~lines 21,22] :

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

Later you you have selected an Object

`(if (isText == TRUE))`

     HFONT hFontOld = (HFONT) SelectObject(pdis->hDC, font);
      DrawText(pdis->hDC, Txtstr, textsize, &pdis->rcItem, DT_SINGLELINE |  DT_VCENTER | DT_RIGHT);

and restored the prev. object

    SelectObject( pdis->hDC, hFontOld );

But you have never restored the first SelectObject()
see remark *1 above You did not save the previous (default) object before.

Lupus Magnus (c) 1993

0
Sempai On

try this:

move hiconoff = ... and hiconon = ... outside and above the if statement. They will be deleted any way at the end of function. You can figure out optimization after the bugs are fixed.

At first run hiconon and hiconoff are not set to anything. Don't assume they are null just because they are static data.