句柄源代码:

#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif

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

MFC在创建窗口的时候用钩子函数沟住HCBT_CREATEWND消息,然后通过CWnd::Attach()函数把二者捆绑在一起。以后就可以用上述三个函数可以互相得到了。

具体分析  :    

     句柄是一个32位的整数,实际上是windows在内存中维护的一个对象(窗口等)内存物理地址列表的整数索引由于MS未完全公开相关技术,在一定程度上只能如此理解,这个索引更像是一种映射关系从句柄到对象指针的映射)。因为windows的内存管理经常会将当前空闲对象的内存释放掉,当需要时访问再重新提交到物理存储,所以对象的物理地址是变化的,不允许程序直接通过物理地址来访问对象。程序将想访问的对象的句柄传递给系统,系统根据句柄检索自己维护的对象列表就能知道程序想访问的对象及其物理地址了。句柄是一种指向指针的指针

      所谓指针是一种内存地址。应用程序启动后,组成这个程序的各个对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象了。

      但是,windows是一个虚拟内存为基础操作系统。在这种情况下,windows内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要,对象被移动意味着它的地址变化了。如果地址总是如此的变化,我们应该去那里找对象呢?为了解决这个问题,windows操作系统为各个应用程序腾出一些内存地址用来专门登记各个应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。

      windows内存管理器移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需要记住这个句柄地址就可以间接地知道对象具体在内存中哪个位置了。这个地址是在对象装载(load)时由系统分配的,当系统卸载时又释放给系统。必须注意,程序每次重新启动,系统不保证分配跟这个程序的句柄还是原来哪个句柄,而绝大多数情况下的确不一样。

       句柄地址(稳定)----->记载着对象在内存中的地址-------->对象在内存中的地址(不稳定)----->实际对象

      windows系统用句柄标记系统资源,用句柄隐藏系统信息。你只需要知道有这个东西,然后去调用它就行了,它是32bituint。指针则标记某个物理内存的地址,是不同的概念。



Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