当前位置: 首页 > news >正文

Windows对象、句柄与MFC对象

Windows对象是以句柄来标识的,对应的MFC类就是这些句柄的C++包装。内存中的Windows对象一定有唯一的句柄来标识,但不一定有对应的MFC类对象在内存中。当需要获取Windows对象的对应MFC类对象而内存中又没有此对象时,系统会创建一个临时MFC类对象返回给用户,并在之后某个空闲时刻进行回收。

 
  Windows对象句柄及其对应的MFC类如下表所示:

HWND

CWnd及派生类

HDC

CDC及派生类

HMENU

CMenu

HPENHBRUSHHFONTHBITMAPHPALETTEHRGN

CGdiObject

HIMAGELIST

CImageList

SOCKET

CSocket


  如果你拥有上面的任何一个Windows对象句柄,你可以调用对应类的静态成员函数 FromHandle来查找对应的MFC对象 (系统为每个线程维护了一个从Windows对象句柄到MFC对象的映射,一个持久的map和一个临时的map);如果你拥有上面的MFC对象,你也可以 通过MFC类的公有成员变量来获取对应的Windows对象句柄
 
  例如,给定一个HWND类型的句柄hWnd,可以通过

CWnd::FromHandle(hWnd)

来获得CWnd对象的指针。如果hWnd没有对应的CWnd对象,则系统会产生一个临时CWnd对象与hWnd关联,并返回该对象的指针。在获得CWnd对象后,你可以通过CWnd的公有成员m_hWnd获得窗口对象的句柄。
 
  如果在调用FromHandle时产生临时MFC对象,句柄和MFC对象之间的映射被保存在系统的临时map中。默认情况下,CWinThread::OnIdle自动为那些支持临时句柄映射的MFC类调用DeleteTempMap函数。在DeleteTempMap函数中,这些临时对象将被取消与句柄的关联,然后被销毁。
 
  如果你拥有一个Windows对象句柄,那么你可以创建一个对应的MFC对象,然后把该MFC对象与该Windows对象句柄进行关联。此时,该MFC对象与Windows对象相互建立起映射关系。
 
  例如,对于如下代码:

CWnd  myWnd;

myWnd.Attach(hWnd);

将建立起hWnd到myWnd的映射。此后,你调用CWnd::FromHandle(hWnd)将返回myWnd对象的指针。如果myWnd对象被销毁,它的析构函数将自动通过调用DestroyWindow来销毁该hWnd所指Windows对象。如果该行为不是所期望的,则需要在myWnd销毁之前调用 Detach成员函数解除两者之间的关联(映射) ,如 myWnd.Detach()。
 
   所有临时MFC对象和持久(permanent)MFC对象都是以线程为单位进行维护管理的。也就是说,一个线程不能够访问另一个线程的MFC包装类对象,不管它是临时的还是持久的。
 
  为了在不同的线程间传递这些Windows对象,总是应该通过HANDLE类型传递。从一个线程向另一个线程传递MFC包装对象将可能引起不可预料的结果。
 
  由于MFC包装类对象是以线程为单位进行管理的,因此,在程序中的不同线程中可能有多个MFC对象与同一个句柄对应。

相关文章:

  • C++结构体
  • C++ 指针运算符( 和 *)
  • C++中 引用与取地址的区别
  • C/C++语言中函数参数传递的三种方式(x,*x,x)
  • VC 和 VS 区别
  • 什么是Windows API
  • c++类与对象用多文件编写以及vs的操作步骤
  • DUMPBIN工具的使用
  • DLL的创建和使用(含代码)
  • _T() 函数
  • DirectUI
  • 托管与非托管
  • 什么是回调函数?
  • ShowWindow与UpdateWindow
  • VS2015无法打开源文件#include “iostream.h“的解决方法
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • codis proxy处理流程
  • es6(二):字符串的扩展
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • ES6简单总结(搭配简单的讲解和小案例)
  • Facebook AccountKit 接入的坑点
  • javascript 总结(常用工具类的封装)
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JSONP原理
  • nodejs实现webservice问题总结
  • PAT A1120
  • vue 配置sass、scss全局变量
  • 对JS继承的一点思考
  • 容器服务kubernetes弹性伸缩高级用法
  • 微服务框架lagom
  • 写给高年级小学生看的《Bash 指南》
  • 学习ES6 变量的解构赋值
  • Hibernate主键生成策略及选择
  • 数据库巡检项
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ![CDATA[ ]] 是什么东东
  • #宝哥教你#查看jquery绑定的事件函数
  • (2)STL算法之元素计数
  • (6)设计一个TimeMap
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (k8s中)docker netty OOM问题记录
  • (Python第六天)文件处理
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (第27天)Oracle 数据泵转换分区表
  • (二)windows配置JDK环境
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (原)本想说脏话,奈何已放下
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)jQuery 基础
  • (转载)Google Chrome调试JS
  • (转载)虚函数剖析
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .Net Remoting(分离服务程序实现) - Part.3