标题:
[2025开源大赛] [全站首发] 使用子类化技术修改hk条背景颜色
实现原理
1. 子类化技术 (Subclassing)
- 通过
SetWindowLongA
替换窗口过程,拦截并处理特定消息
- 主窗口处理
WM_CTLCOLORSTATIC
消息设置背景画刷
- hk条控件处理
WM_ERASEBKGND
消息自定义背景绘制
2. GDI 对象管理
- 使用
CreateSolidBrush
创建纯色画刷
- 通过
FillRect
填充客户区背景
- 资源释放时调用
DeleteObject
避免内存泄漏
部分源码(完整源码见附件)
.版本 2
.支持库 user32
.支持库 kernel
.程序集 窗口程序集_启动窗口
.程序集变量 OldMainProc, 整数型
.程序集变量 OldTrackBarProc, 整数型
.程序集变量 hTrackBarBrush, 整数型
.程序集变量 hk条背景颜色, 整数型
.数据类型 RECT
.成员 left, 整数型
.成员 top, 整数型
.成员 right, 整数型
.成员 bottom, 整数型
.DLL命令 GetClientRect, 整数型, "user32.dll", "GetClientRect"
.参数 hWnd, 整数型
.参数 lpRect, RECT
.DLL命令 FillRect, 整数型, "user32.dll", "FillRect"
.参数 hDC, 整数型
.参数 lprc, RECT
.参数 hBrush, 整数型
.子程序 __启动窗口_创建完毕
hk条背景颜色 = #青蓝
hTrackBarBrush = CreateSolidBrush(hk条背景颜色)
.如果真 (hTrackBarBrush = 0)
信息框("画刷创建失败!", 0, , )
结束()
.如果真结束
OldMainProc = SetWindowLongA(取窗口句柄(), #GWL_WNDPROC, 到数值(&NewProc_Main))
OldTrackBarProc = SetWindowLongA(hk条1.取窗口句柄(), #GWL_WNDPROC, 到数值(&NewProc_TrackBar))
.子程序 __启动窗口_将被销毁
.如果真 (是否已创建(hk条1))
SetWindowLongA(hk条1.取窗口句柄(), #GWL_WNDPROC, OldTrackBarProc)
.如果真结束
SetWindowLongA(取窗口句柄(), #GWL_WNDPROC, OldMainProc)
.如果真 (hTrackBarBrush ≠ 0)
DeleteObject(hTrackBarBrush)
hTrackBarBrush = 0
.如果真结束
.子程序 NewProc_Main, 整数型
.参数 hWnd, 整数型
.参数 Msg, 整数型
.参数 wParam, 整数型
.参数 lParam, 整数型
.判断开始 (Msg = #WM_CTLCOLORSTATIC 且 lParam = hk条1.取窗口句柄())
SetBkMode(wParam, #TRANSPARENT)
返回 (hTrackBarBrush)
.默认
返回 (CallWindowProcA(OldMainProc, hWnd, Msg, wParam, lParam))
.判断结束
.子程序 NewProc_TrackBar, 整数型
.参数 hWnd, 整数型
.参数 Msg, 整数型
.参数 wParam, 整数型
.参数 lParam, 整数型
.局部变量 rect, RECT
.判断开始 (Msg = #WM_ERASEBKGND)
GetClientRect(hWnd, rect)
FillRect(wParam, rect, hTrackBarBrush)
返回 (1)
.判断 (Msg = #WM_DESTROY)
返回 (CallWindowProcA(OldTrackBarProc, hWnd, Msg, wParam, lParam))
.默认
返回 (CallWindowProcA(OldTrackBarProc, hWnd, Msg, wParam, lParam))
.判断结束
关键代码解析
1. 初始化部分
.子程序 __启动窗口_创建完毕
hTrackBarBrush = CreateSolidBrush(#青蓝) ’ 创建背景画刷
SetWindowLongA(hk条1.取窗口句柄(), #GWL_WNDPROC, 到数值(&NewProc_TrackBar)) ’ 子类化hk条
2. 消息处理
’ 主窗口处理静态控件颜色
.判断开始 (Msg = #WM_CTLCOLORSTATIC)
返回 (hTrackBarBrush) ’ 返回自定义画刷
’ hk条处理背景擦除
.判断开始 (Msg = #WM_ERASEBKGND)
FillRect(wParam, rect, hTrackBarBrush) ’ 填充背景
3. 资源释放
.子程序 __启动窗口_将被销毁
DeleteObject(hTrackBarBrush) ’ 必须释放GDI对象
SetWindowLongA(..., OldTrackBarProc) ’ 恢复原始窗口过程
注意事项
- GDI 对象管理
- 必须成对调用
CreateSolidBrush / DeleteObject
- 建议添加错误检查:
hTrackBarBrush ≠ 0
- 子类化安全
- 窗口销毁前必须恢复原始过程
- 使用
是否已创建 ()
判断控件有效性
- 消息处理规范
- 未处理的消息必须传递原始过程
WM_ERASEBKGND
返回 1 表示已处理
下载附件
请在下方的附件中下载源代码:
修改hk条底色_Fix.e
(30.99 KB, 下载次数: 9)