- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
导读
本文围绕 RGF 仓颉版(下称 RGF)核心事件体系中的EvDwmColorizationColorChanged参数类展开,讲解当 Windows 桌面窗口管理器(DWM)的着色器色彩发生变化时,RGF 如何将该系统消息封装为类型安全的事件对象,并通过onDwmColorizationColorChanged回调方法与bindDwmColorizationColorChanged绑定属性两种方式暴露给应用层。读完本文,你将掌握该事件参数的构造原理、字段语义(0xAARRGGBB 着色色值与透明度标志)以及在自己的 RGF 窗口中监听系统配色变更的完整写法。
事件背景:WM_DWMCOLORIZATIONCOLORCHANGED 与 DWM 着色
Windows 的桌面窗口管理器(DWM)负责桌面合成与窗口外观渲染,其中"着色"(Colorization)决定任务栏、窗口边框等非客户区元素的系统强调色。当用户通过个性化设置修改强调色,或系统主题发生切换时,DWM 会向所有顶级窗口广播WM_DWMCOLORIZATIONCOLORCHANGED消息(消息值0x0320),通知应用层着色颜色已变更。
在 RGF 中,这一原始 Win32 消息在 hwinuser.cj 中被定义为常量:
public const WM_DWMCOLORIZATIONCOLORCHANGED:UInt32 = 0x0320RGF 遵循"事件参数类以Ev前缀命名"的约定(见 rgf_proc.cj 的注释约定),将这条消息的参数封装为EvDwmColorizationColorChanged,与EvDwmCompositionChanged、EvDwmNcRenderingChanged、EvDwmWindowMaximizedChange等共同构成 DWM 相关的事件参数族(可在 rgf_core 模块 readme 中查看完整清单)。
类签名与继承结构
EvDwmColorizationColorChanged的定义如下(见 rgf_proc.cj):
/** @brief DWM着色器色彩变更 - 事件参数 */ public open class EvDwmColorizationColorChanged <: EvCore{ // 0xAARRGGBB public let colorizationColor:UInt32 public let opacity:Bool @OverflowWrapping public init(wParam:UInt64, lParam:Int64) { super(0x0320 /*WM_DWMCOLORIZATIONCOLORCHANGED*/, wParam,lParam) colorizationColor = UInt32(wParam) opacity = lParam != 0 } }它与文档 EvDwmColorizationColorChanged.md 中声明的 API 签名完全一致:
public open class EvDwmColorizationColorChanged <: EvCore该类继承自EvCore。EvCore是所有 RGF 事件参数类的公共基类(见 rgf_proc.cj),它为每个事件对象保留了原始消息的完整信息:
/** @brief 核心事件参数 */ public open class EvCore{ // 当前方法是否已经被覆盖 internal var isOverride:Bool = true; public let message:UInt32 public let wParam:UInt64 public let lParam:Int64 public init(uMsg:UInt32, wParam:UInt64, lParam:Int64) { this.message = uMsg; this.wParam = wParam; this.lParam = lParam; } }也就是说,即便后续 RGF 升级为colorizationColor、opacity增加了更丰富的解析字段,你依然可以通过继承自EvCore的message、wParam、lParam访问到最原始的 Win32 消息数据,便于排查问题或自行扩展解析逻辑。
构造函数与 Win32 消息参数解析
函数签名
@OverflowWrapping public init(wParam: UInt64, lParam: Int64)| 名称 | 类型 | 描述 |
|---|---|---|
| wParam | UInt64 | DWM 广播的着色颜色值(WM_DWMCOLORIZATIONCOLORCHANGED的 wParam) |
| lParam | Int64 | 透明度启用标志(WM_DWMCOLORIZATIONCOLORCHANGED的 lParam) |
参数解析细节
构造函数内部完成两件事(见 rgf_proc.cj):
- 调用基类构造器
super(0x0320, wParam, lParam),将消息编号0x0320、原始wParam、lParam一并存入EvCore; - 对参数做类型转换与语义化:
colorizationColor = UInt32(wParam):将 64 位wParam低 32 位截断为UInt32颜色值;opacity = lParam != 0:将lParam转换为布尔值,非零表示透明度已启用。
需要注意的是构造器标注了@OverflowWrapping注解,这与 RGF 其他事件参数类(如EvAppCommand、EvDwmNcRenderingChanged)保持一致——此类转换基于 Win32 消息参数的实际位布局,在参数极端取值下采用包装语义而非抛出溢出异常,保证窗口过程在处理系统消息时始终能够稳定构造出事件对象。
事件属性详解
EvDwmColorizationColorChanged对外暴露两个只读字段(public let,构造后不可修改):
colorizationColor:UInt32 —— 新的 DWM 着色颜色
public let colorizationColor: UInt32其格式为0xAARRGGBB(见 rgf_proc.cj 注释与 API 文档 EvDwmColorizationColorChanged.md):
AA:Alpha 通道(透明度分量,8 位);RR:红色分量(8 位);GG:绿色分量(8 位);BB:蓝色分量(8 位)。
由于颜色以UInt32整体存储,读取时可直接用于后续的位运算拆解,例如:
let argb = e.colorizationColor let a:UInt32 = (argb >> 24) & 0xFF // Alpha let r:UInt32 = (argb >> 16) & 0xFF // Red let g:UInt32 = (argb >> 8) & 0xFF // Green let b:UInt32 = argb & 0xFF // Blue注意 RGF 渲染侧(Surface、Color等)通常采用 0~1 的浮点颜色分量(可参考 HLT 测试用例 中createSolidColorBrush(0.5,0.0,0.0,1.0,5.0)的用法),如需将colorizationColor应用到渲染画刷,建议自行完成0~255 → 0~1的换算。
opacity:Bool —— 透明度启用标志
public let opacity: Bool由lParam != 0推导而来:true表示当前 DWM 着色启用了透明度,false表示不透明。该字段可用于判断系统当前强调色是否为半透明模式,从而决定应用窗口是否同步调整自身边框或控件的透明渲染策略。
接入事件:两种推荐方式
RGF 为WM_DWMCOLORIZATIONCOLORCHANGED提供了两条接入路径,均可在 API 文档中找到对应接口声明:
- 继承覆盖方式:重写窗口基类的
onDwmColorizationColorChanged(e: EvDwmColorizationColorChanged): Unit方法,见 IEvent.md; - 绑定回调方式:设置
bindDwmColorizationColorChanged: Option<(EvDwmColorizationColorChanged) -> Unit>属性,见 IBindEvent.md。
方式一:继承并覆盖 onDwmColorizationColorChanged
在消息分发链路上(rgf_proc.cj),RGF 收到0x0320消息时会先构造事件对象,再派发到回调方法:
case 0x0320 /*WM_DWMCOLORIZATIONCOLORCHANGED*/ =>{=> let eObj:EvDwmColorizationColorChanged = EvDwmColorizationColorChanged(wParam,lParam) onDwmColorizationColorChanged(eObj) return (0,eObj.isOverride) }基类默认实现仅将isOverride置为false(rgf_proc.cj),表示"未被覆盖、消息按默认方式处理",且该消息处理后返回0。应用层只要在继承WinBase的窗口类中重写该方法即可拦截事件:
public override open func onDwmColorizationColorChanged(e:EvDwmColorizationColorChanged):Unit{ println("DWM 着色颜色已变更: ${e.colorizationColor.toString(16)}, 透明度: ${e.opacity}") super.onDwmColorizationColorChanged(e) }方式二:绑定回调 bindDwmColorizationColorChanged
若不想通过继承改写窗口类,可以使用绑定属性方式。在绑定分发链路(rgf_proc.cj)中,构造事件对象后直接调用用户绑定的回调:
case 0x0320 /*WM_DWMCOLORIZATIONCOLORCHANGED*/ =>{=> let eObj:EvDwmColorizationColorChanged = EvDwmColorizationColorChanged(wParam,lParam) return if(let Some(v) <- bindDwmColorizationColorChanged?(eObj)){ 0 }else{ Option<Int64>.None } }绑定示例:
win.bindDwmColorizationColorChanged = Some({e => println("绑定方式收到 DWM 色彩变更: ${e.colorizationColor} / opacity=${e.opacity}") })宏生成机制(源码级佐证)
上述两条分发分支并非手写维护,而是由编译期宏生成。在 rgf_proc_utils.cj 与 rgf_proc_utils.cj 中,分别以("onDwmColorizationColorChanged","EvDwmColorizationColorChanged","Unit")和("bindDwmColorizationColorChanged","EvDwmColorizationColorChanged","Unit")为键,生成对应的case 0x0320分发代码。这意味着:只要开发者按 RGF 约定在窗口类中声明覆盖方法或绑定属性,宏即自动接入消息循环,无需手写任何wndProc分支(关于窗口注册与消息循环的完整流程,可参考 HLT 测试用例 中的rsMain启动方式)。
完整实战示例
以下示例完整展示如何在 RGF 窗口中监听系统 DWM 着色颜色变化(窗口骨架参照 test/HLT/base/src/test_win.cj 的rwTest模式):
public open class DwmColorWatchWin <: WinBase{ // 窗口创建(省略部分参数,完整签名见 WinBase 文档) public open func createWin( winCtxt:WinContext, lpWindowName:String, x:Int32, y:Int32, nWidth:Int32, nHeight:Int32, parent:RgfHwnd, dwExStyle:UInt32, dwStyle:UInt32, substrate!:Substrate, layered!:Bool ):RgfHwnd{ return super.createWin( winCtxt, lpWindowName, x, y, nWidth, nHeight, parent, dwStyle, dwExStyle:dwExStyle, substrate:substrate, layered:layered ) } // 监听 DWM 着色器色彩变更 public override open func onDwmColorizationColorChanged(e:EvDwmColorizationColorChanged):Unit{ let argb = e.colorizationColor println("消息ID=0x0320 (WM_DWMCOLORIZATIONCOLORCHANGED)") println("ARGB=${argb.toString(16)} (0xAARRGGBB)") println("Alpha=${(argb >> 24) & 0xFF} Red=${(argb >> 16) & 0xFF} Green=${(argb >> 8) & 0xFF} Blue=${argb & 0xFF}") println("opacity=${e.opacity}") // 原始消息数据仍可通过基类访问 println("raw wParam=${e.wParam} lParam=${e.lParam}") super.onDwmColorizationColorChanged(e) } }运行后,在 Windows 设置中修改"个性化 → 颜色 → 强调色"或切换深浅色主题,DWM 广播0x0320消息,上述窗口即会打印新的着色颜色与透明度标志。
注意事项与扩展阅读
- 触发时机:
WM_DWMCOLORIZATIONCOLORCHANGED由系统在 DWM 着色颜色或透明度设置变更时向所有顶级窗口广播,无需应用主动注册,只要窗口消息循环处于运行状态即可收到。 - 仅顶层窗口:该消息面向顶级窗口广播,子窗口不会直接收到;如子窗口需要同步,可在父窗口回调中自行转发。
- 返回值:RGF 对该消息统一返回
0(表示"已处理"),应用层回调无需(也无法)修改该返回值。 - 同类事件:如需感知 DWM 合成开关(
WM_DWMCOMPOSITIONCHANGED)、非客户区渲染策略(WM_DWMNCRENDERINGCHANGED)、窗口最大化(WM_DWMWINDOWMAXIMIZEDCHANGE)等相邻系统状态,可分别使用EvCore/EvDwmNcRenderingChanged/EvDwmWindowMaximizedChange对应事件,相关参数类均位于 rgf.rgf_core 类目录 下。 - 底层常量与文档:消息编号定义见 hwinuser.cj 与 win_def 变量与常量文档;事件类的完整 API 参考见 EvDwmColorizationColorChanged.md,模块级索引见 rgf_core readme。
综上,EvDwmColorizationColorChanged是 RGF 将系统级 DWM 着色变更"翻译"为类型安全事件参数的典型示例:构造器负责位级参数解析(wParam → 0xAARRGGBB、lParam → Bool),EvCore基类兜底保留原始消息数据,宏生成机制负责自动接入窗口消息循环,开发者只需选择覆盖方法或绑定回调即可响应系统配色变化。
- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
相关推荐
RGF 仓颉版事件体系详解:EvContextMenu 上下文菜单事件参数类
RGF 仓颉版事件体系详解:EvContextMenu 上下文菜单事件参数类 RGF(仓颉版)在 rgf.rgf_core 子包中提供了一套完整的 Win32
图形学桌面应用RGF 仓颉版 ColorUtils 色彩插值工具类:`lerp` 接口解析与实战
RGF 仓颉版 ColorUtils 色彩插值工具类: lerp 接口解析与实战 ColorUtils 是 RGF 仓颉版(RGF_CJ) rgf.rgf_ut
图形学桌面应用RGF 仓颉版事件参数 EvCaptureChanged:WM_CAPTURECHANGED 鼠标捕获状态变更的完整解析
RGF 仓颉版事件参数 EvCaptureChanged:WM_CAPTURECHANGED 鼠标捕获状态变更的完整解析 本文围绕 RGF(Cangjie 版)
图形学桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考