无法释放 HBITMAP,内存泄漏使用 CreateDIBitmap
Can't release HBITMAP, memory leaking using CreateDIBitmap
我正在使用 CreateDIBitmap() 并且总是通过 DeleteObject() 释放它。
我在滑块移动时使用它,我注意到每次使用的内存都在增加。
这是我从索引位图数据创建 HBITMAP 的函数:
HBITMAP APP_Make_HBITMAP_From_Bitmap_Indexed(int _width, int _height, u_int32* _table_ptr, u_int8* _index_ptr)
{
// window bitamp structure - to use with window API
struct sAPP_Windows_Bitmap
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
};
sAPP_Windows_Bitmap tmp_w_bitmap;
tmp_w_bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
tmp_w_bitmap.bmiHeader.biWidth = _width;
tmp_w_bitmap.bmiHeader.biHeight = -1 * _height;
tmp_w_bitmap.bmiHeader.biPlanes = 1;
tmp_w_bitmap.bmiHeader.biBitCount = 8;
tmp_w_bitmap.bmiHeader.biCompression = BI_RGB;
tmp_w_bitmap.bmiHeader.biSizeImage = 0;
tmp_w_bitmap.bmiHeader.biXPelsPerMeter = 0;
tmp_w_bitmap.bmiHeader.biYPelsPerMeter = 0;
tmp_w_bitmap.bmiHeader.biClrUsed = 256;
tmp_w_bitmap.bmiHeader.biClrImportant = 0;
for (unsigned int i = 0; i < 256; i++)
{
tmp_w_bitmap.bmiColors[i].rgbRed = (_table_ptr[i] >> 8) & 0x0ff;
tmp_w_bitmap.bmiColors[i].rgbGreen = (_table_ptr[i] >> 16) & 0x0ff;
tmp_w_bitmap.bmiColors[i].rgbBlue = (_table_ptr[i] >> 24) & 0x0ff;
}
return CreateDIBitmap(GetDC(APP_hWnd), &tmp_w_bitmap.bmiHeader, CBM_INIT, _index_ptr, (BITMAPINFO*)&tmp_w_bitmap, DIB_RGB_COLORS);
}
以上函数在WM_HSCROLL消息中使用:
case WM_HSCROLL:
{
LRESULT slider_pos = SendMessage(GetDlgItem(_hwnd, IDS_DC_SLIDER), TBM_GETPOS, 0, 0);
wchar_t output[4];
wsprintf(output, L"%ld", slider_pos);
SetWindowText(GetDlgItem(_hwnd, IDS_DC_INTENSITY), output);
int intensity = _wtoi(output);
int intensity_offset = intensity * 256;
convert_hbm_texture_256 = APP_Make_HBITMAP_From_Bitmap_Indexed(256, 256, convert_table + intensity_offset, convert_index);
RedrawWindow(_hwnd, NULL, NULL, RDW_INVALIDATE);
}
break;
在 WM_PAINT 中:消息我正在显示位图并释放它
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(_hwnd, &ps);
EndPaint(_hwnd, &ps);
// display 256 preview
PAINTSTRUCT ps_texture_256;
HDC hdc_texture_256 = BeginPaint(GetDlgItem(_hwnd, IDS_DC_TEXTURE_256), &ps_texture_256);
HDC hdc_tmp_256 = CreateCompatibleDC(hdc_texture_256);
SelectObject(hdc_tmp_256, convert_hbm_texture_256);
BitBlt(hdc_texture_256, 0, 0, 256, 256, hdc_tmp_256, 0, 0, SRCCOPY);
DeleteDC(hdc_tmp_256);
DeleteObject(convert_hbm_texture_256);
EndPaint(GetDlgItem(_hwnd, IDS_DC_TEXTURE_256), &ps_texture_256);
return (INT_PTR)TRUE;
}
解释:
我正在使用滑块在具有不同强度的颜色表中移动。
每次我移动滑块时,我的应用程序的内存使用量都会增加 -
我不知道为什么,因为我正在释放 DeleteObject(convert_hbm_texture_256);每次显示后。
请注意,我也在使用相同的功能APP_Make_HBITMAP_From_Bitmap_Indexed
在我的应用程序的不同部分工作正常并且没有内存问题。
但在这种情况下,我只使用了一次(在拖放之后)。
提前致谢..
您肯定在 APP_Make_HBITMAP_From_Bitmap_Indexed
中存在设备上下文的 GDI 泄漏:
return CreateDIBitmap(GetDC(APP_hWnd), &tmp_w_bitmap.bmiHeader, CBM_INIT, _index_ptr, (BITMAPINFO*)&tmp_w_bitmap, DIB_RGB_COLORS);
您调用 GetDC
,但从未调用 ReleaseDC
。使用一些 GDI 泄漏检测工具检查整个应用程序是个好主意,例如 GDIView or Deleaker.
WM_PAINT 处理程序应该处理调用 window 过程的 window。这样的处理程序必须以单个 BeginPaint 开始并以单个 EndPaint 结束。
您的处理程序处理两个 windows。
SelectObject returns 旧对象的句柄。您必须 select 稍后再回来。
我正在使用 CreateDIBitmap() 并且总是通过 DeleteObject() 释放它。 我在滑块移动时使用它,我注意到每次使用的内存都在增加。
这是我从索引位图数据创建 HBITMAP 的函数:
HBITMAP APP_Make_HBITMAP_From_Bitmap_Indexed(int _width, int _height, u_int32* _table_ptr, u_int8* _index_ptr)
{
// window bitamp structure - to use with window API
struct sAPP_Windows_Bitmap
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
};
sAPP_Windows_Bitmap tmp_w_bitmap;
tmp_w_bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
tmp_w_bitmap.bmiHeader.biWidth = _width;
tmp_w_bitmap.bmiHeader.biHeight = -1 * _height;
tmp_w_bitmap.bmiHeader.biPlanes = 1;
tmp_w_bitmap.bmiHeader.biBitCount = 8;
tmp_w_bitmap.bmiHeader.biCompression = BI_RGB;
tmp_w_bitmap.bmiHeader.biSizeImage = 0;
tmp_w_bitmap.bmiHeader.biXPelsPerMeter = 0;
tmp_w_bitmap.bmiHeader.biYPelsPerMeter = 0;
tmp_w_bitmap.bmiHeader.biClrUsed = 256;
tmp_w_bitmap.bmiHeader.biClrImportant = 0;
for (unsigned int i = 0; i < 256; i++)
{
tmp_w_bitmap.bmiColors[i].rgbRed = (_table_ptr[i] >> 8) & 0x0ff;
tmp_w_bitmap.bmiColors[i].rgbGreen = (_table_ptr[i] >> 16) & 0x0ff;
tmp_w_bitmap.bmiColors[i].rgbBlue = (_table_ptr[i] >> 24) & 0x0ff;
}
return CreateDIBitmap(GetDC(APP_hWnd), &tmp_w_bitmap.bmiHeader, CBM_INIT, _index_ptr, (BITMAPINFO*)&tmp_w_bitmap, DIB_RGB_COLORS);
}
以上函数在WM_HSCROLL消息中使用:
case WM_HSCROLL:
{
LRESULT slider_pos = SendMessage(GetDlgItem(_hwnd, IDS_DC_SLIDER), TBM_GETPOS, 0, 0);
wchar_t output[4];
wsprintf(output, L"%ld", slider_pos);
SetWindowText(GetDlgItem(_hwnd, IDS_DC_INTENSITY), output);
int intensity = _wtoi(output);
int intensity_offset = intensity * 256;
convert_hbm_texture_256 = APP_Make_HBITMAP_From_Bitmap_Indexed(256, 256, convert_table + intensity_offset, convert_index);
RedrawWindow(_hwnd, NULL, NULL, RDW_INVALIDATE);
}
break;
在 WM_PAINT 中:消息我正在显示位图并释放它
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(_hwnd, &ps);
EndPaint(_hwnd, &ps);
// display 256 preview
PAINTSTRUCT ps_texture_256;
HDC hdc_texture_256 = BeginPaint(GetDlgItem(_hwnd, IDS_DC_TEXTURE_256), &ps_texture_256);
HDC hdc_tmp_256 = CreateCompatibleDC(hdc_texture_256);
SelectObject(hdc_tmp_256, convert_hbm_texture_256);
BitBlt(hdc_texture_256, 0, 0, 256, 256, hdc_tmp_256, 0, 0, SRCCOPY);
DeleteDC(hdc_tmp_256);
DeleteObject(convert_hbm_texture_256);
EndPaint(GetDlgItem(_hwnd, IDS_DC_TEXTURE_256), &ps_texture_256);
return (INT_PTR)TRUE;
}
解释:
我正在使用滑块在具有不同强度的颜色表中移动。 每次我移动滑块时,我的应用程序的内存使用量都会增加 - 我不知道为什么,因为我正在释放 DeleteObject(convert_hbm_texture_256);每次显示后。
请注意,我也在使用相同的功能APP_Make_HBITMAP_From_Bitmap_Indexed 在我的应用程序的不同部分工作正常并且没有内存问题。 但在这种情况下,我只使用了一次(在拖放之后)。
提前致谢..
您肯定在 APP_Make_HBITMAP_From_Bitmap_Indexed
中存在设备上下文的 GDI 泄漏:
return CreateDIBitmap(GetDC(APP_hWnd), &tmp_w_bitmap.bmiHeader, CBM_INIT, _index_ptr, (BITMAPINFO*)&tmp_w_bitmap, DIB_RGB_COLORS);
您调用 GetDC
,但从未调用 ReleaseDC
。使用一些 GDI 泄漏检测工具检查整个应用程序是个好主意,例如 GDIView or Deleaker.
WM_PAINT 处理程序应该处理调用 window 过程的 window。这样的处理程序必须以单个 BeginPaint 开始并以单个 EndPaint 结束。
您的处理程序处理两个 windows。
SelectObject returns 旧对象的句柄。您必须 select 稍后再回来。