问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

窗口句柄的解疑

发布网友 发布时间:2023-08-31 06:16

我来回答

1个回答

热心网友 时间:2023-09-10 05:06

句柄是什么?
在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯
一的句柄,句柄也可以映射到唯一的对象。 为什么我们需要句柄?
更准确地说,是windows需要句柄。windows需要向程序员提供必要的编程接口
,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地考虑,wi
ndows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出了对象存储
的确切位置;其次,要操作一个指针,程序员必须知道指针所指对象的内部结构特
征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也许是操作
系统想向程序员隐藏的。
如果说COM技术向用户隐藏了数据,只暴露了接口并只允许按接口定义的方法操
作数据的话,句柄这种方式则允许你按自己的方式直接操作数据,但windows又不向
你直接暴露数据。直接操作数据是程序员需要的,不暴露数据是windows所需要的,
句柄封装方式实现了各取所需。 句柄如何与对象映射
封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互转换。在
windows中,存在两种映射方式:
a. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转换而已。
这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。
b. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操作系统创
建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找到空入口
,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其在表中的
入口被释放。 句柄的定义和实现
我们以GDI对象为例进行讨论。创建了GDI对象,就会得到该对象的句柄。句柄
的对象可能是HBRUSH、HPEN、HFONT或HDC中的一种,这依赖于你创建 的GDI对象类
型。但是最普通的GDI对象类型是HGDIOBJ。HGDIOBJ被定义成空指针。
HPEN的实际编译类型定义随编译时间宏STRICT的不同而不同。如果STRCIT已经
被定义了,HPEN是这样的:
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对象。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
招聘和招募和招收区别 人力资源中招聘与招募的区别 招聘与招募有啥区别 夏日繁星公众号可信吗 关于“红杏出墙”的古诗词描写有哪些 需要考多少分才过雅思 雅思考试多少分才可以算及格 雅思考试多少分算及格 雅思的总分多少分及格 雅思一般考多少分能合格 梦见狗冲自己叫预示什么 发电机电压低功率小的问题 使用面积应该如何计算?小心面积被坑在公摊上 人体生命活动所需的能量,从根本上来说 生命能量依赖于什么 梦幻西游中怎申请安全码 梦幻西游建了帐号,怎样建安全码? 怎么样才做好一个管理层的工作? 根除蟑螂的方法 梦见一窝不会飞家雀 怎么我的CAD2008注册机不能启动了 家里养花烂根怎么解决 豇豆角饭的做法 鸡蛋面的做法分享 鲍鱼和海参一起煮方法介绍 梦见刚出生的婴儿什么意思 手机内存占了多少手机才会卡,看视频打游戏影响吗? 32寸的炒锅是多大的? 跪求短剧开局为爱冲锋(103集),我需要这个百度网盘资源,希望分享一下... 象棋教学视频教程第八集开局及几种形式 想起个带火字两个字一样的名字,男孩 75年正月惊蛰过后箅几月 采样点有异常 银行冠字号采集机客户端运行异常 气温高牛津布会产生泡泡皱么 济南市立三院到鲍贤商务公寓多远 寓贤公寓工作怎么样 武汉拉菲公寓开发商是哪家公司? 人才公寓是房产证是商业吗 下面病毒中,属于宏病毒的是( ),宏病毒一般感染( )文件。 孙膑胸有成竹的原因是什么 黄米凉糕做法介绍 建瓯还有摆地摊卖鞋的吗? 如何蒋油漆淡蓝色变深蓝色 荣耀X30max重量是多少 荣耀X30max刷新率是多少 开班致辞简短 形成电流一定要有回路吗 没有回路有电流吗 家庭交流电路是不是一定要形成回路才会有电流通过?