有时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;
}