GetDlgItem用于获得指定控件ID的窗体指针,函数原型如下:


HWND GetDlgItem(
HWND hDlg,
int nIDDlgItem
); CWnd* GetDlgItem(int nID) const;

它的使用说明中有这样一行字,**The returned pointer may be temporary and should not be stored for later use.

**,那说明,它返回的指针有可能是有效的,有可能是无效的,不建议保存留给后续来使用。那么问题来了,

  • 为什么通过GetDlgItem返回的指针有时稳定,有时不稳定?

  • 在实际应用中,如何正确处理GetDlgItem的返回值?

先回答第一个问题, GetDlgItem返回的数据类型是CWnd*类型,它内部有一个 HWND m_hWnd 句柄成员,该句柄成员是一个4字节(64位程序中为8字节)的无符号整形,它代表内存中对象物理地址列表的索引,索引对应保存的内容是特定对象的物理地址。由于Windows的内存管理策略会定时对空闲内存进行释放、移动等操作,当应用程序再次使用时,系统会重新申请物理内存,所以对象的物理地址会变化,Windows通过句柄来对应用程序屏蔽这种变化。当应用程序要访问对象时,只需要将对应的句柄传递给系统,系统内部会根据句柄检索指向对象的最新地址。

C++中的指针也代表地址。对于应用程序中的不同对象和同类中的不同实例来说,Windows不允许直接通过其地址来访问内核对象,而是通过标识或者索引指针的句柄(HANDLE)来访问对象信息。

上面提到了Windows的内存管理策略会对空闲对象内存进行相关操作,据此推测,在Windows认为应用程序空闲时,就会对应用程序的空闲对象进行操作。

GetDlgItem实际上是调用CWnd::FromHandle函数来实现功能的,先看CWnd::FromHandle函数


CWnd::FromHandle(HWND hWnd) -->CHandleMap* pMap = afxMapHWND(TRUE); //create map if not exist -->AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); -->pState->m_pmapHWND = new CHandleMap -->CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd);
-->pWnd->AttachControlSite(pMap);

再看下CWinApp::OnIdle函数,OnIdle函数的官方解释:

CWinApp::OnIdle

OnIdle is called in the default message loop when the application's message queue is

empty. Use your override to call your own background idle-handler tasks.

MFC程序中对Idle状态的处理:

基于MFC的OnIdle相关流程如下:


CWinApp::OnIdle --> CWinThread::OnIdle(lCount) -->AfxUnlockTempMaps() --> AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
--> pState->m_pmapHWND->DeleteTemp();

对CWinApp:OnIdle进行重载,返回非零代表还有Idle Task要处理,这样下次OnIdle仍然会继续执行。返回0,表示无Idle任务需要处理。具体详细的参考MFC框架程序中的OnIdle

很多函数,如FromHandle、FindWindow都用到了临时对象技术,这些临时对象即用即取,不能保存后另作他用。默认情况下,MFC框架会在空闲时间把临时对象给清空掉。

最后解答开头提出的问题:

  • 当默认Idle流程执行时,会删除临时对象句柄。

  • 对于GetDlgItem这类的函数,随用随取,不要保存另作它用

GetDlgItem的用法小结的更多相关文章

  1. 转载:Hadoop排序工具用法小结

    本文转载自Silhouette的文章,原文地址:http://www.dreamingfish123.info/?p=1102 Hadoop排序工具用法小结 发表于 2014 年 8 月 25 日 由 ...

  2. [No000010]Ruby 中一些百分号(%)的用法小结

    #Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...

  3. C++ typedef用法小结 (※不能不看※)

    C++ typedef用法小结 (※不能不看※) 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不 ...

  4. 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)

    函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...

  5. 1:CSS中一些@规则的用法小结 2: @media用法详解

    第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下     at-rule ...

  6. 英语语法最终珍藏版笔记- 21it 用法小结

    it 用法小结 it 在英语中的意思较多,用法较广,现总结如下. 一.it作句子的真正主语 1.it 指前面已经提到过的人或事物,有时指心目中的或成为问题的人或事物,作真正主语. 例如: What’s ...

  7. [转]ssh常用用法小结

    ssh常用用法小结 1.连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机, ...

  8. 结构体定义 typedef struct 用法详解和用法小结

    typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...

  9. typedef用法小结

    typedef用法小结- - 注意:本文转自网络,版权归原作者所有. typedef typedef用法小结- - 这两天在看程序的时候,发现很多地方都用到typedef,在结构体定义,还有一些数组等 ...

随机推荐

  1. vmware的硬件选项里有关于虚拟化引擎的选项(虚拟机支持硬件虚拟化)

    前一阵子在使用陈沙克老师的博客安装devstack的时候就有一个疑问: 使用vmware创建虚拟机时,硬件选项里有关于虚拟化引擎的选项到底都代表了什么意思?  Intel VT-x/EPT和AMD-V ...

  2. rapidjson使用总结

    Reference:  https://blog.csdn.net/elloop/article/details/49908689 rapidjson简介 rapidjson是腾讯的开源json解析框 ...

  3. python pandas ---Series,DataFrame 创建方法,操作运算操作(赋值,sort,get,del,pop,insert,+,-,*,/)

    pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包 pandas 也是围绕着 Series 和 DataFrame 两个核心数据结构展开的, 导入如下: from panda ...

  4. PHP写的一个轻量级的DI容器类(转)

    理解什么是Di/IoC,依赖注入/控制反转.两者说的是一个东西,是当下流行的一种设计模式.大致的意思就是,准备一个盒子(容器),事先将项目中可能用到的类扔进去,在项目中直接从容器中拿,也就是避免了直接 ...

  5. 【转】使用scipy进行层次聚类和k-means聚类

    scipy cluster库简介 scipy.cluster是scipy下的一个做聚类的package, 共包含了两类聚类方法: 1. 矢量量化(scipy.cluster.vq):支持vector ...

  6. am335x Watchdog 生效导致 LAN8710A action 异常

    原因是因为 watchdog 生效的时候,产生的 reset 信号,只有 2.5us 左右,太短了,导致 LAN8710a 未完全重启 在 kernel watchdog 里面增加下面的代码即可 86 ...

  7. virtualbox 安装 USB 扩展功能

    virtualbox USB 扩展包下载 扩展包下载地址: http://download.virtualbox.org/virtualbox/ 选择你的 virtualbox 版本 看版本在 vir ...

  8. gcc命令中参数c和o混合使用的详解

    gcc -c a.c 编译成目标文件a.o gcc -o a a.o 生成执行文件a.exe gcc a.c 生成执行文件a.exe gcc -o a -c a.c 编译成目标文件a gcc -o a ...

  9. jQuery源代码解析(3)—— ready载入、queue队列

    ready.queue放在一块写,没有特殊的意思,仅仅是相对来说它俩可能源代码是最简单的了.ready是在dom载入完毕后.以最高速度触发,非常实用. queue是队列.比方动画的顺序触发就是通过默认 ...

  10. 微信小程序——计算2点之间的距离

    关于计算2点之间的距离都依赖了腾讯地图,所以请先在腾讯地图官网申请key.具体流程看下图: 下面具体讲计算2点之间距离的方法. 方法一: 1.通过 wx.getLocation(Object obje ...