BitBlt 内存泄漏
BitBlt Memory leak
我正在使用 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()
之前,您需要 select 将旧对象放回 HDC
。
此外,您似乎没有清理 CreateFont()
返回的 HFONT
。
在上面的示例中,您选择了一个对象 [~lines 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 语句之外和上方。它们将在函数结束时以任何方式被删除。修复BUG后即可进行优化
起初运行 hiconon 和 hiconoff 没有设置任何值。不要仅仅因为它们是静态数据就假设它们为空。
我正在使用 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()
之前,您需要 select 将旧对象放回 HDC
。
此外,您似乎没有清理 CreateFont()
返回的 HFONT
。
在上面的示例中,您选择了一个对象 [~lines 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 语句之外和上方。它们将在函数结束时以任何方式被删除。修复BUG后即可进行优化
起初运行 hiconon 和 hiconoff 没有设置任何值。不要仅仅因为它们是静态数据就假设它们为空。