- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
本篇文章系统梳理 RGF_CJ(仓颉版 RGF 通用渲染框架)核心包rgf.rgf_core暴露的全部顶层函数(API 文档见 doc/api/rgf.rgf_core/函数.md),涵盖应用主流程(rsMain/rsInitialize/rsDestroy)、系统定时器、显示器查询、窗口类注册与批量布局、以及字符串/指针等 Win32 互操作工具函数。阅读后你将掌握 RGF_CJ 的全局函数命名约定、每个函数的参数与返回值语义、底层 Win32 调用链,并能独立拼装出一个完整的 RGF 桌面应用骨架。
全局函数三大家族:rs、ru、rw 前缀约定
rgf.rgf_core的公开函数按用途分为三个前缀家族,从源码 src/rgf_core/rgf_api.cj、src/rgf_core/rgf_utils.cj 与 src/rgf_core/rgf_base.cj 中可以清晰看出其分工:
| 前缀 | 语义 | 典型成员 |
|---|---|---|
rs | RGF System,框架级系统函数:初始化/释放、主入口、定时器、进程结束、显示器查询 | rsMain、rsInitialize、rsDestroy、rsCreateSysTimer、rsEnd |
ru | RGF Utility,通用工具函数:字符串编码转换、指针互转、内存安全、位重解释、句柄转换 | ruStrToWStr、ruUllToPtr、ruSafeCStruct、ruRedefBit、ruToHwnd |
rw | RGF Window,窗口相关函数:窗口类注册/注销、批量移动、主窗口判断、默认窗口过程 | rwRegister、rwUnregister、rwBatchMove、rwIsMainWin |
这三类函数共同构成了 RGF_CJ 面向应用层开放的"系统 API 面"。其中涉及句柄的类型别名定义见 doc/api/rgf.rgf_core/类型别名.md:RgfHwnd = UIntNative(窗口句柄)、RgfHdc = UIntNative(设备上下文)、RgfTimer = HANDLE(定时器句柄)。
应用生命周期管理:rsMain 主入口与三种运行模式
rsMain是 RGF_CJ 应用的主入口,内部封装了 Win32 消息循环的完整流程。官方注释特别说明:"本函数内部封装了 Win 的主要流程,若需要更高的自由度可参考此代码结构自行实现"。
函数签名与重载
// 完整形态:create 回调 + destroy 回调 + 运行模式(默认阻塞当前线程) public func rsMain(create: () -> Unit, destroy: () -> Unit, mode!: RunMode): Unit // 便捷重载:只提供 create,destroy 为空实现,默认 SysThreadAndWait @When[!debug] public func rsMain(create: () -> Unit): Unit // 便捷重载:create + destroy,默认 SysThreadAndWait @When[!debug] public func rsMain(create: () -> Unit, destroy: () -> Unit): Unit // 便捷重载:create + 显式 mode public func rsMain(create: () -> Unit, mode!: RunMode): Unit参数说明:
| 参数 | 类型 | 描述 |
|---|---|---|
create | ()->Unit | 用于创建窗口相关资源的回调(窗口类注册、窗口创建、渲染资源初始化) |
destroy | ()->Unit | 用于释放窗口相关资源的回调(窗口销毁、窗口类注销) |
mode | RunMode | 主函数运行模式,默认阻塞当前线程 |
RunMode 三种模式
mode参数取值定义在 doc/api/rgf.rgf_core/枚举/RunMode.md:
| 枚举值 | 语义 | 说明 |
|---|---|---|
CJMainThread | 直接基于仓颉主线程 | 在主线程上直接运行消息循环,无需额外线程 |
SysThreadAndAsyn | 新建系统线程,异步不阻塞 | UI 线程独立运行,调用rsMain的线程继续向下执行 |
SysThreadAndWait | 新建系统线程,并等待执行结束 | UI 线程运行期间阻塞调用线程,直到窗口全部关闭 |
默认模式随编译条件切换
从源码 src/rgf_core/rgf_base.cj#L1358-L1400 可以看出,两个便捷重载的默认模式依赖编译条件:
@When[!debug](非调试构建,即发行版):默认RunMode.SysThreadAndWait,创建独立系统 UI 线程并阻塞等待;@When[debug](调试构建):默认RunMode.CJMainThread,直接在仓颉主线程上跑窗口逻辑。
这是因为在调试环境下仓颉侧部分功能在系统线程上表现异常,主线程模式便于断点与调试。
底层流程:rsMainInner 消息循环
rsMain的真正实现在rsMainInner(src/rgf_core/rgf_base.cj#L1234-L1293),其执行顺序为:
- 获取模块句柄:调用
wGetModuleHandleW得到HINSTANCE; - 初始化 RGF 绘制库:
CJMainThread模式复用全局初始化自动机持有的上下文,其余模式调用rsInitialize(); - 构造全局上下文:
context = Context(contextPtr, hInst); - 执行 create 回调:
rgfCreateFunc()调用用户传入的create; - 进入消息循环:
while(haveMainWin.load())循环执行wGetMessageW→ 错误处理(bRet < 0抛WinException)→WM_QUIT(bRet == 0)跳出 → 过滤无效窗口消息 →wTranslateMessage→wDispatchMessageW。当主窗口被销毁(haveMainWin为 false)时循环自动退出; - 执行 destroy 回调:
rsDestroyFunc()调用用户destroy,并顺带清理所有记录在案、未被释放的窗口类(rwClearAllWinClass); - 释放上下文与绘制库:置空
context,非主线程模式下调用rsDestroy(contextPtr); - 清理全局依赖并允许再次进入。
注意:rsMain内部通过AtomicBool互斥保证"主 UI 线程只能初始化一次";重复进入会抛出异常,异常文本见常量rgfErrorMainUiThreadinited("RGF 的主 UI 线程已被初始化!",见 doc/api/rgf.rgf_core/变量与常量.md)。
实战骨架:来自测试工程的标准用法
仓库测试工程 test/CT/base/src/main.cj 给出了标准应用骨架:
func TestCall(): Int64 { rsModRefToCurrDir() // 将程序存储路径作为相对路径起点 let mainWin: rwTest = rwTest() let winClass: WinContext = WinContext() rsMain( {=> // create:创建窗口相关资源 // 1. 注册窗口类 rwRegister(winClass, "GF_", WinClassStyle.DblClks | WinClassStyle.HRedraw | WinClassStyle.VRedraw ) // 2. 创建 Direct2D 窗口 mainWin.createWin(winClass, "test", Int32.Min, Int32.Min, 500, 500, 0, WinStyleEx.e2n(WinStyleEx.Default), WinStyle.e2n(WinStyle.OverlappedWindow), substrate: Substrate.Direct2D, layered: false ) }, {=> // destroy:释放窗口相关资源 // 3. 确保窗口被释放(安全释放) // 4. 注销窗口类 rwUnregister(winClass) } ) return 0 } main(): Int64 { TestCall() return 0 }SysThreadAndAsyn 模式与 ruFinished/rsEnd 的配合
当选择RunMode.SysThreadAndAsyn时,rsMain立即返回,主线程可继续做自己的事(如摄像头采集、后台计算),此时用ruFinished()判断 UI 是否已结束。文档明确说明:ruFinished 一般用于rsMainmode 为SysThreadAndAsyn的情况下,用于检查并阻塞其它线程。
public func ruFinished(): Bool // false 正在执行;true 执行完成其实现(src/rgf_core/rgf_base.cj#L1419-L1421)为return !isInInner(),即内部"进入标志"被清除(消息循环结束并exitInner())后返回 true。
rsEnd(exitCode: UInt32)用于强制结束进程,底层直接调用wExitProcess(exitCode)(src/rgf_core/rgf_utils.cj#L364-L366),参数exitCode为进程退出码。摄像头测试工程 test/HLT/camera/src/main.cj 演示了完整的组合用法:
rsMain({=> /* 注册窗口类、创建窗口 */ }, mode: RunMode.SysThreadAndAsyn) // 主线程继续执行摄像头采集逻辑 let camera = CameraManager() if(camera.initialize()){ if(camera.loadDevices() && camera.deviceCount > 0){ let fmts = camera.getDeviceFormats(0) if(fmts.size > 0 && camera.select(0, fmts[0].size)){ while(!ruFinished()){ // UI 未结束期间持续采集 if(let Some(frame) <- camera.frameLock()){ mainWin.updateFrame(frame, fmts[0].size) camera.frameUnLock() } sleep(Duration.millisecond * 30) // 帧率 30fps } } camera.unselect() } camera.shutdown() } main(): Int64 { TestCall() rsEnd(0) // 仓颉中 SysThreadAndAsyn / SysThreadAndWait 模式下,调试时可能导致误报 return 0 }全局上下文:rsInitialize / rsDestroy / rsGetContext / rsModRefToCurrDir
初始化与释放
| 函数 | 签名 | 说明 |
|---|---|---|
rsInitialize | public func rsInitialize(): ContextPtr | RGF 绘制库全局初始化,返回全局上下文 Token。文档强调:本函数创建的上下文环境需要使用rsDestroy()方法释放 |
rsDestroy | public func rsDestroy(token: ContextPtr): Bool | RGF 绘制库全局释放,返回是否成功释放 |
两者分别是对 FFI 函数rApiInitialize与rApiDestroy的薄封装(src/rgf_core/rgf_api.cj#L111-L119),在rsMain内部被自动调用;只有当你绕过rsMain自建消息循环时才需要手动成对调用。注意:CJMainThread模式下rsMain不会手动释放上下文("交给 GC 处理"),其余模式在消息循环退出后自动调用rsDestroy。
获取全局上下文
public func rsGetContext(): Option<Context>返回当前全局上下文Context(doc/api/rgf.rgf_core/结构体/Context.md 中定义的技术上下文结构体),其内部持有 RGF 底层上下文指针与程序模块句柄hInst。由于rsMain未运行时上下文不存在,返回类型是Option<Context>(src/rgf_core/rgf_utils.cj#L192-L194)。rwRegister内部即通过context.getOrThrow().hInst获取程序实例句柄来完成窗口类注册。
模块路径配置
public func rsModRefToCurrDir(): Unit"模块当前路径配置"——将当前程序的存储路径作为相对路径的起始点。底层调用rApiSetCurrentDirectoryToExe()(src/rgf_core/rgf_api.cj#L101)。测试工程中它总是出现在rsMain之前,用于保证后续以相对路径加载图片、字体、配置文件时不受"当前工作目录"影响。
系统定时器:rsCreateSysTimer / rsDestroySysTimer
RGF_CJ 提供基于 Win32Timer Queue(CreateTimerQueueTimer/DeleteTimerQueueTimer)的系统定时器,适合底层周期任务。
public func rsCreateSysTimer( callback: CFunc<(CPointer<Unit>, UInt8) -> Unit>, parameter: CPointer<Unit>, dueTime: UInt32, period: UInt32 ): RgfTimer| 参数 | 类型 | 描述 |
|---|---|---|
callback | CFunc<(CPointer<Unit>, UInt8) -> Unit> | 定时回调(@CLambda 表达式,即 C 调用约定的函数指针) |
parameter | CPointer<Unit> | 回调函数的参数(透传给回调) |
dueTime | UInt32 | 首次执行等待时间(毫秒) |
period | UInt32 | 每次间隔时间(毫秒) |
返回:成功返回定时器句柄RgfTimer(即HANDLE);失败抛出WinException。
销毁接口:
public func rsDestroySysTimer(timer: RgfTimer): Unit| 参数 | 类型 | 描述 |
|---|---|---|
timer | RgfTimer | 定时器句柄 |
⚠️ 文档特别提示:凡是本函数创建的定时器,都需要销毁。从实现看(src/rgf_core/rgf_utils.cj#L286-L316),rsCreateSysTimer通过wCreateTimerQueueTimer创建,标志位为WT_EXECUTEDEFAULT | WT_EXECUTELONGFUNCTION(允许长任务在专用线程池线程执行);rsDestroySysTimer调用wDeleteTimerQueueTimer,失败即抛WinException(wGetLastError())。因此务必在应用退出前成对销毁,避免句柄泄漏。
若你只是做 UI 动画级别的延时/周期任务,仓库还提供了更轻量的
RTimer(基于std.sync.timer改进,支持after/once/repeat/repeatDuring/repeatTimes与 Burst 追赶模式),见 src/protected/timer/rgf_timer.cj 及 doc/api/rgf.rgf_utils/类/RTimer.md。
显示器查询:rsGetMonitorFromPoint 三个重载
rsGetMonitorFromPoint获取桌面坐标系下某点所在的显示器工作区(rcWork,即排除任务栏后的可用区域)宽高,返回Rect。共有三个重载,坐标来源不同:
public func rsGetMonitorFromPoint(x: Int32, y: Int32): Rect // 桌面坐标系下的 X/Y 轴值 public func rsGetMonitorFromPoint(pos: Point): Rect // 整数位置值 public func rsGetMonitorFromPoint(pos: FPoint): Rect // 浮点位置值底层实现(src/rgf_core/rgf_utils.cj#L202-L231)依次调用:
wEnumDisplayMonitors枚举所有显示器;wPtInRect判断点是否落在某显示器监视矩形内;wGetMonitorInfoW取得该显示器的MONITORINFO,取其rcWork(工作区)作为结果;找不到匹配显示器时抛WinException。
Point/FPoint重载最终都转换为(Int32, Int32)形式(FPoint直接截断浮点为整数)。典型场景:多显示器环境下把窗口定位到鼠标所在的显示器,或计算窗口居中坐标。
窗口类管理:rwRegister / rwUnregister
RGF_CJ 封装了 Win32 窗口类(WNDCLASS)的注册与注销,配合WinContext使用(窗口上下文类,见 doc/api/rgf.rgf_core/类/WinContext.md)。
public func rwRegister( ctxt: WinContext, className: String, style: UInt32, hbrBackground!: Int32 = 5 // 默认 NULL_BRUSH ): Bool| 参数 | 类型 | 描述 |
|---|---|---|
ctxt | WinContext | 窗口上下文,注册成功后内部会记录底层窗口类指针与类名 |
className | String | 窗口类名 |
style | UInt32 | 窗口风格(可用WinClassStyle枚举组合,如DblClks | HRedraw | VRedraw) |
hbrBackground | Int32 | 窗口背景画刷,默认NULL_BRUSH(值为 5),即不自动擦背景 |
注销接口:
public func rwUnregister(ctxt: WinContext): Bool| 参数 | 类型 | 描述 |
|---|---|---|
ctxt | WinContext | 需要注销的窗口上下文 |
文档两条硬性提示:
- 非本类注册的窗口类需要手动注入窗口过程函数,否则 RGF 窗口类无法捕获系统事件——即只有通过
rwRegister注册的类,RGF 才能自动把 Win32 消息路由到绑定式事件体系; - 凡注册的窗口类都应该由
rwUnregister注销。
实现细节(src/rgf_core/rgf_api.cj#L134-L163):rwRegister内部把className通过ruStrToWStr转成宽字符串,调用 FFIrApiRegisterWinClass,成功后把(className, ctxt)记录进全局staticWinClassMap;rwUnregister调用rApiUnregisterWinClass并从 map 中移除。这就是rsMain退出时rwClearAllWinClass能自动善后的依据。
窗口操作:批量移动、主窗口判断、句柄反查与默认过程
rwBatchMove —— 一次系统调用批量布局窗口
public func rwBatchMove(batch: Array<(RgfHwnd, Int32, Int32, Int32, Int32)>): Bool public func rwBatchMove(batch: Array<(WinPure, Int32, Int32, Int32, Int32)>): Bool public func rwBatchMove(batch: Array<(IWinMethod, Int32, Int32, Int32, Int32)>): Boolbatch为移动对象信息数组,每个元组含义统一为[0]: 目标;[1] X 坐标;[2] Y 坐标;[3] 宽度;[4] 高度,区别仅在于目标的表达形式:
| 重载 | 元组第一个元素类型 |
|---|---|
| 重载一 | RgfHwnd(窗口句柄,UIntNative) |
| 重载二 | WinPure(RGF 窗口核心类,见 doc/api/rgf.rgf_core/类/WinPure.md) |
| 重载三 | IWinMethod(窗口常用方法接口,见 doc/api/rgf.rgf_core/接口/IWinMethod.md) |
返回:是否全部成功。实现(src/rgf_core/rgf_utils.cj#L322-L358)采用 Win32 延迟定位三步曲:wBeginDeferWindowPos(数量)→ 逐项wDeferWindowPos(hdwp, ..., x, y, w, h, SWP_NOZORDER | SWP_NOOWNERZORDER)→wEndDeferWindowPos(hdwp)一次性提交。任何一步失败(返回 null)立即返回false。相比逐窗口MoveWindow,这种方式能减少多次重排闪烁,适合多窗口联动布局。
rwIsMainWin —— 判断主窗口
public func rwIsMainWin(rw: WinPure): Bool public func rwIsMainWin(hWnd: RgfHwnd): Bool public func rwIsMainWin(rw: IWinMethod): Bool判断窗口是否为 RGF 主窗口(主窗口退出则消息循环跳出,参见rsMainInner中的haveMainWin条件)。三种重载的语义等价:句柄版直接与全局mainWinHwnd比较;WinPure版在状态达到GFState.Initialized后查底层;IWinMethod版委托给句柄版(src/rgf_core/rgf_utils.cj#L254-L275)。
rwGetRgfClass —— 句柄反查窗口类
public func rwGetRgfClass(rgfHwnd: RgfHwnd): Option<WinPure>通过 RGF 窗口句柄反查其对应的WinPure窗口类实例(返回Option,句柄无效时为None),底层由gfClassFromHandlePermanent从 RGF 维护的句柄映射中查找(src/rgf_core/rgf_utils.cj#L185-L187)。可用于在事件回调中把收到的原生句柄还原为窗口对象。
rwDefWindowProc —— 默认窗口过程包装
public func rwDefWindowProc(hWnd: RgfHwnd, uMsg: UInt32, wParam: UInt64, lParam: Int64)DefWindowProc的包装函数(src/rgf_core/rgf_utils.cj#L148-L150),将 RGF 句柄经ruToHwnd转换后转发给wDefWindowProcW。当你在自建窗口过程中处理了消息、需要把未处理消息交还系统默认处理时调用,四个参数与 Win32DefWindowProcW(hWnd, uMsg, wParam, lParam)一一对应。
字符串与编码互操作:ruStrToWStr / ruWStrToStr / ruFree / ruWStrlen / ruStrToCStr
Win32 API 普遍使用 UTF-16 宽字符(LPWSTR),而仓颉String是 UTF-8 语义字符串。RGF_CJ 提供一组编码转换工具,全部位于 src/rgf_core/rgf_api.cj:
| 函数 | 签名 | 说明 |
|---|---|---|
ruStrToWStr | public func ruStrToWStr(str: String): LPWSTR | 仓颉字符串 → C 宽字符串(含编码转换)。本函数创建的字符串需要使用ruFree释放 |
ruWStrToStr | public func ruWStrToStr(str: LPWSTR): String | C 宽字符串 → 仓颉字符串(含编码转换),内部自动释放中转缓冲 |
ruFree | public func ruFree(cPtr: CPointer<Unit>): Unit | 释放宽字符串,专门用于释放ruStrToWStr申请的内存空间 |
ruWStrlen | public func ruWStrlen(wcharPtr: LPWSTR): UInt32 | 获取 C 宽字符串长度(宽字符数),底层调用rApiWcharslen |
ruStrToCStr | public func ruStrToCStr<T>(str: String, callback: (cStr: LPWSTR) -> T) | 字符串编码转换与自动释放:转换 → 执行回调 → 自动释放,免去手动ruFree |
内存管理要点:ruStrToWStr的实现是"mallocCString→rApiCharStrToWcharStr转换 →free临时 CString",返回的宽字符串指针由 RGF 底层分配;ruWStrToStr反向转换时会自动释放内部临时缓冲。因此成对记忆是:
- 手动模式:
let w = ruStrToWStr(str)… 用完后ruFree(CPointer<Unit>(w)); - 自动模式:
ruStrToCStr(str) { cStr => /* 使用 cStr */ },回调返回后自动释放(内部调用rApiReleaseWcharStr)。
指针与句柄互操作:ruUllToPtr / ruLlToPtr / ruToHwnd / ruToHdc
RGF_CJ 的 RGF 侧句柄(RgfHwnd/RgfHdc)本质是UIntNative整数,而 Win32 FFI 需要CPointer/HWND/HDC,因此提供两组转换:
// 数值 ↔ 裸指针 public func ruUllToPtr(ptrVal: UIntNative): CPointer<Unit> // 无符号数值 → C 侧指针(标注 @FastNative) public func ruLlToPtr(ptrVal: IntNative): CPointer<Unit> // 有符号数值 → C 侧指针 // RGF 句柄 ↔ Win32 句柄 public func ruToHwnd(rgfHwnd: RgfHwnd): HWND // 内部实现:HWND(ruUllToPtr(rgfHwnd)) public func ruToHdc(rgfHdc: RgfHdc): HDC // 内部实现:HDC(ruUllToPtr(rgfHdc))ruUllToPtr:用于明确指针地址值时,将地址恢复为指针(如从lParam/wParam中解出的句柄值还原成指针);ruLlToPtr:有符号版本,文档标注"极少数情况下使用";ruToHwnd/ruToHdc:是rwBatchMove、rwDefWindowProc、rwIsMainWin等窗口函数的公共底层(src/rgf_core/rgf_utils.cj#L169-L179)。
底层内存工具:ruSafeCStruct / ruRedefBit
这两组工具面向需要直接操作 C 结构体内存的场景。
ruSafeCStruct —— CType 内存的自动创建与释放
public func ruSafeCStruct<T, RT>(count: Int64, callback: (data: CPointer<T>) -> RT) where T <: CType自动创建count个T类型(T <: CType,即 C 兼容结构体)的连续内存,传入回调使用,回调返回后自动LibC.free(src/rgf_core/rgf_utils.cj#L138-L143)。典型场景:构造RECT、MONITORINFO、MSG等 Win32 结构体传给 FFI 时无需手动管理内存。
ruRedefBit —— 比特级数据重解释
public func ruRedefBit<T1, T2>(v: T1): T2 where T1 <: LittleEndianOrder<T1> & CType, T2 <: LittleEndianOrder<T2> & CType从内存比特层面重解释数据值(类似 C++ 的联合体 type-punning)。实现思路(src/rgf_core/rgf_utils.cj#L156-L161):取T1/T2中较大的尺寸分配字节缓冲,v.writeLittleEndian(buffer)写入,再T2.readLittleEndian(buffer)读出,即完成"同一段比特,换个类型解释"。要求两个类型都实现LittleEndianOrder且为CType。可用于在整数/浮点/位域结构之间互转,例如把UInt32重新解释为浮点或位域结构。
全局函数的错误处理与最佳实践
异常机制
RGF_CJ 的全局函数在底层失败时统一抛出WinException(Windows 系统相关异常,见 doc/api/rgf.rgf_core/异常/WinException.md),错误码来自wGetLastError()。触发点包括:
rsCreateSysTimer创建失败;rsDestroySysTimer注销失败;rsGetMonitorFromPoint未找到点所在显示器;rsMain重复初始化(抛普通Exception,文案rgfErrorMainUiThreadinited);- 系统线程创建失败等。
生命周期配对清单
| 成对关系 | 说明 |
|---|---|
rsInitialize↔rsDestroy | 手动自建消息循环时成对使用;rsMain内部已自动处理 |
rsMain(create, destroy) | create 中建资源,destroy 中rwUnregister等 |
rsCreateSysTimer↔rsDestroySysTimer | 创建的定时器都必须销毁 |
ruStrToWStr↔ruFree | 手动转换必须手动释放;或用ruStrToCStr自动释放 |
rwRegister↔rwUnregister | 注册的窗口类都应由rwUnregister注销 |
使用建议
- 入口总是先
rsModRefToCurrDir(),再进rsMain,保证相对路径资源加载稳定(测试工程均如此); - 单纯 UI 动画计时优先用
RTimer,系统级定时任务才用rsCreateSysTimer; - 多窗口同时移动用
rwBatchMove一次提交,避免逐窗移动的闪烁; SysThreadAndAsyn模式下务必用ruFinished()协调主线程与 UI 线程的退出时序,并在main末尾rsEnd(0)兜底结束进程(调试状态下可避免误报)。
总结
rgf.rgf_core的全局函数构成了 RGF_CJ 应用的"地基层":rsMain+RunMode定义应用形态与线程模型,rsInitialize/rsDestroy/rsGetContext管理全局上下文,rsCreateSysTimer/rsDestroySysTimer提供系统定时能力,rsGetMonitorFromPoint服务多显示器布局,rwRegister/rwUnregister/rwBatchMove/rwIsMainWin等封装窗口类与窗口管理,ru*系列则打通仓颉与 Win32 之间的字符串、指针和句柄互操作。结合 test/CT/base/src/main.cj 与 test/HLT/camera/src/main.cj 两个参考工程,你可以快速搭建自己的 RGF_CJ 桌面应用骨架。
- 图形学
- 桌面应用
【免费下载链接】RGF_CJ
RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。
相关推荐
Midway 应用生命周期全解:ILifeCycle 接口、对象生命周期与超时机制实战
Midway 应用生命周期全解:ILifeCycle 接口、对象生命周期与超时机制实战 本篇围绕 Midway( @midwayjs/core )的 应用生命周
后端微服务云原生告别窗口管理痛点:Iced窗口生命周期全解析
告别窗口管理痛点:Iced窗口生命周期全解析 你是否还在为跨平台GUI应用的窗口管理烦恼?从创建窗口到处理用户调整大小,再到优雅关闭,每个环节都可能藏着不易察觉
前端跨平台UI组件桌面应用Apache Beam Python ParDo 变换详解:从 DoFn 生命周期到时间戳与窗口绑定
Apache Beam Python ParDo 变换详解:从 DoFn 生命周期到时间戳与窗口绑定 导读 ParDo 是 Apache Beam 中用于 通用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考