Win32 GDI中HBRUSH类型转换与内部机制疑问
Win32 HBRUSH 类型转换与内部实现答疑
1. 整数转HBRUSH指针的目的
这不是把整数当指针地址用,而是Win32的系统预定义画刷约定:系统内置了一批对应系统颜色的画刷,它们的句柄值就是COLOR_XXX + 1(比如COLOR_WINDOW+1对应窗口背景色的系统画刷)。
FillRect要求第三个参数是HBRUSH类型,所以必须把这个整数标识强制转成HBRUSH。系统API内部会判断:如果传入的HBRUSH是小于0x10000的小整数,就识别为系统预定义画刷,而非用户创建的画刷指针。
2. 画刷RGB颜色的存储位置
- 系统预定义画刷:颜色存在系统全局资源里,用
GetSysColor(COLOR_WINDOW)就能拿到对应RGB值。 - 用户创建的画刷(比如
CreateSolidBrush返回的):颜色信息存在内核的GDI对象表中,你看到的struct HBRUSH__{int unused;}; typedef struct HBRUSH__ *HBRUSH只是用户态的“占位类型”,里面的unused字段根本没用——HBRUSH的数值其实是内核对象的句柄索引,不是真正的内存指针,内核里才存着实际的颜色数据。
3. 相关API的内部处理逻辑
CreateSolidBrush:传入RGB后,系统在内核创建GDI画刷对象、存储颜色,返回一个对应内核对象索引的句柄(就是HBRUSH的值)。FillRect:拿到HBRUSH后先判断类型:- 是小整数(系统画刷标识):直接用系统资源里的对应颜色填充;
- 是用户画刷句柄:通过句柄找到内核中的画刷对象,读取颜色后执行填充。
至于struct HBRUSH__的设计,只是为了让HBRUSH在C语法上是指针类型,避免和普通整数混用,保证类型安全。实际这个结构体在运行时根本不会被访问,HBRUSH的数值和它的内存地址毫无关系。
内容的提问来源于stack exchange,提问作者Skimer
相关产品推荐
相关产品推荐

