
句柄是一种特殊的智能指针。句柄,是整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不在I/O文件中,它是毫无用处的。 句柄是Windows用来标志应用程序中建立的或是使用的唯一整数,Windows使用了大量的句柄来标识很多对象。项目包括:*.模块(module)*.任务(task)*.实例(instance)*.文件(file)*.内存块(block of memory)*.菜单(menu)*.控件(control)*.字体(font)*.资源(resource),包括图标(icon),光标(cursor),字符串(string)等*.GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画笔(pen),区域(region),以及设备描述表(device context)。语句:HINSTANCE hInstance;可以改成:HANDLE hInstance;上面的2条语句都是对的,表达的是一个意义。一个WINDOWS应用程序可以用不同的方法获得一个特定项的句柄。许多API函数,诸如CreateWindow,GlobalAlloc,OpenFile的返回值都是一个句柄值。另外,WINDOWS也能通过应用程序的引出函数将一个句柄作为参数传送给应用程序,应用程序一旦获得了一个确定项的句柄,便可在WINDOWS环境下的任何地方对这个句柄进行操作。其实句柄的大量使用已经影响到了每一个WINDOWS的程序设计。一个句柄,只有当唯一地确定了一个项目的时候,它才开始有意义。句柄对应着项目表中的一项,而只有WINDOWS本身才能直接存取这个表,应用程序只能通过API函数来处理不同的句柄。举个例子来说吧,比如:我们可以为我们的应用程序申请一块内存块,通过调用API函数GlobalAlloc,来返回一个句柄值:hMem=GlobalAlloc(......);现在的hMem是个索引值 不是物理地址,应用程序还不能直接存取这块内存。这儿还有一句题外话,是关于操作系统的内存管理的。一般情况下操作系统给应用程序分配的内存块都是可以被移动的或者是可以丢弃的,这样能使有限的内存资源得到充分利用。所以,我们刚开始分配到的那块内存的地址是不确定的,因为它是可以被移动的,所以得先锁定那块内存块,这里应用程序需要调用API函数GlobalLock函数来锁定句柄。如下:lpMem=GlobalLock(hMem);这样应用程序才能存取这块内存。作用:句柄是一个标识符,是拿来标识对象或者项目的。如果想更透彻一点地认识句柄,我可以告诉大家,句柄类似指向指针的指针,仅仅是类似,通过句柄可以找到对应的数据,但是不是二级指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是驻留在内存中的。简单地理解,似乎我们只要获知这个内存的首地址,就可以随时用这个地址访问对象了。如果您真的这样认为,那您可就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找那一个对象呢?为了解决这个问题,Windows操作系统为全体应用程序腾出一些内存单元,用来专门登记各应用程序的对象在内存中的地址的变化,而前者的物理地址在系统运行期间是始终保持不变的。Windows内存管理器移动了对象在内存中的位置后,会把该对象新的地址及时地告知给对应的句柄进行更新。这样我们只要知道这个句柄,就可以间接地知道对象具体在内存中的哪个位置了。这个地址是在对象装载(Load)时由系统分配给的,当对象卸载时(Unload)又释放给系统。
