Win32 二进制资源格式(续二)

本文介绍了Windows资源编译器的工作原理,包括如何通过资源描述文件创建资源表,以及资源文件在可执行文件中的作用。文章还详细解释了几种新添加的语句,如AUTO3STATE、AUTOCHECKBOX等,并探讨了如何使用EXSTYLE和CHARACTERISTICS等语句来增强应用程序的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 2.一般信息

资源编译器通过分析资源描述文件(.rc)、包含任何其它的资源数据文件(如.ICO图标,.CUR光标,.BMP位图,.FNT字体文件等)来创建资源文件。资源文件包含了在可执行文件中创建资源表的所有必须的信息。资源文件的主要目的是为了加速“编辑-编译-链接”循环,因为它使得资源不必被重新编译。

当前存在大约十几种预定义资源类型。包括菜单、对话框、加速键、字符串、图标、光标、位图、字体和版本信息。Windows系统使用这些资源定义应用程序窗口的显示。资源脚本使得程序编制者可以以一种简易的可编辑形式来表现这些特性。其它类型被保留作应用程序自定义的数据所使用。资源编译器不会尝试修改这些用户自定义的数据(比如将16位数据转换为32位数据)。

Windows 32可执行文件并不是一个分段的映像。在16位可执行文件中,每个资源都被单独放在一个段内。Windows 32可执行文件将所有资源统一放在一个对象或区域中。Windows 32可执行文件同时提供一个二进制排序的资源表以允许快速查询一个特定的资源,而不是像16位可执行文件那样只提供一个仅可进行线性查询的表。正因如此,Windows 32可执行文件更加复杂,很难直接对其进行更新,因此Windows 32 API提供了一些函数用来直接修改资源数据。

能够将资源文件转换为一个COFF对象的CVTRES转换工具会创建一个资源表。这个表包含三个目录,以类型、名称、语言为索引顺序。类型和名称目录均由两部分组成:一部分是类型或名称的字符串标识,另一部分是它们的单字值标识。由于类型或名称的字符串标识会比单字值标识占用更多的空间,因此微软并不推荐使用。

应当注意的是,由于资源文件里的所有字符串(包括类型和名称的标识字符串)都是UNICODE字符,因此用户程序中的LoadBitmap等函数都必须传入相应的UNICODE字符串作为参数(仅当程序使用UNICODE版本的API集合而不是ASCII版本的API集合时)。可以使用定义在winnt.h文件中的TEXT宏修饰字符串来自动达到此目的。

第三个目录,语言,使程序开发者可以在一个单独的可执行文件中提供多语言支持。例如,一个映像文件可以很容易地同时支持法语、加拿大法语以及比利时法语三种语言的资源。理论上一个应用程序可以同时支持UNICODE标准所支持的所有语言,虽然最终的可执行文件可能会大得难以承受。不过,由于系统提供了可以修改映像内资源的工具,因此应用程序的安装程序可以为每个用户自定义程序的映像文件,从而删掉不需要的语言以节省空间,减小最终的映像文件的大小。

2.1 新语句

Windows 32资源编译器可以处理几个新添加的语句。

2.1.1 新按钮语句

这几个语句允许程序员自由使用,就像PUSHBUTTON、DEFAULTPUSHBUTTON等语句一样。

它们的语法与PUSHBUTTON等相同。

2.1.1.1 AUTO3STATE

允许声明一个AUTO3STATE按钮。

2.1.1.2 AUTOCHECKBOX

允许声明一个AUTOCHECKBOX按钮。

2.1.1.3 AUTORADIOBUTTON

允许声明一个AUTORADIOBUTTON按钮。

2.1.1.5 PUSHBOX

允许声明一个PUSHBOX按钮。

2.1.1.6 STATE3

允许声明一个3STATE按钮(由于语法而将3放在了后面)。

2.1.1.7 USERBUTTON

允许声明一个USERBUTTON用户定义的按钮。

2.1.2 EXSTYLE语句

这个语句允许程序员指名一个对话框或控件窗口的扩展样式(WS_EX_xxx)。有三种声明方法,取决于需要什么。

它可以被直接放在DIALOG语句下面(像CAPTION和STYLE语句一样),以应用于对话框窗口。

    EXSTYLE <flags>

它可以与内存标志一起被放在DIALOG语句中。

    FOOBAR DIALOG [MemFlags...] [EXSTYLE=<flags>] x, y, dx, dy
    
它也可以被单独放在CONTROL、PUSHBUTTON、LTEXT等语句的结尾部分。

    AUTOCHECHBOX "autocheckbox", id, x, y, dx, dy
    [styleflags] [exstyleflags]

2.1.3 CHARACTERISTICS语句

这个语句允许程序员指定可能被(第三方)资源文件读写工具使用的资源信息。它对系统没有任何意义,而且也不会存储在映像文件中。

    CHARACTERISTICS <用户定义的DWORD值>

2.1.4 VERSION语句

这个语句使程序可以在资源文件中指定资源的版本号(供读写资源文件的工具使用)。它对系统没有任何意义,而且也不会存储在映像文件中。

    VERSION <用户定义的DWORD值>

2.1.5 LANGUAGE语句

LANGUAGE语句用来指定资源或资源的一段所使用的语言。它可以被放在资源脚本文件中一个单行语句(比如ICON、CURSOR、BITMAP语句)所能放置到的任何地方。它的作用域从它定义的位置开始,直到下一个LANGUAGE语句,或者文件尾。

    LANGUAGE <主数字>, <次数字>

其中<主数字>表示语言ID,<次数字>表示字语言ID。应当使用在winnt.h文件中定义的值。

LANGUAGE语句也可能连同其它可选语句(如CAPTION、STYLE等)被放在MENU、DIALOG、STRINGTABLE、ACCELERATOR和RCDATA资源的BEGIN语句之前,此时它的作用域仅限于此资源。

2.1.6 MESSAGETABLE语句

MESSAGETABLE语句被用来包含一个消息表。消息表是一个有特殊意义的字符串表,通常包含一些错误消息或信息,而且可能含有格式字符串信息(如“/n”、“/t”等),它的格式是:

    <nameid> MESSAGETABLE <filename>

2.1.7 UNICODE字符串的附加语法

在资源脚本中,使用双引号括起来的字符串都被看作是ASCII字符串(在当前代码页),除非使用"L"或"l"字符前缀,例如:
    L"这是一个Unicode字符串"
使用这种语法定义UNICODE字符串有两个效果。在RCDATA语句中,它会使编译器将字符串存储为UNICODE而不是ASCII。在任何情况下,使用这种语法,嵌入的不可见字符将被翻译为UNICODE代码点——一个16位UNICODE字符,例如:
    L"这是第一行,/x2028这是第二行"
其中0x2028 UNICODE字符是分行符(Line Separator)。任何UNICODE字符都可以被以此种方式嵌入到任何资源脚本字符串中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值