【问题标题】:What is the lifetime of a CWnd obtained from CWnd::FromHandle?从 CWnd::FromHandle 获得的 CWnd 的生命周期是多少?
【发布时间】:2010-12-03 00:49:54
【问题描述】:

根据msdn,当我得到一个带有 CWnd::FromHandle 的 CWnd* 时,

指针可能是临时的,不应存储以供以后使用。

我不清楚“以后使用”是什么意思。它只是当前方法的范围吗? 据我所知,Win32是没有GC的!

【问题讨论】:

    标签: mfc winapi hwnd cwnd


    【解决方案1】:

    基于相同的 MSDN 描述,我假设这意味着如果没有将 CWnd 附加到作为对象提供的 hWnd,它将创建一个临时 CWnd,一旦超出范围或析构函数,它可能会被销毁别处被调用,或者为所讨论的 hWnd 显式创建 CWnd。因此,如果您已经创建了 CWnd,则应该没问题,否则您可能需要非常小心地存储收到的指针。

    【讨论】:

      【解决方案2】:

      通常他们只希望您在函数范围内使用此句柄。并且不要将它存储为一个类字段,您可以在对象的整个生命周期中引用它。

      【讨论】:

      • 函数的范围不如我猜的处理相同消息时那么大。
      【解决方案3】:

      MFC 维护了许多句柄映射,从 HWND 到 CWnd,从 HDC 到 CDC 等,它们存储在线程状态中。每个句柄映射都包含一个永久映射和临时映射 - 当您调用 CWnd::Create 或 CDC::Attach 等方法时会添加永久条目,而在没有永久条目。

      在空闲处理期间(在 CWinApp::OnIdle 中)清除临时条目,因此它们只能在处理当前消息时安全地使用。一旦您返回消息循环,或进入另一个模式循环(例如通过调用 DoModal),它们可能会被删除。

      【讨论】:

      • 这是否意味着您可以从(可能是临时的)CWnd 获取 HWND 并将其存储?然后,稍后在需要时,您可以使用存储的 HWND 调用 FromHandle 以获取 CWnd。
      • 是的,没关系,HWND 将在窗口的生命周期内有效。
      【解决方案4】:

      FromHandle 主要用于获取对现有窗口对象的临时引用。 MFC 将这些引用存储在称为临时句柄映射的内部结构中(句柄映射是 Windows HWND 到 MFC CWnd 对象的映射,MFC 使用该映射进行 Win32 调用以操作 MFC 对象对应的实际 Windows 窗口)。为了避免此结构中的对象数量增长超出所有范围,在 MFC 的空闲循环处理期间从句柄映射中删除项目。

      您可能已经猜到了,还有一个永久句柄映射不会有这种自动清理行为。如果您需要获取一个未将其 HWND 引用放入临时句柄映射的 CWnd 对象,您可以调用 FromHandlePermanent()。

      -罗恩

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 2010-09-27
        • 2016-05-16
        • 1970-01-01
        相关资源
        最近更新 更多