struct HPEN__ {int unused};
typedef struct HPEN__ HPEN;
假如STRICT没有界说,HPEN是这样界说的:
typedef void HANDLE;
typedef HANDLE HPEN;
上面这段代码是一个重视细节的程序员最接近句柄的当地,因而咱们重点剖析
一下。这儿有一点点技巧。假如界说了STRICT宏,HPEN是指向有单个未运用字段的
结构的指针,不然HPEN是空指针。C/
C++编译器答应把任何类型的指针作为空指什传
递,反之则不能够。两个不同类型的非空指针是互不兼容的。在STRICT版本中,编
译对GDI目标句柄的不正确混用将给出正告,关于非GDI句柄,如HWND、HMENU的不正
确混用也会给出正告,从而使程序在编译器得到更STRICT的检查。
接下来的剖析或许不那么令你感兴趣,但它更深刻地提醒了句柄。对GDI句柄来
说,虽然windows头文件把它界说成指针,但假如你仔细检查这些句柄的值,它根本
就不像指针,这也是为什么我说它只是一个32位无符整数值的原因。对句柄就是指
针的情况,这句话也依然适用。让咱们随意地生成一些句柄,比如你用GetStockOb
ject()以得到一些句柄,你会发现,它们的值总在区间0x01900011到0xba040389。
前者指向用户区中的未分配的无效区域,后者指向内核地址空间。另外你或许发现
,两个句柄之间的值或许只差数值1,这也阐明GDI句柄不是指针。
和多数人想象的不一样,句柄也不是一个单纯的索引值。对GDI目标句柄来说,
GDI句柄由8位 、1位堆目标符号(标明目标是否创立在堆中)、7位目标类型信息和
高4位为0的16位索引组成,如:
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
10 9 8 7 6 5 4 3 2 1 0 98 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
/ 8 位引证计数 /堆 / 目标类型7 / 16位索引 /
符号
在这儿你能够看到,对GDI来说,它只运用了16位作为索引。这意味着一个进程最多只
能够创立小于64K个句柄,实际上受其他一些约束,整个Windows体系中大约能够容纳约
16384(0x4000)个GDI目标。
<上一页12