Mekamea
Mekamea

Reputation: 13

BitBlt Memory leak

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

Upvotes: 1

Views: 961

Answers (3)

Sempai
Sempai

Reputation: 1

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.

Upvotes: -1

user7457230
user7457230

Reputation: 1

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

Upvotes: -1

Artem Razin
Artem Razin

Reputation: 1286

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().

Upvotes: 6

Related Questions