从CWnd::FromHandle获取的CWnd对象的寿命是多久?

13
根据 msdn,使用CWnd::FromHandle获取CWnd*时,

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

“日后使用” 是什么意思并不清楚。它只限于当前方法的范围吗?据我所知,Win32中没有GC!
4个回答

17

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

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


这是否意味着您可以从(可能是临时的)CWnd获取HWND并将其存储起来?然后,在需要时,您可以使用存储的HWND调用FromHandle以获取CWnd。 - Steg
3
可以,HWND 将在窗口的生命周期内保持有效。 - Phil Devaney

1

FromHandle基本上用于获取已存在的窗口对象的瞬态引用。MFC将这些引用存储在一个名为临时句柄映射的内部结构中(句柄映射是Windows HWND到MFC CWnd对象的映射,由MFC用于进行Win32调用以操作与MFC对象对应的实际Windows窗口)。为了避免该结构中的对象数量超出所有限制,MFC在空闲循环处理期间从句柄映射中删除项目。

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

-Ron


0
根据相同的MSDN说明,我会认为这意味着如果没有与提供的对象hWnd相连的CWnd,它将创建一个临时的CWnd,该临时对象可能会在作用域结束时被销毁或在其他位置调用析构函数,或者针对hWnd创建一个显式的CWnd。因此,如果您已经创建了一个CWnd,那么应该没问题,否则您可能需要非常小心地存储收到的指针。

0
通常他们只希望您在函数范围内使用此句柄,而不是将其存储为类字段,在对象的整个生命周期中都引用它。

我猜在处理相同的消息时,函数的作用域并不是那么重要。 - EFraim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接