【问题标题】:How does GDI::DeleteObject exactly workGDI::DeleteObject 究竟是如何工作的
【发布时间】: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 的默认字体的属性。

标签: c++ winapi gdi


【解决方案1】:

所以一个(我自己)会认为一旦 DeleteObject 被执行, HANDLE 不再有效。但是检索到的对象会发生什么 通过 ::GetObject() 一旦我删除对象,然后再保存它们 其他 WinAPI 调用?

使用 GetObject,您可以获得对象的描述,而不是新对象。句柄删除后保持不变。

如下例所示,如果我决定删除我的 HFONT,之前 通过 SendMessage 发送新消息,我会检索一些意想不到的信息 结果,其他控件更改其字体的地方,好像我会 产生了某种句柄泄漏。

如果你想发送一条删除了HFONT的消息,我想如果你将它与任何其他垃圾一起发送,结果将是相同的。

【讨论】:

    猜你喜欢
    • 2011-06-26
    • 2021-08-15
    • 2012-06-08
    • 2011-10-11
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2011-06-01
    相关资源
    最近更新 更多