有时delete GDI+类型的对象会报错.
例如
Bitmap * pBitmap = new Bitmap;
...
delete pBitmap;
正常来说是不会错误的.
但是要确保在 GdiplusShutdown(gdiplusToken)之前delete.
那当然了.
但是容易出现陷阱, 例如下面代码
// 这是VC基于Dialog的工程, 一般都是按照下面的格式使用GDI+, 在CTestDlg中就用到GDI+的各种类.
BOOL CTestApp::InitInstance()
{
…
// GDI+ 初始化
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CTestDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此处放置处理何时用“确定”来关闭
// 对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用“取消”来关闭
// 对话框的代码
}
//关闭gdiplus的环境
GdiplusShutdown(gdiplusToken);
// 由于对话框已关闭,所以将返回FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
问题就出在CTestDlg中的GDI+的使用.
假设你在CTestDlg的构造函数中new一个GDI+对象.
你大多数会在CTestDlg的析构函数中把该GDI+对象中delete.
问题就来了.
CTestDlg的析构函数是什么时候被调用的.
在 BOOL CTestApp::InitInstance()的return FALSE 之后.
但析构CTestDlg之前 GdiplusShutdown(gdiplusToken);已经被调用了
此时delete GDI+的对象就会报错.
简单解决方法
BOOL CTestApp::InitInstance() { … // GDI+ 初始化 GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); { CTestDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: 在此处放置处理何时用“确定”来关闭 // 对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用“取消”来关闭 // 对话框的代码 } } //关闭gdiplus的环境 GdiplusShutdown(gdiplusToken); // 由于对话框已关闭,所以将返回FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }

本文探讨了在使用GDI+时可能遇到的资源释放问题,特别是在对话框类CTestDlg的生命周期内正确管理GDI+对象的重要性。文章提供了一个示例代码片段,展示了如何通过调整代码结构避免在关闭GDI+环境后删除GDI+对象导致的错误。
271

被折叠的 条评论
为什么被折叠?



