CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别

本文详细介绍了MFC中用于从HWND中获取CWnd指针的Handle机制,包括FromHandle和FromHandlePermanent的区别及应用场景。特别关注了在非Extension DLL中创建窗口时可能遇到的问题及解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

你可以参考 MFC 代码中 FromHandle 和 FromHandlePermanent 的实现,这两个函数都是在公共的 CMapHandle 中查找句柄对应的 CWnd 对象(通过一个CBT钩子,CWnd 对象将创建时得到的句柄和自己的指针纪录到 CMapHandle),区别是如果找不到相关的对象,FromHandle 在CMapHandle 的 temporarylist 中创建并返回一个临时对象的指针 ,而 FromHandlePermanent 返回 NULL(此外 FromHandlePermanent 不使用 temporarylist ,所以不查找 temporarylist 下的句柄)。

我想 MFC 引入这个机制的原因是需要从 WindowProc、钩子或 API 返回的 HWND 值中得到“正确”的 CWnd 指针,比如 CMainFrame, CView 的指针。因为需要从这些指针调用 CWnd 的虚函数(如PreTranslateMessage),这些虚函数可能被重载过。

大部分情况下,对任意句柄使用 FromHandle 是不错的,因为大多情况下只利用返回的 CWnd 指针调用的非虚函数,返回的即使是一个临时对象,调用也是正确的(MFC 中较少用 FromHandlePermanent,除非确定句柄是由本线程创建的或不需要创建临时对象)。

但是在某些情况下,比如从使用 MFC 的非 Extension DLL 中创建的窗口,这个机制会有问题,因为窗口创建在其他的 MFC 模块之下,在 EXE 中调用 FromHandle,由于该模块的 CMapHandle 对象某有相关的纪录,所以只能得到临时对象,如果使用返回的指针调用 CWnd 的虚函数如 PreTranslateMessage,得到调用的是 CWnd::PreTranslateMessage,而不是 DLL 中的 CWnd 派生类重载过的 CWnd::PreTranslateMessage。我觉得 “FromHandle 有可能失效”这种情况是 MFC 中 Bug 的主要来源。

关于 CMapHandle 的描述可以参考 MFC 代码中的以下函数和结构:
_AFX_MODULE_THREAD_STATE,CThreadLocal
CHandleMap* PASCAL afxMapHWND(BOOL bCreate)
LRESULT CALLBACK _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
BOOL CWinThread::PreTranslateMessage(MSG* pMsg)

BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)

转自:http://bbs.youkuaiyun.com/topics/20268542

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值