【发布时间】:2014-02-10 09:15:36
【问题描述】:
我在我们庞大的应用软件中发现了 GDI 漏洞。
下面是一个简单的程序来测试这个问题。 想法是主对话框打开另一个对话框(对话框A)。 如果对话框 A 包含 CStatic 控件的位图函数, 它会造成 GDI 泄漏。
即使我使用“DeleteObject(bitmap)”。
我做错了什么吗? 你有什么想法吗?
谢谢。
// Resource File
...
DIALOG_BOXA DIALOGEX 0, 0, 219, 142
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_BORDER
EXSTYLE WS_EX_STATICEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,46,121,50,14
PUSHBUTTON "Cancel",IDCANCEL,119,121,50,14
CONTROL 131,RED_LIGHT0,"Static",SS_BITMAP,7,17,80,37
PUSHBUTTON "",RED_LIGHT1,7,60,80,37,BS_BITMAP | NOT WS_TABSTOP
END
// head file
DialogBoxA: public CDialog
{
...
CStatic m_static;
CButton m_button ;
...
}
/////////////////////////////////////////////////////////
void DialogBoxA::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, RED_LIGHT0, m_static);
DDX_Control(pDX, RED_LIGHT1, m_button);
}
BOOL DialogBoxA::OnInitDialog()
{
CDialog::OnInitDialog();
HBITMAP bitmap ;
// This will create GDI leak !!!
bitmap = LoadBitmap ( AfxGetApp()->m_hInstance,BEACON_BIG_RED_ON) ;
m_static.SetBitmap (bitmap );
DeleteObject(bitmap);
// This is OK !!!
bitmap = LoadBitmap ( AfxGetApp()->m_hInstance,BEACON_BIG_RED_ON) ;
m_button.SetBitmap (bitmap );
DeleteObject(bitmap);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
【问题讨论】:
-
你如何确定有泄漏?
-
另外,MSDN 声明您应该使用 LoadImage 而不是 LoadBitmap ...您尝试过更改吗?
-
感谢您的回复。是的,我使用“GDIView”和“Windows 任务管理器”来监控这个,我发现打开“DialogBoxA”后“GDI 对象”增加了。
-
谢谢,我试试“LoadImage”,同样的问题。
-
打开对话框时 GDI 对象应该增加。尝试注释掉你的代码行,你可能会发现它做同样的事情......你认为他们如何绘制这些按钮等!??
标签: visual-c++ memory-leaks gdi