你可以参考 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.csdn.net/topics/20268542

CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别相关推荐

  1. CWnd::Create和CWnd::CreateEx 区别

    1. CWnd::CreateEx定义 BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowNam ...

  2. CWnd与HWND的区别与联系(相互转换)完全解析

    区别 首先,从这两个单词的第一个字母即可知道两者之间的差别.熟悉MFC的人都知道在MFC中,类基本上都是以C开头的,这是一种规则约定,目的就是让人一看就知道它是一个类! 因此,CWnd第一个字母C指的 ...

  3. CWND和HWND之间的关系和转换 和获取方法

    CWnd与HWND的区别 一.区别 HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是m_hWnd. HWND是Windows系统中对所有窗口的一种标识,即窗口句柄.这是一个 ...

  4. MFC_Session2

    MFC包含的基本四个类 框架类 应用程序类 文档类 视图类 MFC程序运行启动 AFX_MODULE_STATE aaa;//当前程序模块状态信息aaa(臆造的名字) AFX_MODULE_THREA ...

  5. SystemTray.cpp

    SystemTray.cpp _tcscpy _tcscpy 把参2复制到参1并返回参1 _tcscpy是一个拷贝字符串,源字符串指针是strSource,有strcpy.wcscpy._mbscpy ...

  6. GetDlgItem的用法小结

    GetDlgItem用于获得指定控件ID的窗体指针,函数原型如下: HWND GetDlgItem(HWND hDlg,int nIDDlgItem );CWnd* GetDlgItem(int nI ...

  7. CWnd和HWND的区别

            所有控件类都是CWnd类的派生类,CWnd的所有成员函数在控件类中都可以使用.在MFC中,CWnd类是一个很重要的类,它封装了Windows的窗口句柄HWND.在Windows编程中, ...

  8. HINSTANCE/HWND/CWnd/HANDLE 的区别

    HINSTANCE是应用程序实例句柄, HWND是窗口对象句柄, HANDLE是任意对象的句柄, CWnd是MFC中的窗口类. MSDN里面对于HINSTANCE的解释是"handle   ...

  9. INSTANCE/HWND/CWnd/HANDLE区别

    HINSTANCE是应用程序实例句柄, HWND是窗口对象句柄, HANDLE是任意对象的句柄, CWnd是MFC中的窗口类. MSDN里面对于HINSTANCE的解释是"handle   ...

最新文章

  1. 如何打赢一场唯快不破的比赛,看看他们的绝招
  2. 日志组件DotNetCommon.Filelog
  3. spring框架(三)mvc
  4. 一晚浓浓的程序员鸡汤,先干为敬
  5. Android ProgressBar手动控制开始和停止
  6. html5 content type,Content-Type一览
  7. TCP如何实现可靠性传输
  8. sqlplus登录、连接命令
  9. julia linux下载位置,在 Ubuntu 上安装 Julia
  10. 机器学习分析租房价格的影响因素
  11. Fingerprint has already been taken
  12. 小球落地c语言编程答案,c语言模拟小球落地
  13. 苹果手机的定向广告时代告终
  14. MySQL 8.0.17 第一次登录并修改密码
  15. 如何将notepad++设置为默认打开方式
  16. 图文结合带你搞懂InnoDB MVCC
  17. 互联网巨头前沿科技产品一览
  18. 布局技巧(等高、圣杯)
  19. Verilog十大基本功7 (IC设计经典书籍)
  20. 【Eclipse AST】AST与ASTView简介

热门文章

  1. Obsidian 0x01:Obsidian 双链
  2. 我用纯C语言开发的中英文混合分词服务器3.0正式发布,词库190多万词,每秒切分5万+,同时提供 c、java、C#、delphi、js调用范例
  3. 基于java植物大全智能识别系统设计与实现
  4. Oracle10g 基本命令
  5. 产品分析报告—哔哩哔哩
  6. Excel2Latex 实操步骤(1)
  7. 业界关注中药创新 古典名方目录急盼出台
  8. 努力是为了让自己不平庸
  9. 人人开源后台项目maven构建(yyds)
  10. Android 5.x浏览器webView或者qqX5崩溃,Resources$NotFoundException:String resource ID #0x2040003