博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GetDlgItem的用法小结
阅读量:4912 次
发布时间:2019-06-11

本文共 1881 字,大约阅读时间需要 6 分钟。

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状态的处理:

5c18b658eb979.jpg

基于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任务需要处理。具体详细的参考

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

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

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

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

转载于:https://www.cnblogs.com/cherishui/p/9433486.html

你可能感兴趣的文章
Travel on the TranzAlpine Rail Line in New Zealand
查看>>
多c文件的shelloce框架探讨
查看>>
List、Map、Set
查看>>
关于iOS多线程
查看>>
[转]Linux之type命令
查看>>
flash画图API:解析obj格式
查看>>
近日国家几个简单的思考
查看>>
JBoss 7/WildFly Domain 模式怎样配置 Server 启动的 JVM 參数
查看>>
(转)通往(革命性的、不做恶的、疯狂赚钱的、自我毁灭的)Google核心之路
查看>>
hubust 1339Touring (最短路Dijkstra算法)
查看>>
实验四 小学生四则运算需求分析结对报告
查看>>
转换CLOB字段类型为VARCHAR2, lob类型不支持的sql语句
查看>>
用nRF52的RTC实现万年历
查看>>
mysql 外键约束
查看>>
CSS设置透明背景
查看>>
APP自動化測試腳本3
查看>>
[git] branch 分支操作
查看>>
谭浩强 c程序设计 8.17用递归法将一个整数n转换成字符串。例如,输入486,应输出字符串"486"。n的位数不确定,可以是任意位数的整数。...
查看>>
HtmlEncode和JavaScriptEncode(预防XSS)
查看>>
Visual Studio 2012 应用软件开发新方式
查看>>