CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别
来源:互联网 发布:前瞻数据 编辑:程序博客网 时间:2024/06/14 17:20
你可以参考 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)
我想 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.csdn.net/topics/20268542
0 0
- CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别
- CWnd与Hwnd的区别
- CWnd与HWND的区别
- CWnd与HWND的区别
- CWnd
- CWnd
- CWnd
- CWnd
- CWnd
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- CWnd与HWND的区别与转换
- Java基础学习之——类的继承extends
- linux makefile学习笔记(4)
- Reference for Robotium
- BSTR、_bstr_t与CString、char *转换
- 【微信开发】微信公众号开发 之 编辑模式使用
- CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别
- Java Web开发——整体框架了解与构建
- hive安装
- 2012年蓝桥杯预选赛-微生物增殖(我有疑问)
- hdu 3790 最短路径问题
- nginx http proxy接收响应过程(一)
- 操作文件
- Zabbix2.2.2源码安装部署排错以及MySQL数据库监控实例
- BUPT OJ93 中序遍历序列