【发布时间】:2015-10-29 06:33:48
【问题描述】:
根据MSDN
DeleteObject 函数删除逻辑笔、画笔、字体、位图、 区域或调色板,释放与 目的。删除对象后,指定的句柄不再是 有效。
所以一个人(我自己)会认为一旦 DeleteObject 被执行,HANDLE 就不再有效。但是,一旦我在使用其他 WinAPI 调用保存对象之前删除对象,由 ::GetObject() 检索到的对象会发生什么情况?
HFONT hFont = reinterpret_cast<HFONT>(::SendMessage(hwndCtrl, WM_GETFONT, 0, 0));
if (nullptr == hFont)
{
LOG_ERROR(L"Invalid font specified");
return false;
}
LOGFONT font = { 0 };
if (0 == ::GetObject(hFont, sizeof(font), &font))
{
LOG_ERROR(L"Failed getting font");
return false;
}
font.lfHeight = nSize;
::DeleteObject(hFont);
HFONT hFontEx = ::CreateFontIndirect(&font);
LPARAM lparam = MAKELPARAM(TRUE, 0);
WPARAM wparam = (WPARAM)(hFontEx);
SendMessage(hwndCtrl, WM_SETFONT, wparam, lparam);
如下例所示,如果我决定删除我的 HFONT,在通过 SendMessage 发送新消息之前,我会检索一些意想不到的结果,其中其他控件的字体会发生变化,就好像我生成了某种句柄泄漏。
【问题讨论】:
-
GetObject() 不返回对象,它返回对象的描述。一个 LOGFONT 在字体的情况下。删除字体不会使该结构无效。您的代码有问题,您正在破坏您没有创建的字体。事故是不可避免的。您需要依赖发送 WM_SETFONT 消息的那个窗口来了解如何自行管理字体句柄。预计会正确地做到这一点。删除 DeleteObject() 调用,这是一个错误。
-
此外,在 WM_GETFONT 中的对象被删除后,gui 对象将毫无疑问地恢复为 hDC 的默认字体的属性。