本帖最后由 gytxtx 于 2025-2-5 14:44 编辑
标题:
【易语言子类化实战】自定义按钮边框颜色 | 纯源码 + WM_CTLCOLORBTN 消息处理
其实具体来说应该是修改底色吧,毕竟我的需求是修改 Windows 10 按钮的 1px 的边框,这个默认边框在窗口底色不是默认底色的时候就很烦人(会出现色差)
源码简介
通过窗口子类化(Subclassing)技术,拦截 WM_CTLCOLORBTN 消息,实现按钮边框颜色的自定义绘制。代码简洁高效,适用于 易语言 5.x 版本,无第三方依赖。
实现原理
- 子类化(Subclassing)
- 核心思想:替换窗口的默认消息处理过程(
WndProc ),插入自定义逻辑。
- 关键 API:
SetWindowLongA 修改窗口过程 → CallWindowProcA 调用原有逻辑。
- 颜色控制
WM_CTLCOLORBTN 消息:当按钮需要绘制时触发,返回画刷句柄决定背景色。
- 颜色设置:
CreateSolidBrush 创建画刷 → SetTextColor / SetBkColor 设置文本和背景色。
源码展示
核心代码(完整源码见附件)
.版本 2
.程序集 窗口程序集_启动窗口
.程序集变量 OldBtnProc, 整数型 ' 保存按钮原始窗口过程
.程序集变量 hBtnBrush, 整数型 ' 按钮背景画刷
.子程序 __启动窗口_创建完毕
hBtnBrush = CreateSolidBrush (#绿色) ' 创建绿色画刷
' 子类化按钮
OldBtnProc = SetWindowLongA (按钮1.取窗口句柄 (), #GWL_WNDPROC, 到数值 (&BtnProc))
.子程序 BtnProc, 整数型
.参数 hWnd, 整数型
.参数 uMsg, 整数型
.参数 wParam, 整数型
.参数 lParam, 整数型
.判断开始 (uMsg = #WM_CTLCOLORBTN)
SetTextColor (wParam, #白色) ' 设置文字白色
SetBkColor (wParam, #绿色) ' 设置背景绿色
返回 (hBtnBrush) ' 返回画刷
.判断 (uMsg = #WM_DESTROY)
' 恢复原始窗口过程,防止内存泄漏
SetWindowLongA (hWnd, #GWL_WNDPROC, OldBtnProc)
返回 (0)
.默认
' 其他消息交还系统处理
返回 (CallWindowProcA (OldBtnProc, hWnd, uMsg, wParam, lParam))
.判断结束
.子程序 __启动窗口_将被销毁
DeleteObject (hBtnBrush) ' 释放画刷
使用说明
- 直接调用:
将代码粘贴到易语言窗口程序集中,修改 #绿色 为其他颜色值即可。
- 扩展应用:
- 修改
WM_PAINT 实现更复杂绘制
- 动态切换颜色:在事件中调用
DeleteObject + 重新创建画刷
注意事项
- 资源释放:
- 必须调用
DeleteObject 释放画刷,否则会 GDI 泄漏!
- 窗口销毁时恢复原始
WndProc (见 WM_DESTROY 处理)。
- 线程安全:
- 动态控件:
- 循环创建按钮时,需为每个控件单独保存 OldProc。
常见问题
Q1:如何修改边框粗细?
A:需处理 WM_NCPAINT 消息,或改用自绘组件。
Q2:Win10 / Win11 下颜色不生效?
A:部分系统版本需额外处理 WM_THEMECHANGED 。
下载附件
请在下方的附件中下载源代码:
修改按钮边框颜色.e
(7.25 KB, 下载次数: 5)
|