首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

句柄和指针的区别和联系?解决办法

2014-05-11 
句柄和指针的区别和联系?句柄是一个整形吧?如有一个窗口句柄,一个窗口指针,怎么把两者联系起来?[解决办法]

句柄和指针的区别和联系?
句柄是一个整形吧?
如有一个窗口句柄,一个窗口指针,怎么把两者联系起来?

[解决办法]
从窗口指针获取窗口句柄:GetSafeHwnd();
从窗口句柄获取窗口指针:FromHandle();

[解决办法]

从窗口指针获取窗口句柄:GetSafeHwnd();
从窗口句柄获取临时窗口指针:FromHandle();
从窗口句柄获取永久窗口指针: FromHandlePermanent();

其实两者被没有关系,实际上是MFC在创建窗口的时候用钩子函数沟住HCBT_CREATEWND消息,
然后通过CWnd::Attach()函数把二者捆绑在一起。
以后就可以用GetSafeHwnd(),FromHandle(),FromHandlePermanent()这三个函数可以互相得到了。

MFC之所以要这样做,主要是为了使原来的SDK面向过程的编程遍成面向对象的编程,所有的MFC的窗口都共用一窗口过程函数,在窗口过程函数里,通过窗口句柄(HWND)找到窗口对象指针(CWnd *)从而把消息分发到窗口对象中,这样以后就可以在窗口类中实行消息响应编程处理了。



[解决办法]
两者的关系仅此而已。
Class CWnd
{
HWND m_hWnd;
};
MFC为了面向对象编程,把二者捆绑在一起。
[解决办法]
这是初学者最常问及的问题,一些面试官也很喜欢问这个问题 ,
我觉得下面的描述是相当清晰独到的:

句柄是一个32位的整数,实际上是windows在内存中维护的一个对象(窗口等)内存物理地址列表的整数索引。因为windows的内存管理经常会将当前空闲对象的内存释放掉,当需要时访问再重新提交到物理存储,所以对象的物理地址是变化的,不允许程序直接通过物理地址来访问对象。程序将想访问的对象的句柄传递给系统,系统根据句柄检索自己维护的对象列表就能知道程序想访问的对象及其物理地址了。句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各个对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象了。但是,如果真这么认为,那么就大错特错了。我们知道windows是一个虚拟内存为基础的操作系统。在这种情况下,windows内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要,对象被移动意味着它的地址变化了。如果地址总是如此的变化,我们应该去那里找对象呢?为了解决这个问题,windows操作系统为各个应用程序腾出一些内存地址,用来专门登记各个应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。windows内存管理器移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需要记住这个句柄地址就可以间接地知道对象具体在内存中哪个位置了。这个地址是在对象装载(load)时由系统分配的,当系统卸载时又释放给系统。句并地址(稳定)-----> 记载着对象在内存中的地址--------> 对象在内存中的地址(不稳定)-----> 实际对象。但是必须注意,程序每次重新启动,系统不保证分配跟这个程序的句柄还是原来哪个句柄,而绝大多数情况下的确不一样。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院给我们的门票总是不同的座位是一个道理。
因此,句柄和指针其实是两个截然不同的概念。windows系统用句并标记系统资源,用句并隐藏系统信息。你只需要知道有这个东西,然后去调用它就行了,它是32bit的uint。指针则标记某个物理内存的地址,是不同的概念。
(摘自:欧立奇,刘洋,段韬 编著的《程序员面试宝典 》)

热点排行