- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
导读
EvGestureNotify是仓颉版通用渲染框架 RGF(RGF_CJ)在rgf_core子包中提供的手势触控通知事件参数类,对应 Windows 消息WM_GESTURENOTIFY(0x011A)。本文围绕 EvGestureNotify 文档 展开,结合 rgf_proc.cj 中该类 59 行的完整实现,剖析其从 Win32 结构体GESTURENOTIFYSTRUCT到仓颉事件对象的解析映射过程、可写回的手势配置字段,以及继承式与绑定式两种事件接入方式。读完本文,你将能在 RGF 窗口中接收手势通知、读取触控目标与位置信息,并通过postProcess()回写手势配置。
EvGestureNotify 的定位:手势发生前的配置通知
在 RGF 的窗口消息事件体系中,EvGestureNotify与EvGesture成对出现,分别对应两条相邻的 Windows 消息:
| 事件参数类 | Windows 消息 | 消息值 | 语义 |
|---|---|---|---|
EvGesture | WM_GESTURE | 0x0119 | 手势触发,实际的手势动作发生 |
EvGestureNotify | WM_GESTURENOTIFY | 0x011A | 手势触控通知,在手势处理前通知窗口,可借此设置手势配置 |
该对应关系在 rgf_proc.cj 的消息分发表中可直接验证。两条分支的注释分别为"手势触发"与"本消息可设置手势配置",后者正是EvGestureNotify的核心用途。在 rgf_core 的 readme 的事件参数类索引中,两者同样被相邻列出。
public open class EvGestureNotify <: EvCoreEvGestureNotify继承自 EvCore(核心事件参数基类),因此自动拥有message、wParam、lParam三个只读字段,分别保存原始消息号、消息参数与扩展参数,可用于与原始 Win32 消息对照调试。
五个可读可写成员:与 GESTURENOTIFYSTRUCT 的一一映射
EvGestureNotify公开了 5 个var(可变)成员,完整覆盖了 Win32 结构体tagGESTURENOTIFYSTRUCT的全部字段。结构体定义位于 hwinuser.cj,对应的文档见 tagGESTURENOTIFYSTRUCT:
| EvGestureNotify 成员 | 类型 | 对应结构体字段 | Win32 类型 | 含义(基于源码注释与字段命名) |
|---|---|---|---|---|
cbSize | UInt32 | cbSize | UINT | 结构体大小,用于标识结构版本 |
dwFlags | UInt32 | dwFlags | DWORD | 手势标志,可写回以控制手势行为 |
hwndTarget | RgfHwnd | hwndTarget | HWND | 手势目标窗口句柄 |
ptsLocation | Point | ptsLocation | POINTS | 手势发生位置(RGF 以Point封装) |
dwInstanceID | UInt32 | dwInstanceID | DWORD | 手势实例标识,用于关联连续的手势 |
其中hwndTarget使用了 RGF 的窗口句柄类型RgfHwnd,而ptsLocation使用 Point 位置类封装,这两个类型均是 RGF 对 Win32 原生类型的统一包装,体现了"开箱即用的 Windows API"设计思路:开发者操作的是仓颉类型,底层则直接对接系统结构体。
init(wParam, lParam):底层结构体的解析过程
@OverflowWrapping public init(wParam: UInt64, lParam: Int64)构造函数接收与消息一起到达的wParam、lParam两个原生参数。@OverflowWrapping标注表明其内部涉及整型与指针之间的位宽换算,采用回绕语义避免溢出检查的开销。
从 rgf_proc.cj 的实现可以看到完整的三步解析:
- 基类初始化:调用
super(0x011A /*WM_GESTURENOTIFY*/, wParam, lParam),把消息号、原始参数存入EvCore; - 指针转换:
ptr = CPointer<GESTURENOTIFYSTRUCT>(ruUllToPtr(ruInt64SafeToUIntNative(lParam)))——将lParam安全转换为无符号原生整数,再转为指向GESTURENOTIFYSTRUCT的指针。在 Win32 中,WM_GESTURENOTIFY的lParam正是指向该结构体的指针; - 内存读取与字段拷贝:
Obj = unsafe{ ptr.read() }一次性读取结构体,随后逐字段赋值,其中位置坐标ptsLocation从原生POINTS(Int16坐标)转换为Point(Int32(...), Int32(...))。
可以看到,EvGestureNotify本质上是一个"内存视图 + 安全包装":原始结构体同时以内部指针ptr和值副本Obj保留,公开成员只是这些内部状态的投影。
postProcess():把修改写回系统,完成手势配置
@OverflowWrapping public func postProcess()postProcess()是EvGestureNotify区别于大多数只读事件参数类的关键方法,其实现位于 rgf_proc.cj。它执行init的逆过程:
- 将 5 个公开成员逐一写回内部副本
Obj(hwndTarget通过ruToHwnd从RgfHwnd还原为HWND,ptsLocation的Int32坐标截断回Int16写入POINTS); unsafe{ ptr.write(Obj) }将修改后的结构体整体写回lParam指向的原生内存。
也就是说,开发者可以在回调中修改dwFlags、hwndTarget、ptsLocation、dwInstanceID等字段,再调用postProcess(),让修改真正作用于系统手势管线——这正是源码注释"本消息可设置手势配置"的具体实现方式。
两种接入方式:继承回调与事件绑定
与 RGF 所有窗口事件一致,EvGestureNotify支持两种接入范式,两者的消息分发代码均由宏在 rgf_proc_utils.cj 中生成(继承式生成点、绑定式生成点)。
方式一:继承窗口类并覆写 onGestureNotify
在 rgf_proc.cj 中定义了默认实现,覆写它即可接收通知:
// @brief 本消息可设置手势配置 func onGestureNotify(e: EvGestureNotify): Unit { e.isOverride = false }消息到达时,分发逻辑构造EvGestureNotify(wParam, lParam)后调用onGestureNotify(eObj),随后以return (0, false)结束——源码在此处特别注释"本消息始终应该从 DefWindowProc 返回值",即不覆写系统对该消息的默认处理结果。
方式二:通过 bindGestureNotify 绑定事件函数
IBindEvent事件绑定式分发接口在 IBindEvent.md 中声明了该属性,其实现位于 rgf_proc.cj:
// @brief 本消息可设置手势配置 mut prop bindGestureNotify: Option<(EvGestureNotify) -> Unit> { get() { None } set(v) { throw NoneValueException(rgfFunctionWillIgnored) } }case 0x011A /*WM_GESTURENOTIFY*/ => { let eObj: EvGestureNotify = EvGestureNotify(wParam, lParam) bindGestureNotify?(eObj) return Option<Int64>.None // 本消息始终应该从 DefWindowProc 返回值 }绑定方式下,回调被调用后分发器直接返回None,同样将最终处理权交还DefWindowProc。两种方式都遵循"手势通知不拦截、仅配置"的原则。
与 EvGesture 协同:一次完整的手势处理流程
结合两条消息的分发代码(rgf_proc.cj),一次典型的手势交互在 RGF 中会经历两个阶段:
- 通知阶段(WM_GESTURENOTIFY / 0x011A):系统在识别手势前先通知窗口。此时
EvGestureNotify携带目标窗口hwndTarget、手势位置ptsLocation与实例标识dwInstanceID,应用可修改字段并调用postProcess()调整后续手势识别行为; - 触发阶段(WM_GESTURE / 0x0119):手势正式发生,
EvGesture事件参数携带原始参数arguments与信息句柄handle(见 EvGesture 文档),应用在此完成手势的实际响应与绘制。
应用可以同时覆写onGestureNotify与onGesture(或同时绑定bindGestureNotify与bindGesture),在通知阶段做配置、在触发阶段做响应,形成完整的手势交互闭环。
实践要点小结
- 消息号识别:
EvGestureNotify.message固定为0x011A,可据此在通用事件处理中区分手势通知; - 坐标注意:
ptsLocation在内部经过POINTS(Int16)到Point(Int32)的转换,读取时无需再处理原生坐标类型;写回时超出Int16范围的坐标会被截断,配置坐标时应注意窗口尺寸限制; - 写回时机:只有在
postProcess()被调用后,对成员字段的修改才会写入系统结构体,只读观察场景不必调用; - 返回值约定:无论继承式还是绑定式,
WM_GESTURENOTIFY都应放行给DefWindowProc处理,不要返回自定义值拦截消息。
如需继续深入,可对比阅读 EvGesture.md 了解手势触发阶段的事件参数,或查阅 IBindEvent.md 查看全部绑定式事件属性。
- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
相关推荐
RGF_CJ 手势触控事件参数类 EvGesture 详解:从 WM_GESTURE 到 onGesture/bindGesture 的完整事件链路
RGF_CJ 手势触控事件参数类 EvGesture 详解:从 WM_GESTURE 到 onGesture/bindGesture 的完整事件链路 RGF(仓
图形学桌面应用RGF_CJ 窗口可用性事件 EvEnable 详解:从 WM_ENABLE 消息到事件参数类
RGF_CJ 窗口可用性事件 EvEnable 详解:从 WM_ENABLE 消息到事件参数类 导读 :本文深入剖析 RGF(仓颉 Windows 系统通用渲染
图形学桌面应用GitHub汉化插件终极指南:3分钟让GitHub说中文,告别英文困扰
GitHub汉化插件终极指南:3分钟让GitHub说中文,告别英文困扰 你是否曾经面对GitHub的全英文界面感到迷茫?"Repository"、"Pull R
前端国际化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考