☰
RGF 图标类型枚举 EmIcon 详解:Big / Small / Small2 与 Win32 窗口图标消息的映射
2026/10/14 3:16:55 网站建设 项目流程
  • 图形学
  • 桌面应用

【免费下载链接】RGF_CJ

RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。

项目地址:https://gitcode.com/Cangjie-SIG/RGF_CJ
点击查看免费下载

导读:本文围绕 RGF(仓颉 Windows 通用渲染框架)核心包rgf.rgf_core中的图标类型枚举EmIcon展开,完整讲解其三个成员(Big、Small、Small2)、与 Win32WM_GETICON/WM_SETICON消息数值(ICON_BIG/ICON_SMALL/ICON_SMALL2)的映射机制、内置的相等比较运算符与e2Num/num2e双向转换函数,并结合Icon类与窗口图标事件参数类给出可直接运行的实战用法。读完本文,你将能够理解并独立处理 RGF 窗口图标设置与获取场景中的类型判定与数值转换问题。

一、枚举定义与成员

EmIcon定义于 doc/api/rgf.rgf_core/枚举/EmIcon.md,是 RGF 核心包rgf.rgf_core中用于描述"图标类型"的公开枚举:

public enum EmIcon

其枚举成员及语义如下:

成员说明
Big大图标,对应 Win32 窗口标题栏 / 任务栏切换(Alt+Tab)时使用的大尺寸图标
Small2小图标(第二种),对应 Win32 中的ICON_SMALL2类型,即当前 DPI 下的小图标
Small小图标,对应 Win32 中默认的小尺寸图标(如窗口标题栏左上角图标)

在源码 src/rgf_core/rgf_proc.cj 中,枚举的声明与成员如下:

/** @brief 图标类型 */ public enum EmIcon{ | Big | Small | Small2 ... }

需要说明的是:API 文档中成员的展示顺序为Big、Small2、Small,而源码声明顺序为Big、Small、Small2;由于该枚举通过e2Num显式映射数值(而非依赖声明顺序),因此成员顺序差异不影响任何行为。

二、与 Win32 图标类型的数值映射:e2Num / num2e

EmIcon的核心价值在于它与 Win32 窗口消息中图标类型参数的严格对应。源码提供了两个const static转换函数(src/rgf_core/rgf_proc.cj):

public const static func e2Num(tk:EmIcon):UInt8{ return match (tk) { case Big => 1 case Small => 0 case Small2 => 2 } } public const static func num2e(num:UInt8):EmIcon{ return match (num) { case 1 => Big case 2 => Small2 case _ => Small } }

e2Num:枚举 → UInt8

e2Num(tk: EmIcon): UInt8将枚举值转换为对应的数值,映射关系与 Win32 的图标类型常量完全一致:

EmIcon成员数值对应 Win32 常量
Big1ICON_BIG
Small0ICON_SMALL
Small22ICON_SMALL2

这一映射与rgf_icon子包中实际发送窗口消息时的用法互相印证:在 src/rgf_icon/rgf_icon.cj 中,Icon.setWinIcon向窗口发送WM_SETICON消息时,wParam分别传入1/*ICON_BIG*/与0/*ICON_SMALL*/:

// 设置大图标 wSendMessageW(hwnd, 0x0080/*WM_SETICON*/, UInt64(1/*ICON_BIG*/), ...); // 设置小图标 wSendMessageW(hwnd, 0x0080/*WM_SETICON*/, UInt64(0/*ICON_SMALL*/), ...);

num2e:UInt8 → 枚举

num2e(num: UInt8): EmIcon是反向转换函数,用于把消息参数还原为枚举类型。注意其case _ => Small的兜底分支:任何非1、非2的数值(尤其是0)都会解析为Small。这意味着:

  • 数值0→Small
  • 数值1→Big
  • 数值2→Small2
  • 其他数值 → 一律视为Small(安全兜底)

从源码结构可以推断,兜底为Small的设计保证了即使收到未知数值,事件参数类也能得到一个合法、稳定的枚举值,不会出现未定义行为。

三、比较运算符:== 与 !=

EmIcon重载了运算符==与!=,其实现基于e2Num的数值比较(src/rgf_core/rgf_proc.cj):

public operator func ==(right:EmIcon):Bool{ return e2Num(this) == e2Num(right); } public operator func !=(right:EmIcon):Bool{ return e2Num(this) != e2Num(right); }

API 文档 doc/api/rgf.rgf_core/枚举/EmIcon.md 中对应的签名声明为:

public operator func ==(right: EmIcon): Bool public operator func !=(right: EmIcon): Bool

由于比较建立在数值映射之上,语义与 Win32 侧的类型常量判等完全一致。典型的判定写法:

// 判断事件请求的图标类型是否为大图标 if (ev.iconType == EmIcon.Big) { // 响应大图标请求 }

四、在窗口图标事件中的实际应用

EmIcon最主要的消费方是rgf_core中两个窗口消息事件参数类:EvGetIcon与EvSetIcon,二者均定义于 src/rgf_core/rgf_proc.cj。

EvGetIcon:WM_GETICON(获取图标)

