Window Handle介绍

本文深入解析Windows操作系统中的句柄概念,解释句柄的作用及其与对象之间的映射关系,探讨句柄与指针的区别,帮助读者理解句柄在Windows编程中的应用。
部署运行你感兴趣的模型镜像

HANDLE(句柄)是Windows操作系统中的一个概念。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标示这些资源的标示号,即句柄。句柄指的是一个核心对象在某一个进程中的唯一索引,而不是指针。由于地址空间的限制,句柄所标识的内容对进程是不可见的,只能由操作系统通过进程句柄列表来进行维护。

句柄列表:每个进程都要创建一个句柄列表,这些句柄指向各种系统资源,比如信号量线程,和文件等,进程中的所有线程都可以访问这些资源。

在Windows中,句柄是对一个系统内部数据结构的引用。例如当你操作一个窗口时,系统会给你一个该窗口的句柄,系统会通知你:你正在操作XXX号窗口,就此你的应用程序就能要求系统对XXX号窗口进行操作——移动窗口、改变窗口大小、把窗口极小化为图标等。

实际上许多Windows API函数把句柄作为它的第一个参数,如GDI(图形设备接口)句柄、菜单句柄、实例句柄、位图句柄等,不仅仅局限于窗口函数。换句话说,句柄是一种内部代码,通过它能引用受系统控制的特殊元素,如窗口、位图、图标、内存块、光标、字体、菜单等。

单从概念上讲,句柄指一个对象的标识,而指针是一个对象的首地址。从实际处理的角度讲,即可以把句柄定义为指针,又可以把它定义为同类对象数组的索引,这两种处理方法都有优缺点,至于选用哪种方式,完全应该看实际需要,这可以说是一种程序设计上的技巧。那种单纯认为句柄是指针或索引的想法都是机械的、不确切的。

其实,在Windows中类似的处理是很多的、很灵活的。举个相似的例子:

我们知道,在Windows中有个函数叫做CallWindowProc。顾名思义,它的作用就是向指定的窗口过程传递一个消息。你也许会想,既然我已经有了窗口过程的指针,为什么我不可以直接通过这个指针调用该函数(这是C语言的内建功能)?事实上,在Win16中确实可以这么做,因为GetWindowLong返回的确实是该函数的指针。但在Win32下,GetWindowLong返回的并不是该函数的指针,而是一个包含函数指针的数据结构的指针(MSDN上说返回的是一个窗口函数地址或它的句柄,就是指的这种情况)。该数据结构是可变的,但只要你使用CallWindowProc来调用的话是不会出错的。这里我们又看到使用句柄处理带来的好处。(补充说明一点:微软在这里之所以这么处理,是为了解决16位/32位以及ANSI/UNICODE的转化问题)

 

1.句柄是什么?

在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯一的句柄,句柄也可以映射到唯一的对象。

2.为什么我们需要句柄?

更准确地说,是windows需要句柄windows需要向程序员提供必要地编程接口,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地考虑,windows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出了对象存储的确切位置;其次,要操作一个指针,程序员必须知道指针所指对象的内部结构特征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也许是操作系统想向程序员隐藏的。

如果说COM技术向用户隐藏了数据,只暴露了接口并只允许按接口定义的方法操作数据的话,句柄这种方式则允许你按自己的方式直接操作数据,但windows又不向你直接暴露数据。直接操作数据是程序员需要的,不暴露数据是windows所需要的,句柄封装方式实现了各取所需。

3.句柄如何与对象映射?

封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互转换。在windows中,存在两种映射方式:

a. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转换而已。这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。

b. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操作系统创建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找到空入口,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其在表中的入口被释放


您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

<think>我们正在处理Halcon中窗口句柄的设置问题。根据引用内容,Halcon提供了`dev_set_window`算子来设置当前活动窗口的句柄。 步骤: 1. 首先,我们需要打开一个窗口,使用`dev_open_window`,它会返回一个窗口句柄WindowHandle)。 2. 然后,我们可以使用`dev_set_window`来设置当前活动窗口为指定的窗口句柄。 例如,如果我们有两个窗口,我们可以在它们之间切换: - 打开第一个窗口:`dev_open_window(0, 0, 400, 300, 'black', WindowHandle1)` - 打开第二个窗口:`dev_open_window(500, 0, 400, 300, 'black', WindowHandle2)` - 设置第一个窗口为活动窗口:`dev_set_window(WindowHandle1)` - 在第一个窗口显示图像:`dev_display(Image1)` - 设置第二个窗口为活动窗口:`dev_set_window(WindowHandle2)` - 在第二个窗口显示图像:`dev_display(Image2)` 此外,引用[2]中还提到了`dev_get_window`用于获取当前活动窗口的句柄,这在需要记录当前窗口或者进行窗口存在性检查时很有用。 因此,设置窗口句柄的核心算子就是`dev_set_window`。 下面我们用一个完整的例子来说明:</think>在 Halcon 中设置窗口句柄WindowHandle)主要通过 `dev_set_window` 算子实现,以下是详细操作步骤: ### 设置窗口句柄的方法 1. **打开新窗口并获取句柄** 使用 `dev_open_window` 创建窗口并返回句柄: ```halcon dev_open_window(0, 0, 800, 600, 'black', WindowHandle1) // 创建窗口1 dev_open_window(400, 0, 800, 600, 'white', WindowHandle2) // 创建窗口2 ``` 2. **切换活动窗口** 通过 `dev_set_window` 设置当前活动窗口: ```halcon dev_set_window(WindowHandle1) // 激活窗口1 read_image(Image1, 'part1.png') dev_display(Image1) // 图像显示在窗口1 dev_set_window(WindowHandle2) // 切换到窗口2 read_image(Image2, 'part2.png') dev_display(Image2) // 图像显示在窗口2 ``` 3. **动态获取当前句柄** 使用 `dev_get_window` 获取当前活动窗口句柄: ```halcon dev_get_window(CurrentHandle) // 返回当前窗口句柄到变量 CurrentHandle ``` 4. **错误处理** 检测窗口是否存在: ```halcon try dev_get_window(WindowHandle) catch // 窗口不存在时创建新窗口 dev_open_window(0, 0, 500, 400, 'black', NewHandle) endtry ``` ### 关键技巧 1. **多窗口管理** 通过保存不同窗口句柄实现视图切换: ```halcon // 保存句柄到元组 WindowHandles := [Handle1, Handle2, Handle3] // 切换到第三个窗口 dev_set_window(WindowHandles[2]) ``` 2. **图形堆栈优化** 在界面开发中启用图形堆栈避免闪烁: ```halcon set_window_param(WindowHandle, 'graphics_stack', 'true') // 推荐设置[^1] ``` 3. **缓冲控制** 禁用自动刷新提升多图显示性能: ```halcon set_window_param(WindowHandle, 'flush', 'false') // 关闭自动刷新 dev_display(Image1) dev_display(Image2) flush_buffer(WindowHandle) // 手动刷新显示所有图像[^1] ``` > **注意**:窗口句柄是 Halcon 管理窗口的唯一标识,所有显示操作(`dev_display`, `disp_text` 等)均在当前活动窗口执行。多相机系统或复杂界面中,建议使用 `dev_get_window` 动态获取句柄确保操作正确[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值