C++ GetDlgItem用法案例详解

GetDlgItem的用法小结

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这类的函数,随用随取,不要保存另作它用

到此这篇关于C++ GetDlgItem用法案例详解的文章就介绍到这了,更多相关C++ GetDlgItem用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 带你粗略了解C++中的深浅拷贝

    目录 一. 背景 二. 代码实现 三. 问题 四. 解决方法 总结 一. 背景 首先看这样一个问题,在Car类中聚合了Engine类 二. 代码实现 下面给出类Car与类Engine的定义 Car.h #ifndef COPY__CAR_H_ #define COPY__CAR_H_ #include "Engine.h" #include <string> using namespace std; class Car { public: // 构造函数 Car(); Ca

  • 一篇文章带你了解C++语法基础--字符串

    目录 总结 字符与整数的关联在于ASCII码:每一个常用字符都对应一个-128 ~ 127 的数字,二者之间是可以进行相互转换的: #include <iostream> using namespace std; int main(){ char wordOne = 'a'; cout << int(wordOne) << endl; int number = 66; cout << char(number) << endl; return 0;

  • C++相交链表和反转链表详解

    目录 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点.如果两个链表没有交点,返回 null . 思路 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表. 双指针思路 递归 总结 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点.如果两个链表没有交点,返回 null . 思路 简单来说,就是求两个链表交点节点的 指针. 这里同学们要注意,交点不是数值相等,而是指针相等. 为了方便举例,假设节点

  • c++网络编程下Linux的epoll技术和Windows下的IOCP模型

    目录 一.IOCP和Epoll之间的异同 1.异 2.同 二:Epoll理解与应用. 1.epoll是什么? 2.epoll与select对比优化 3.epoll是怎么优化select问题的 三.epoll的几个函数的介绍: 1.epoll_create函数 2.epoll_ctl函数 3.epoll_wait函数 4.条件触发和边缘触发 四.IOCP理解与应用 1.传统服务器的网络IO流程 2.使用IOCP的基本步骤 一.IOCP和Epoll之间的异同 1.异 1).IOCP是WINDOWS系

  • 带你粗略了解C++流的读写文件

    目录 读写文本文件 二进制读写文件 按指定格式读写文件 总结 读写文本文件 C++的IO流: IO:向设备输入数据和输出数据 设备有: 1)文件 2)控制台 3)特定的数据类型(stringstream) C++中,必须通过特定的已经定义好的类, 来处理IO(输入输出) C++的 IO类库为: 文件流:对文件进行读写操作 头文件: < fstream > ifstream 对文件输入(读文件) ofstream 对文件输出(写文件) fstream 对文件输入或输出 文件的打开方式: 模式标志

  • JS调用C++函数抛出异常及捕捉异常详解

    目录 总结 本文讲述如何利用v8::TryCatch捕捉js代码中发生的异常. 首先,声明TryCatch对象. v8::TryCatch trycatch( isolate ); 然后,定义抛出异常的函数: void ThrowException( const v8::FunctionCallbackInfo<v8::Value>& info ) { v8::Isolate* isolate = info.GetIsolate(); v8::HandleScope scope( is

  • C++ namespace案例详解

    在C++语言编写的程序中,变量和函数等的作用范围是有一定限制的.比如,在函数体中定义的一个临时变量就不可以在函数体外使用.为了解决变量和函数等的作用范围,在C++语言中引入了名空间的概念,并增加了关键字namespace和using 在一个名空间中可以定义一组变量和函数,这些变量和函数的作用范围一致,可以将这些变量和函数称为这个名空间的成员. 通过名空间,可以在同一个文件中使用相同的变量名或函数名,只要它们属于不同的名空间.另外,名空间可以使得代码操作具有相同名字但属于不同库的变量.而且,名空间

  • 带你了解C++this指针的用法及其深究

    目录 前言 一.this指针是个什么东东,重要吗? 二.案例理解 主要的用途 总结 前言 今天,码神像一个新车手一样,尝试着用模板来更新一下,不要建议哦,毕竟没有放弃爱情的拓海也不是真正的车神,哈哈,发车了 一.this指针是个什么东东,重要吗? 首先,我以码神的名义起誓,this指针绝对重要,尤其是对于c++这个面向对象编程的语言来说! 有的码手可能要说了:你说重要就重要?那我还说不重要呢? 这个么,空口无凭,我现在来举一个例子: 我们知道对于一个类来说,要有很多工作要做,其中类的成员函数可以

  • C++ GetDlgItem用法案例详解

    GetDlgItem的用法小结 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. **,那说明,它返回的指针有可能是有效的,有可能是无效

  • Python中return用法案例详解

    python中return的用法 1.return语句就是把执行结果返回到调用的地方,并把程序的控制权一起返回 程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return. 例如: def haha(x,y): if x==y: return x,y print(haha(1,1)) 已改正: 结果:这种return传参会返回元组(1, 1) 2.但是也并不意味着一个函数体中只能有一个return 语句,例如: def test_return(x): if x >

  • Java ConcurrentHashMap用法案例详解

    一.概念 哈希算法(hash algorithm):是一种将任意内容的输入转换成相同长度输出的加密方式,其输出被称为哈希值. 哈希表(hash table):根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址. 二.HashMap与HashTable 1,线程不安全的HashMap 因为多线程环境下,使用HashMap进行put操作会引起死循环,导致CP

  • C++优先队列用法案例详解

    c++优先队列(priority_queue)用法详解 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除. 在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有最高级先出 (first in, largest out)的行为特征. 首先要包含头文件#include<queue>, 他和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队. 优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上

  • CSS hack用法案例详解

    之前一直很狭隘的对CSS hack持有偏见,觉得写得规范的代码不应该使用这些"邪门歪道",可最近产品发布一个小问题却让我头疼了很久,最后查了一下资料,竟然使用CSS hack轻松解决了,不得不服啊,对付神奇的IE就得使用这些利器. 什么是CSS hack 由于不同的浏览器,甚至同一浏览器的不同版本对CSS的解析认识不一样,导致生成的页面效果不一致,写出针对不同浏览器CSS code就称为CSS hack. 常用的CSS hack 有三种方式,CSS 内部hack.选择器hack.HTM

  • C# Request.Form用法案例详解

    在CS文件中获得对应页面中的下拉框DropDownList_sitebranch值可以有以下几种方法获得: siteInfo.FZJGID = DropDownList_sitebranch.SelectedItem.Value.Trim(); siteInfo.FZJGID = Request.Form["DropDownList_sitebranch"].ToString(); siteInfo.FZJGID = Request["DropDownList_sitebra

  • C++ ostream用法案例详解

    概述 在 C++中,ostream表示输出流,英文"output stream"的简称.在 C++中常见的输出流对象就是标准输出流cout,很少自定义ostream的对象,更多的是直接使用cout.那么 ostream 有什么用呢,来看一个场景: class CPoint { public: CPoint(int x_,int y_):x(x_),y(y_){} int x,y; }; 这里定义了一个简单的类CPoint,如果我们实例化该类过后,想要打印对象的值: CPoint poi

  • C# Console.WriteLine()用法案例详解

    以前用Console.WriteLine()的时候就只会用它直接输出string字符串,但后来发现它还有其它在有些场合下会十分方便的输出方法,这篇就记录一下这些方法的使用吧. 代码格式我就不写了,因为写了也不好理解,所以直接上示例了.  ① static void Main(string[] args) { int i = 6; string s = "输出"; Console.WriteLine("{0}还可以这样{1}哦.", i, s); Console.Wr

  • MFC LoadImage用法案例详解

    目录 函数原型 cxDesired, cyDesired: fuLoad: 示例 1.加载Icon资源 2.加载本地磁盘的Icon文件 3.加载本地磁盘的Bitmap文件 函数原型 HANDLE LoadImage( HINSTANCE hinst, // 若加载程序外部资源传NULL,否则一般传AfxGetInstanceHandle() LPCTSTR lpszName, // 图片名称或全路径 UINT uType, // 图片类型:IMAGE_BITMAP或IMAGE_ICON或IMAG

  • SQL之patindex函数的用法案例详解

    语法格式:PATINDEX ( '%pattern%' , expression ) 返回pattern字符串在表达式expression里第一次出现的位置,起始值从1开始算. pattern字符串在expression表达式里没找就返回0,对所有有效的文本和字符串就是有效的数据类型. 描述一下此函数的具体用法: 1. PATINDEX ( '%pattern%' , expression ) '%pattern%'的用法类似于 like '%pattern%'的用法,也就是模糊查找其patte

随机推荐