/** @brief 获取图标 - 事件参数 */ public open class EvGetIcon <: EvCore{ // 请求的icon类型 public let iconType:EmIcon // 请求的dpi public let dpi:UInt32 @OverflowWrapping public init(wParam:UInt64, lParam:Int64) { super(0x007F /*WM_GETICON*/, wParam,lParam) iconType = EmIcon.num2e(UInt8(wParam)) dpi = UInt32(lParam) } }

对应 API 文档见 doc/api/rgf.rgf_core/类/EvGetIcon.md。在WM_GETICON(0x007F)消息到来时,构造器通过EmIcon.num2e(UInt8(wParam))将消息的wParam转换为EmIcon类型,存入iconType字段;lParam中的 DPI 值则存入dpi字段。由于WM_GETICON可能以ICON_BIG、ICON_SMALL或ICON_SMALL2三种类型发起请求,因此EvGetIcon.iconType理论上三种成员都可能出现。

EvSetIcon:WM_SETICON(设置图标)

/** @brief 设置图标 - 事件参数 */ public open class EvSetIcon <: EvCore{ // 请求的icon类型(值只会为 Big 或 Small) public let iconType:EmIcon // 请求图标句柄,有可能为空 public let handle:CPointer<Unit> @OverflowWrapping public init(wParam:UInt64, lParam:Int64) { super(0x0080 /*WM_SETICON*/, wParam,lParam) iconType = EmIcon.num2e(UInt8(wParam)) handle = ruUllToPtr(ruInt64SafeToUIntNative(lParam)) } }

对应 API 文档见 doc/api/rgf.rgf_core/类/EvSetIcon.md。EvSetIcon处理WM_SETICON(0x0080)消息,同样通过num2e解析wParam,并通过ruUllToPtr将lParam中的图标句柄转换为CPointer<Unit>存入handle。

重要限制:源码注释与 API 文档均明确指出,在WM_SETICON场景下iconType的值只会是Big或Small(即 Win32 只会用ICON_BIG、ICON_SMALL来发送设置图标消息),不会出现Small2。这与setWinIcon的实现行为一致——它只发送1/*ICON_BIG*/和0/*ICON_SMALL*/两种参数。因此处理EvSetIcon事件时,只需针对Big与Small两个分支进行判定即可。

五、实战组合:Icon 类加载并设置窗口图标

EmIcon描述的是消息层面的图标类型,而rgf.rgf_icon子包中的Icon类负责实际的图标加载与设置(doc/course/018_图标光标管理.md 有完整教程)。典型流程如下:

  1. 引入子包:
import rgf.rgf_icon.*
  1. 从.ico文件加载图标:
let icon:Icon = Icon() icon = Icon("./img.ico"/* ico文件路径 */, IconType.Icon/* 图标资源类型 */)
  1. 设置到窗口(内部即发送WM_SETICON消息,wParam为1/*ICON_BIG*/与0/*ICON_SMALL*/,见 src/rgf_icon/rgf_icon.cj):
// 将icon设置为窗口的小图标(同时设置大图标与小图标) icon.setWinIcon(hwnd)

setWinIcon支持多种窗口对象入参:RgfHwnd句柄、WinPure窗口类以及IWinMethod窗口接口(src/rgf_icon/rgf_icon.cj),并会先通过isValid()与类型检查确保句柄有效且类型为Icon。

注意事项(来自 doc/course/018_图标光标管理.md):在窗口关闭之前不要调用icon.release(),否则已设置的图标会失效。

六、使用建议与注意事项小结

  • 判定图标类型时优先使用枚举比较:在EvGetIcon/EvSetIcon事件回调中,直接比较iconType与EmIcon.Big/EmIcon.Small即可,无需关心底层数值,==/!=运算符已封装好比较逻辑。
  • 注意Small2的出现范围:Small2主要在WM_GETICON请求中出现(对应 Win32 的ICON_SMALL2,用于 DPI 感知场景下的小图标);WM_SETICON设置消息中只会出现Big或Small。
  • 反向转换有兜底:num2e对未知数值统一归为Small,处理外部输入时安全无异常;若需精确区分原始数值,可先用UInt8(wParam)直接判断。
  • 数值一致性:e2Num输出的1 / 0 / 2与 Win32ICON_BIG、ICON_SMALL、ICON_SMALL2常量完全对齐,因此需要直接调用底层wSendMessageW时,可放心用e2Num的结果作为wParam。

综上,EmIcon是 RGF 窗口图标体系中连接高层事件对象与 Win32 消息参数的"类型枢纽":一方面通过e2Num/num2e实现枚举与数值的双向转换,另一方面通过重载运算符提供类型安全的比较能力,再配合EvGetIcon、EvSetIcon事件参数类与Icon.setWinIcon,即可完整覆盖窗口大图标、小图标的获取与设置场景。

  • 图形学
  • 桌面应用

【免费下载链接】RGF_CJ

RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C++版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能力以及常用的桌面应用开发工具,并且提供对接Direct3D的相关接口,以满足开发者对3D画面渲染的需求。在Windows开发方面,RGF在子包内也提供开箱即用的Windows API,确保熟悉Win32的开发者快速上手。此外,RGF还提供一些常用功能的封装(如XAudio2、MF),以辅助开发者实现音频、摄像头等扩展功能的管理。

项目地址:https://gitcode.com/Cangjie-SIG/RGF_CJ
点击查看免费下载
上一篇:和AI进行一场真实感模拟面试:interview-guide Skill驱动出题与智能追问功能实战指南
下一篇:linkedin-skills创始人特供版:10个创始人内容角度,赢得投资人与顶尖人才的信任

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询