
- 定 义
- 标识对象或者项目的标识符 [1]
- 本 质
- 一种标识符 [2]
- 由 来
- 源于内存管理机制—虚拟地址 [1]
- 中文名
- 句柄 [1]
- 外文名
- Handle [1]
- 领 域
- 数理科学 [1]
-
句柄
2019-11-26 18:48:45句柄是 Windows 编程的基础,所谓句柄就是 Windows 使用的一种无重复整数。句柄主要用来标识应用程序中的一个对象,如窗口、实例、菜单、内存、输出设备、控制或文件等。 例如在模块文件定义文件中,菜单资源中的...句柄是 Windows 编程的基础,所谓句柄就是 Windows 使用的一种无重复整数。句柄主要用来标识应用程序中的一个对象,如窗口、实例、菜单、内存、输出设备、控制或文件等。
例如在模块文件定义文件中,菜单资源中的菜单项被定义并且赋给了一个句柄值。应用程序的菜单栏中,第一个菜单的第一个菜单项可能被赋予 100 这个句柄值,那么第二个菜单项可能被赋予 101 这个句柄值。在应用程序的源代码中,这些菜单项将要通过 100 和 101 来区分。Windows 应用程序只能访问句柄,而不能直接访问句柄所指示的实际数据。Windows 系统控制着这些系统数据的存取权,这样才能在多任务环境中保护这些数据。Windows 常用的句柄见下表。
Windows 常见的公用句柄类型 句柄类型 说明 备注 HBITMAP 保存位图信息的内存区域的句柄 HBRUSH 画刷句柄 HCTR 子窗口控件句柄 ConTRol
HCURSOR 鼠标光标句柄 HDC 设备描述表句柄 Device Context HDLG 对话框句柄 dialog HFONT 字体句柄 HICON 图标句柄 HINSTANCE 应用程序的实例句柄 HMENU 菜单句柄 HMODULE 模块句柄 HPALETTE 颜色调色板句柄 HPEN 在设备上画图时用于指明线型的笔的句柄 HRGN 剪切区域句柄 HTASK 独立于已执行任务的句柄 HWND 窗口句柄 句柄常作为 Windows 消息和 API(application programming interface,应用程序编程接口)函数的参数,在采用 API 方法编写 Windows 应用程序时要经常使用句柄。采用 MFC 方法编写 Windows 应用程序时,可以通过访问类的一个 public 的成员变量来获取某个 MFC 类对象的句柄,如 CWnd 类的成员变量 m_hWnd 就是一个窗口对象的句柄。由于对应的 MFC 类已经对句柄进行了封装,大多数情况下不在需要访问句柄。
-
句柄
2009-08-04 12:14:001.句柄是什么? 在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯一的句柄,句柄也可以映射到唯一的对象。2.为什么我们需要句柄? 更准确地说,是windows需要句柄。windows需要向程序员...1.句柄是什么?
在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯
一的句柄,句柄也可以映射到唯一的对象。
2.为什么我们需要句柄?
更准确地说,是windows需要句柄。windows需要向程序员提供必要地编程接口
,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地考虑,wi
ndows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出了对象存储
的确切位置;其次,要操作一个指针,程序员必须知道指针所指对象的内部结构特
征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也许是操作
系统想向程序员隐藏的。
如果说COM技术向用户隐藏了数据,只暴露了接口并只允许按接口定义的方法操
作数据的话,句柄这种方式则允许你按自己的方式直接操作数据,但windows又不向
你直接暴露数据。直接操作数据是程序员需要的,不暴露数据是windows所需要的,
句柄封装方式实现了各取所需。
3.句柄如何与对象映射?
封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互转换。在
windows中,存在两种映射方式:
a. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转换而已。
这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。
b. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操作系统创
建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找到空入口
,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其在表中的
入口被释放。
4.句柄的定义和实现
我们以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
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
| 8 位引用计数 |堆 | 对象类型7 | 16位索引 |
标
记
在这里你可以看到,对GDI来说,它只使用了16位作为索引。这意味着一个进程最多只
可以创建小于64K个句柄,实际上受其他一些限制,整个windwos系统中大概可以容纳约
16384(0x4000)个GDI对象。
-
2021-01-19
-
ORA-00904 WMSYS.WM_CONCAT标识符无效解决方案
-
【数据分析-随到随学】Python数据获取
-
Design Compile 介绍.7z
-
IE7 浏览器处理 兼容 input placeholder.zip
-
交流电机电流转速双闭环工程设计SIMULINK仿真
-
【数据分析-随到随学】Hive详解
-
background.js
-
Inpaint 是由国外 Teorex 公司开发的一款很神奇的去水印软件
-
2021年CFA一级notes1-5(完整).zip
-
有关vue性能节约的一些方案
-
flutter插件调用APP页面、使用原生aar,framework库
-
【OpenGL】十六、OpenGL 绘制四边形 ( 绘制 GL_QUADS 四边形 ).zip
-
字节大佬Leetcode刷题笔记,看完吊打问你算法的面试官
-
运料小车(方案二).smart
-
【2021】Python3+Selenium3自动化测试(不含框架)
-
MFC开发简单聊天程序
-
JavaEE框架(Maven+SSM)全程实战开发教程(源码+讲义)
-
delphi unigui如何实现图库式登录校验码.zip
-
web前端开发规范