所谓 句柄实际上是一个数据。是一个Long (整长型)的数据。 句 柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗体。控制,位图。GDI对象等等。 WINDOWS句柄有点象C语言中的文件句柄。 从上面的定义中的我们能够看到,句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每一个人都会有一个。不同的人的姓名不一样,可是。也可能有一个名字和你一样的人。 从数据类型上来看它仅仅是一个16位的无符号整数。应用程序差点儿总是通过调用一个WINDOWS函数来获得一个句柄,之后其它的WINDOWS函数就能够使用该句柄,以引用对应的对象。 假设想更透彻一点地认识句柄,我能够告诉大家, 句柄是一种指向指针的指针。 我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。 假设简单地理解。似乎我们仅仅要获知这个内存的首地址,那么就能够随时用这个地址訪问对象。可是。假设您真的这样觉得。那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这样的系统环境下。Windows内存管理器常常在内存中来回移动对象,依此来满足各种应用程序的内存须要。 对象被移动意味着它的地址变化了。 假设地址总是如此变化,我们该到哪里去找该对象呢? 为了解决问题,Windows操作系统为各应用程序腾出一些内存储地址。用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。 Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们仅仅需记住这个句柄地址就能够间接地知道对象详细在内存中的哪个位置。 这个地址是在对象装载(Load)时由系统分配给的。当系统卸载时(Unload)又释放给系统。 句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定)→实际对象 本质:WINDOWS程序中并非用物理地址来标识一个内存块,文件,任务或动态装入模块的。相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序。然后通过句柄来进行操作。 可是必须注意的是程序每次从新启动。系统不能保证分配给这个程序的句柄还是原来的那个句柄,并且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动执行。那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。 1、句柄所指的能够是一个非常复杂的结构。而且非常有能够是与系统有关的,比方说上面所说的线程的句柄,它指向的就是一个类或者结构,他和系统有非常密切的关系。当一个线程因为不可预料的原因。而终止时在系统就能够回它所占用的资料,如CPU。内存等等。反过来想能够知道,这个句柄中的某一些项,是与系统进行交互的。 因为Windows系统。是一个多任务的系统,它随时都可能要分配内存。回收内存,重组内存。 2、指针它也能够指向一个复杂的结构。可是一般是用户定义的。所以的必需的工作都要用户完毕。特别是在删除的时候。 但在VC++6.0中也有一些指针,它们都是处理一些小问题才用的,如最常见的字符的指针,它也是要用户处理的假设你动态分配了内存;可是Cstring就不要用户处理了,它事实上是VC++中的一个类。所以的操作都由成员函数完毕,产生(分配)由构造函数,删除(回收)由析构函数完毕。 3.句柄是标号,指针是内存地址 句柄和指针根本就不是一回事。基本上没有共同的地方。我对句柄的定义是:. 句柄是系统内部受保护的数据结构的标志或者说索引. 我的解释: 当你的应用程序或者系统建立内核对象。用户对象。GUI对象的时候实际上这些对象是一些内存数据结构(这个就不要我解释了吧)显然这些对象须要受到保护。不能让用户随便改动訪问,否则系统非常easy崩溃所以提供了一个机制来保护性的訪问这些对象,那就是API句柄是这些对象的标记,或者说是索引在内存中往往会存在一张句柄表。一般至少有例如以下结构 索引(也就是句柄) 指针(指向内存对象数据结构) 其它项 1 ox?????? ?? 2 ox?????? ?? 3 ox?? ?? ?? ?? 4... 系统採用API,查询句柄表,取得句柄所相应的指针,这个指针才是真正的指针。用它能够訪问改动受保护的内存. . 假如句柄是指针 . 1 你自己输出一些句柄的值来看,句柄一般都是一些非常小的整数值。 比方1,2,3,4...... 假设是指针的话,它起不是指向受保护的区域?岂不是NULL指针??? 2 句柄假设是指针的话。那么用户岂不能够直接訪问内存对象了?那系统还有什么稳定性,安全性? 3 你把得到的句柄,比方hwnd做hwnd++,hwnd--等运算,你看错不错 其它理由我都不想说了 假设有人说看到句柄的定义为指针(我没有看到过) 那你就去当指针吧,反正指针也是32位的值。和无符号整数没有不论什么差别. 附注:获得窗体句柄三种方法 1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName) HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName) 2.HWND WindowFromPoint(POINT& Point)//获得当前鼠标光标位置的窗体HWND 3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam) BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam) BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam) BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 指针 句柄之间的转换 a.由指针获得句柄 CWnd * pWnd; CWnd HWnd; HWnd = pWnd->GetSafeHWnd(); b.由句柄得到指针: |
CWnd* pWnd=FromeHandle(hMyHandle); pWnd->SetWindowText("Hello World!"); or CWnd* pWnd; pWnd->Attach(hMyHandle); MFC类中有的还提供了标准方法,比方Window 句柄 : static CWnd* PASCAL FromHandle( HWND hWnd ); HWND GetSafeHwnd( ) const; 对于位图: static CBitmap* PASCAL FromHandle( HBITMAP hBitmap ); static CGdiObject* PASCAL FromHandle( HGDIOBJ hObject ); HGDIOBJ GetSafeHandle( ) const; |
版权声明:本文博客原创文章,博客,未经同意,不得转载。