MFC返回的临时对象指针成因?

在MFC中从一个线程工作函数中向窗口发送消息(this指针的妙用) 前一段时间使用MFC写程序的时候,为了实现从一个窗口向另一个窗口发送消息,使用过下面两种方法 /*方法一:通过用SDK的标准API来查找其他对话框窗口返回句柄,并且发送信息 HWND hWnd;  //通过SDK的FindWindow函数得到目标窗口的句柄,TriTest为 阅读详情

 http://www.cppblog.com/flyingxu/archive/2006/07/10/9663.html

http://topic.youkuaiyun.com/t/20040402/10/2916681.html

 

问题:

msdn在介绍GetDlgItem的时候,明确指出:  
The  returned  pointer  may  be  temporary  and  should  not  be  stored  for  later  use.  
如果真是这样那我不惨了!在我的一个软件中,因为常常要使切换按钮的可用与不可用以及改变按钮文字,所以我用DetDlgItem把它们存了起来,用的时候直接到数组里面取,这样的话这个软件不是犯了一个重大的错误了?可是用这么久也没出错。  
另外,它也是说可能是临时的,那一定在某种情况下不是临时的,高手能不能解释一下这个问题?  

 

解答:

---------------------------------------------------------------  
//    Most  Windows  objects  are  represented  with  a  HANDLE,  including  
//            the  most  important  ones,  HWND,  HDC,  HPEN,  HFONT  etc.  
//    We  want  C++  objects  to  wrap  these  handle  based  objects  whenever  we  can.  
//    Since  Windows  objects  can  be  created  outside  of  C++  (eg:  calling  
//            ::CreateWindow  will  return  an  HWND  with  no  C++  wrapper)  we  must  
//            support  a  reasonably  uniform  mapping  from  permanent  handles  
//            (i.e.  the  ones  allocated  in  C++)  and  temporary  handles  (i.e.  
//            the  ones  allocated  in  C,  but  passed  through  a  C++  interface.  
//    We  keep  two  dictionaries  for  this  purpose.    The  permanent  dictionary  
//            stores  those  C++  objects  that  have  been  explicitly  created  by  
//            the  developer.    The  C++  constructor  for  the  wrapper  class  will  
//            insert  the  mapping  into  the  permanent  dictionary  and  the  C++  
//            destructor  will  remove  it  and  possibly  free  up  the  associated  
//            Windows  object.  
//    When  a  handle  passes  through  a  C++  interface  that  doesn't  exist  in  
//            the  permanent  dictionary,  we  allocate  a  temporary  wrapping  object  
//            and  store  that  mapping  into  the  temporary  dictionary.  
//    At  idle  time  the  temporary  wrapping  objects  are  flushed  (since  you  better  
//            not  be  holding  onto  something  you  didn't  create).  
//  
 
 
在CWinThread::OnIdle里调用AfxUnlockTempMaps,AfxUnlockTempMaps会释放temporary  maps.  
 
所以不要保留GetDlgItem等返回的临时指针,可以直接保存HWND  objects,然后CWnd::FromHandle获取临时指针来用。  
 
---------------------------------------------------------------  
 
临时包装对象会在空闲时间删除.在同一函数中多次使用是没用问题的,不同函数中使用先前保存下来的指针就有可能出错,特别是对话框初使化时候存下来的指针.  
       在MFC层次上的函数使用CWnd对象,而本地Windows代码(API)使用句柄.如:当Windows系统调用一个窗口过程时将传递一个HWND参数,而MFC本身的消息机制使用CWnd类;为了更好更高效的实现,MFC需要与Windows系统合作,将句柄与CWnd对象进行关联---它用CHandleMap完成关联.  
CHandleMap有两个CMapPtrToPtr的成员变量:m_permanentMap(永久映射表,程序运行过程中对象/句柄之间的关系),m_temporaryMap(临时映射表,在消息存在的过程中才存在).永久表保存显式创建的CWnd对象,当对象创建时将在永久目录下插入一个条目,在CWnd::OnNcDestrory时删除对应条目.但是Windows有时会传入某些不是由开发人员显式创建的窗口的句柄,此时MFC会分配一个临时对象来包装这个句柄并将它们的映射保存到临时映射表中,这些临时对象会在空闲时间被删除并移走相应的临时映射表条目.类似的MFC对象与Windows句柄的映射表有:  
m_pmapHWND:                        窗口句柄与CWnd对象  
m_pampHMENU:                        菜单句柄与CMenu对象  
m_pmapHDC:                        设备环境句柄与CDC对象  
m_pmapHGDIOBJ:                        GDI句柄与CGDI对象  
m_mapHIMAGELIST:            图像链表句柄到CImageList对象  
 
当给定句柄,如HWND时,MFC简单调用CWnd*  PASCAL  CWnd::FromHandle(HWND  hWnd),  此函数内部使用CHandleMap::FromHandle(hWnd)获取相关联的CWnd对象.在CHandleMap::FromHandle(h)内部(源代码在WinHand.cpp),先使用CObject*  pObject  =  LookupPermanent(h);            if  (pObject  !=  NULL)return  pObject;    检查永久表;如永久表中不存在,使用pObject  =  LookupTemporary(h))  !=  NULL检查临时表,都不存在时,使用pTemp  =  =  m_pClass->CreateObject();if  (pTemp  ==  NULL)AfxThrowMemoryException();m_temporaryMap.SetAt((LPVOID)h,  pTemp);创建临时对象并将其插入到临时表中去,同时返回该临时对象.  
void  CHandleMap::RemoveHandle(HANDLE  h)的注释说明临时对象将在空闲时由OnIdel释放:  
           //  remove  only  from  permanent  map  --  temporary  objects  are  removed  
           //    at  idle  in  CHandleMap::DeleteTemp,  always!  
如果想不自动释放临时对象,使用void  AFXAPI  AfxLockTempMaps()/BOOL  AFXAPI  AfxUnlockTempMaps(BOOL  bDeleteTemps)进行锁定.  

攻防世界逆向高手题之mfc逆向-200 攻防世界逆向高手题之mfc逆向-200 继续开启全栈梦想之逆向之旅~ 这题是攻防世界逆向高手题的mfc逆向-200 MFC类型的题目基本没接触过,现阶段也不想入门MFC语法,所以只能大量搜寻资料学个大概了。 . . 照例下载附件,扔入exeinfope中查看信息: . . 照例运行一下查看主要回显信息: 首先第一步看暗示,题目提示是MFC程序,这首先就是一个暗示,然后这里说Flag在控件里,这也是一个暗示。 . . 在这之前我们先了解一下怎么用工具获取MFC程序的控件:(总不能为了做题而做题吧) 以下 阅读详情

相关推荐

Windows事件ID 10010报错:DCOM注册超时与Game Bar修复指南

DCOM(分布式组件对象模型)是Windows中用于跨进程组件通信的核心机制,其注册超时问题常表现为事件ID 10010报错。当Game Bar的PresenceWriter组件因权限配置不当、组件损坏或开机资源竞争而无法在限定时间内向DCOM注册时,系统会记录该错误,并可能伴随DCOM服务主机CPU占用升高或游戏栏功能异常。理解DCOM激活原理与Network Service账户权限,有助于从权限修复、组件重注册及开机时序优化等层面系统排查。本文针对不同Windows版本,提供从静默处理到根治的完整方案,

weixin_33563728的博客 963

FromHandle函数

  一 FromHandle()   MFC 实际上是对内核对象HANDLE(如CDC的m_hDC,CWnd的m_hWnd)封装了这个句柄有关的所有操作,一个类生成一个新对象的时候这个句柄是无效的,要获得这个句柄,可以有两个方法,一个是Create来创建,另一个就是用Attach来与一个已有的句柄建立关联,实际上也就是给类的句柄成员变量赋值。 而有些时候这个句柄不是由我们创建,但是我们...

aa748597605的博客 473

SAP PPDS启发式排产实战:从零配置到自定义规则开发(附ABAP代码示例)

本文详细介绍了SAP PPDS启发式排产的实战应用,从基础配置到自定义规则开发的全流程。通过ABAP代码示例,展示了如何实现多目标优化、实时响应和约束可视化,帮助企业提升订单交付率、减少设备闲置时间。文章还包含开发环境准备、标准模板解析、自定义开发步骤及性能优化技巧,适合制造业数字化转型的实践参考。

seed的博客 186

通过HWND获得CWnd指针

cwnd 又为计算机网络中拥塞窗口(congestion window)的简写。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口还可能小于拥塞窗口。 CWnd是MFC窗口类的基类,提供了微软基础类库中所有窗口类的基本功能。 通过HWND获得CWnd指针可以调用CWnd::FromHandle函数. static CWnd* PASCAL FromHandle(HW...

weixin_34293059的博客 155

OpenEuler22.03 LTS下Zabbix7.0监控系统的容器化部署避坑指南(含Docker-Compose完整配置)

本文详细介绍了在OpenEuler22.03 LTS操作系统上容器化部署Zabbix7.0监控系统的完整流程,包括Docker引擎配置、Docker-Compose编排、网络模式选择及性能调优等关键步骤。针对OpenEuler环境下的特殊问题提供了解决方案,帮助用户高效搭建稳定可靠的监控系统。

python9snake的博客 270

FPGA八股文(2)——笔试的FPGA问题汇总(持续更新)

常见FPGA笔试题的概念总结

居安士的博客 8912

GetDC(),ReleaseDC()

用GetDC()得到的DC,必须调用ReleaseDC()用CreateDC()创建的DC,必须调用DeleteDC()两者是不能混淆的.一种典型的错误代码如下:CDC*pDC=GetDC();…..//做一些无聊的事…..pDC->DeleteDC();//做了错误的事一般情况下,上面这个代码也能够工作,就是有时要报一点CHandleMap::RemoveHand...

1228

复现Fastjson反序列化漏洞(从dnslog回显到rce再到反弹shell)

Fastjson是阿里巴巴的开源JSON解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。它还可以用于将JSON字符串转换为等效的Java对象,fastjson爆出多个反序列化远程命令执行漏洞,攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。......

记录并分享学习安全的知识点.. 2699

CHandleMap::RemoveHandle(HANDLE h) 内断言报错

在做多线程的时候出现的错误,其实问题是出在别的地方。下面时出现的断言错误的地方 原错误代码: //绘制绿球 if (m_Isgreenball) { CDC *pDC = m_greenrect.GetDC(); CBrush *poldbrush; CBrush newbrush(RGB(0,255,0)); poldbrush=pDC->SelectObject(&...

XiaZai2510的博客 367

RT-DETR-R18 的轻量化 Trick:剪枝与量化在模型中的应用

RT-DETR-R18轻量化技术通过结构化剪枝、混合精度量化和知识蒸馏的组合优化,实现了显著模型压缩效果。摘要如下: RT-DETR-R18模型通过创新轻量化技术组合,在保持46.2% mAP精度的前提下,将模型大小压缩至2.1MB(压缩率78%),计算量降至3.2 GFLOPs(减少78.2%),实现移动端28ms实时推理(加速37.8%)。核心技术包括:1)渐进式结构化剪枝系统,通过L1范数重要性评估和动态剪枝调度;2)混合精度量化策略,对关键层保留FP16精度;3)教师-学生知识蒸馏框架保持模型表达能

走向CTO的路上... 1194

Simulink开发项1000例实战专栏--实例17:基于 Simulink 的 BLDC 电机驱动系统的设计与实现

项目背景无刷直流电机(BLDC)因其高效、可靠、低维护的特点,广泛应用于电动汽车、无人机、工业自动化等领域。基于 Simulink 的 BLDC 电机驱动系统可以实现对电机的精确控制,包括速度控制、位置控制和转矩控制。通过仿真和测试,可以优化控制算法,提高系统的性能和可靠性。

xiaoheshang_123的博客 562

解析 MFC 中的 FromHandle

MFC 对 Windows API 进行了封装,在很多方面都会提供便利。用 FromHandle 返回零时对象的指针,就可以调用各种类的方法。临时对象会在 OnIdle 中销毁。这里对 FromHandle 的实现原理从源码上进行解析。// // 1 // CWnd* PASCAL CWnd::FromHandle(HWND hWnd) {

独木专栏 1万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

MFC对象指针不能在线程间传输!

对于大多数mfc对象,请不要在线程间传递它们,不管是栈上的还是堆上的!原因如下:       1、 mfc的大多数类不是线程安全的,调用传入对象的成员函数可能不会报错,但是未必能达到程序预定的功能!       2、 mfc与界面有关的类,其大多数成员方法都是通过sendmessage实现的,如果消息处理函数本身不是线程安全的,你从工作线程中调用这些方法迟早会同你界面线程的用户消息响应

偶尔e网事 3027

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

MFC临时对象的所产生的BUG

现象:视图类中响应消息时调用对话框 CDlgConfig dlg(this); if(dlg.DoModal() == IDOK) {//  SaveConfig(); }在对话框构造参数中调用:CCapTestView * m_pParent = GetParent(); m_FourMin = m_pParent->m_FourMin; m_EMin = m_pParent->

zjh824的blog 1060

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

[MFC] CWnd类总结

一、MFC 类别阶层架构 二、CWnd类 CWnd是MFC的一个窗口类,这个类里几乎封装了所有关于窗口操作的API函数。 在Windows系统里,一个窗口的属性分两个地方存放:一部分放在“窗口类”里头,如上所述的在注册窗口时指定;另一部分放在Windows Object本身,如:窗口的尺寸,窗口的位置(X,Y轴),窗口的Z轴顺序,窗口的状态(ACTIVE,MINIMIZED,MAXM...

Loewen丶的小窝 9276

MFC简介以及基础使用(小白级别入门讲解)

目录Windows消息机制窗口句柄消息与消息队列WinMain函数Windows编程模型MFCMFC简介MFC程序入口MFC的消息映射 Windows消息机制 窗口 一个Windows应用程序中至少有一个窗口,称为主窗口。我们在客户区进行图案的绘制。 句柄 一个Windows应用程序是包含图标、光标等许多部件(资源),系统在为这些部件(资源)分配内存后会返回他们的标识号,也就是所谓的句柄。比如在Windows应用程序中,使用窗口句柄来标识每一个窗口。对窗口进行操作时候,首先就是得到这个窗口的标识。 消息与消

qq_45549336的博客 5万+

MFC中创建多线程 MFC对象指针不能在线程间传输

原文出处注:碰到MFC线程安全的坑,这个前辈说的比较受用。姑且先粘贴过来,等项目进度跟上了,再来总结。对于大多数mfc对象,请不要在线程间传递它们,不管是栈上的还是堆上的!原因如下: 1、 mfc的大多数类不是线程安全的,调用传入对象的成员函数可能不会报错,但是未必能达到程序预定的功能! 2、 mfc与界面有关的类,其大多数成员方法都是通过sendmessage实现的,如果消息处理函数本身不是线

XiaoHeiBlack的专栏 1299

MFC中经常出错的地方

1.AfxGetApp  功能:获得theApp对象的指针 当且仅当在使用共享MFC DLL的规则DLL和带静态链接MFC的规则DLL(只有这两个类型的DLL中才包含theApp对象)的DllMain函数调用栈中调用AfxGetApp时,AfxGetApp返回的才是动态链接库中的theApp对象指针,其他所有情况AfxGetApp返回的都是主程序中的theApp对象指针。当然,如果主程

backard的专栏 1307

通过父类对象指针发送子类自定义消息

       最近在编写MFC时,遇到一个情况是,当我要向一个自己定义的Dialog发送消息时只有CDialog对象的指针,而没有我自己定义的CMyDialog(派生自CDialog类)的对象指针。而我要发送的消息却是在CMyDialog中自定义的消息。这时我产生了疑问,通过父类对象的指针发送在子类中定义的自定义消息,能否成功?       进过实践,答案是可以的。具体问题可以用下面代码简要说

xiaoqiangXX的专栏 1767

MFC——简单示例演示及通过MFC向导创建MFC项目

创建空项目简单实现Windows下应用程序界面 部分概念 示例实现 帮助文档的使用(备注) Windows字符集 通过MFC向导创建MFC项目 通过VS MFC向导创建MFC项目流程 文档/视图结构体系 消息处理的添加 MFC框架中一些重要的函数

跑不了的你的博客 2350

MFC中窗口类、句柄的获取

2、主窗体的类对象指针:AfxGetApp()->m_pMainWnd->, //AfxGetApp()->m_pMainWnd就是主窗体的窗口对象指针。注:每个窗口类的CWnd *hwnd指针中封装了该窗口的句柄m_hWnd,直接hwnd->m_hWnd即可得到该窗口的句柄。AfxGetApp()->GetMainWnd()->m_hWnd //返回主窗口的句柄。AfxGetMainWnd() ->m_hWnd //返回主窗口的句柄。AfxGetMainWnd() //返回主窗口的CWnd指针。

taihang135的专栏 2533

vs2019-安装MFC

title: vs2019 安装配置MFC time: 2019年8月27日22:55:57 vs2019 MFC 安装MFC 打开vs安装程序 选中c++桌面开发 选择Visual Studio扩展开发 (若想快速配置)选择C++ MFC 生成工具(x86 和 x64)进行安装 选择修改,等待安装 创建新项目,选择MFC应用 空项目 配置MFC 快速构建 新建...

hm成长之路 1万+

MFC---MFC入门

微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。MFC把Windows SDK API函数包装成了几百个类,MFC给Windows操作系统提供了面向对象的接口,支持可重用性、自包含性以及其他OPP原则。

Frank---7的博客 1168
上一篇: RAPI编程之CeCopyFile的用法
下一篇: 关于Driver Studio 3.2 的安装详解
普通网友
普通网友 领域专家: 编程技术技术领域 领域专家: 编程技术技术领域
博客等级 码龄25年 2837粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值