WIN32汇编语言教程:第05章 使用资源 · 5.5 字符串资源/5.6 版本信息资源(1)
程序中用到的字符串常常定义在 .const段中,但Windows也提供了另外一种使用字符串常量的方法,那就是在资源中定义。虽然在资源中定义字符串使用起来比直接在 .const段中定义要复杂一点,但它带来的好处是便于开发不同语言的版本,比如,要推出其他语种的版本只需要修改资源中的字符串表就可以了,即使语言转换的工作是由第三者通过修改可执行文件来做的(如编程爱好者常常做的汉化工作),修改资源也远比修改代码来得快捷和安全。
在资源脚本中定义字符串的语法是:
STRINGTABLE [DISCARDABLE] BEGIN 字符串ID1 "字符串1" 字符串ID2 "字符串2" . . . END
全部字符串组成一个字符串表,和其他资源定义不同,由于整个资源文件中只能定义一个字符串表,所以字符串表没有资源ID,但是表中的不同字符串分别有一个字符串ID。
在程序中使用字符串资源也很简单,用LoadString把字符串装入到缓冲区中去就可以用了:
invoke LoadString,hInstance,字符串ID,addr 缓冲区,sizeof 缓冲区
为了防止溢出,最后一个参数指定缓冲区的长度。
如果要在单个可执行文件中实现多语种,那么可以在字符串表中定义不同语言的字符串。同一语种的字符串按规律排列,如下列中文的以1000开头,英文的以2000开头:
stringtable { 1001 "文件未找到!" 1002 "无法打开文件!" ... 2001 "File not found!" 2002 "Can not open file!" ... }
在程序中使用的时候,先确定一种语言并预先设置在dwLanguage变量中,使用中文时将dwLanguage设置为1000,使用英文时设置为2000,再写一个读取不同版本字符串的子程序_GetString,这样调用_GetString子程序后就不用考虑版本问题了:
_GetString proc _dwID,_lpBuffer,_dwSize pushad mov eax,_dwID add eax,dwLanguage invoke LoadString,hInstance,eax,_lpBuffer,_dwSize popad ret _GetString endp
5.6 版本信息资源
有时应用程序需要确保自己运行时使用某一特定版本的DLL,以便确保可以使用某些函数。检测版本是通过API函数查询定义于资源中的版本信息来完成的,如果资源中没有定义版本,那么就无法知道一个文件的版本究竟是多少。
版本信息是以VERSIONINFO类型的资源保存在应用程序中的,里面可以定义的信息包括文件的版本号、创建单位和语种等。版本信息的定义是可选的,一个程序可以不定义版本信息资源,如果定义了的话,也不一定要定义全部信息项目。
如果一个文件定义有版本信息资源,那么在文件的属性页(在文件图标上按鼠标右键,在弹出的菜单上选择)上就会有一个“版本”页面,如图5.10所示。
图5.10 文件属性中的版本信息
5.6.1 版本信息资源的定义
在所附光盘的Chapter05\VersionInfo目录中有一个例子,在该目录的Version.rc文件中定义了一个版本信息,读者可以看编译后的VersionInfo.exe中的“版本”属性页,对比一下资源定义中的内容究竟出现在属性页的哪些地方,定义的代码如下:
1 VERSIONINFO
FILEVERSION 1,2,3,4 PRODUCTVERSION 2,3,4,5 FILEOS VOS_WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "VarFileInfo" BEGIN VALUE "Translation", Ox804, Ox4b0 END BLOCK "StringFileInfo" BEGIN BLOCK "080404b0" BEGIN VALUE "Comments", "Here is Comments\0" VALUE "CompanyName", "Here is CompanyName\0" VALUE "FileDescription", "Here is FileDescription\0" VALUE "FileVersion", "1, 0, 0, 1\0" VALUE "InternalName", "Here is InternalName\0" VALUE "LegalCopyright", "Here is LegalCopyright\0" VALUE "LegalTrademarks", "Here is LegalTrademarks\0" VALUE "OriginalFilename", "Here is OriginalFilename\0" VALUE "PrivateBuild", "Here is PrivateBuild\0" VALUE "ProductName", "Here is ProductName\0" VALUE "ProductVersion", "1, 0, 0, 1\0" VALUE "SpecialBuild", "Here is SpecialBuild\0" END END END
现在来看这些定义语句的含义。首先,版本信息定义的语句格式是:
版本信息资源ID VERSIONINFO
固定属性
BEGIN 块声明定义 ...... END