BitBlt утечка памяти
Я использую 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);
}
2 ответа
Вы должны выбрать старые объекты обратно в HDC
перед звонком DeleteDC()
,
Кроме того, кажется, вы не убираете HFONT
вернулся CreateFont()
,
В приведенном выше примере вы выбрали объект [~ строки 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 выше. Вы не сохраняли предыдущий (по умолчанию) объект ранее.
Волчанка Магнус (с) 1993
Попробуй это:
переместите hiconoff = ... и hiconon = ... за пределы оператора if и над ним. Они будут удалены в любом случае по окончании работы. Разобраться с оптимизацией можно после исправления ошибок.
При первом запуске hiconon и hiconoff ничего не настроены. Не предполагайте, что они равны нулю только потому, что это статические данные.