admin管理员组

文章数量:1530947

2024年7月23日发(作者:)

18

卷 增刊

1

2007

6

          广西工学院学报           

Vol

1

18

 

Sup1

 

JOURNALOFGUANGXIUNIVERSITYOFTECHNOLOGY

   

June

1

2007

文章编号 

1004

2

6410

(

2007

)

S1

2

0270

2

03

Delphi

开发中的字符串资源动态替换

朱微微

(

柳州市第一职业技术中等专业学校

,

广西柳州 

545007

)

摘 要

:

本文介绍了

Delphi

ResourceString

(

简称资源字符串

)

关键字工作原理

,

运行时动态替换字符串资源

,

以解

决在许多需要多语切换的场合必须定义大量全局变量的方式解决动态切换字符串数据方法。由于全局变量过多且

可读写容易被其它模块撰改没有常量的特性

,

而资源字符串定义的字符串资源是单独存储在

PE

资源节的且是在读

取时才加载并具有常量的特性。

关 键 词

:

资源

;PE

资源节

;

字符串资源

;

动态替换

中图分类号

:TP311

1

11

    文献标识码

:A

0

 引言

国内普通的自由、共享软件和商业软件等因为面向的是国内用户,因此一般都是中文版。国外的软件大

多是英文版,在国内流传时给用户造成了许多不便,因而有热心的程序员开始制作汉化包,用以将程序界面

中的英文字符改成中文。但也有一些软件,发布的时候就自带了多种语言包,运行时可以自动判断用户的

Windows语言种类进而确定界面的语言风格,如网络蚂蚁(NetAnts),它能够在运行的时候由用户来选择中

文或英文,它本身能够在两种不同的语言间进行动态切换,这是所谓“国际版”软件的风格。我们可以通过字

符串资源定义的字符串动态替换来实现运行时改变字符串资源的目的,从而为汉化或多语言化某些软件提

供一种可供选择的方法和途径。

在这里利用Delphi提供的语言特性,资源字符串揭示高级语言在对许多高效编程技巧的封装,尽可能

的利用Win32提供的功能快速高效的解决问题。同时希望读者更加关注通过实践和多解读VCL自带源码

深入理解Win系统特性,体会封装的艺术

[1]

1

 关键词解释

资源———可以说是可执行文件中使用的图像、字串等数据的总称。从原则上来说任何类型的文件都可

以通过资源的方式编译进EXE文件中。编程开发中常用的资源有位图、图标、鼠标光标、字符串等,甚至可

以包括菜单、加速键等。编译后的资源文件(扩展名一般为1res)能在程序编译时通过声明的方式被引入到

可执行文件中。

PE资源节———指的是在PE文件格式中一段存放资源的一段数据结构,可借助类似ResourceHacker之

类的工具查看甚至是修改,对于一些简单软件汉化都是修改或者是替换原程序的资源节达到的。

字符串资源———PE资源节中的字符串数据,一般用于存储提示信息,菜单项名称等。

动态替换———在程序运行时进行资源数据的替换,以达到无需从新编译运行即可改变程序中的某些数

据的目的

(

如程序中/英文界面的切换

)

等。

2

 资源字符串的动态替换

用资源字符串的关键字定义的字符串,将会以字符串资源的形式被链接到可执行文件或者动态链接库

收稿日期

:2007

2

04

2

20

作者简介

:

朱微微

(

1965

2

)

,

,

江苏南通市人

,

广西柳州市第一职业技术学校计算机高级教师。

增刊

1

             朱微微

:Delphi

开发中的字符串资源动态替换

271

中,同等于使用装载函数加载指定模块中的字符串资源一样,不同的是Delphi对其的使用进行了封装使得

可像常量一样方便的使用字符串资源。

本文介绍的是如果在不改变原定义的情况下使其可链接到其它模块的字符串资源上。其实现意思是在

程序多语言化时动态切换其资源串资源,并不影响程序逻辑和代码结构。

211 资源字符串结构

TResStringRec———资源字符串结构,它定位了资源字符串在模块

[1]

中的位置。

PResStringRec———资源字符串指针,它是指向一个资源结构的指针。

资源字符串结构的定义在System1pas单元中,定义如下:

type

  PResStringRec=^TResStringRec;

  TResStringRec=packedrecord

  Module:^Cardinal;//模块实例句柄

  Identifier:Integer;//字符串资源编号

end;

资源结构的Module(简称资源句柄)为什么被定义为一个Cardinal的指针类型呢?因为在同一模块中

所有实例引用的资源句柄都是一样的,既节约了存储空间,又方便统一修改。让它们同时指向同一资源句

柄,这样只要修改了一个资源句柄,那么所有模块中引用了该资源所有实现便会同时改变

(

可参考Program

FilesBorlandDelphi7DemosRichEdit的实现

)

。Identifier

(

简称资源标识符

)

域则是编译器为资源字

符串分配的一个整型编号作为资源标识符,在同一模块中每一个资源项的标识符都是唯一的

[2]

212 动态替换原理

只要利用资源字符串指针改变资源字符串的资源句柄和资源标识符即可实现改变资源字符串的内容。

但以resourcestring关键字定义的资源字符串,编译器为了保证程序结构一致性与严谨性使得资源字符串的

存在就像常量一样,在程序运行时是不允许被修改的。所以在改变资源字符串的资源句柄与资源标识符之

前,必须先将资源字符串变为可读写状态。虽然resourcestring定义的资源字符串结构是只读的,但由于在

程序运行时对自己所属的内存空间内有完全的读写权限,而且资源字符串结构肯定是在进程中分配的内存

空间,仅是由于编译器为了实现数据一致性和安全性对该区域的内存进行的读取限制。在Windows操作系

统中提供了VirtualProtect函数来改变自己提供的内存页面的保护属性,所以只要通过APIVirtualProtect

先将资源字符串结构的内存地址的访问属性置为可读写的,再时行修改资源字符串结构的内容,在修改完成

后再重新置回只读状态即可

[3]

样例关键代码如下:

resourcestring

 csChineseVer=’我的软件

(

中文版

)

’;

 csEnglishVer=’MySoftware(EnglishVer)’;

procedureTfrmTest1btnSwitchClick

(

Sender:TObject

)

;

var

 OldProtect:DWORD;

 tmpRes:TResStringRec;

begin

 

//

通过

VirtualProtect

修改指定数据所在区域的内存属性为可读写

 //该区域原来的属性保存在OldProtect中

 VirtualProtect

(

@csChineseVer,SizeOf

(

PResStringRec

)

,PAGE

-

EXECUTE

-

READWRITE,@OldPro2

tect

)

;

 tmpRes:=PResStringRec

(

@csChineseVer

)

^;//交换资源字符串结构的值

 PResStringRec(@csChineseVer)^:=PResStringRec(@csEnglishVer)^;

272

广西工学院学报                    第

18

 PResStringRec(@csEnglishVer)^:=tmpRes;

 //恢复原内存区域内的属性

 VirtualProtect

(

@csChineseVer,SizeOf

(

PResStringRec

)

,OldProtect,@OldProtect

)

;

 Self1Caption:=csChineseVer;//刷新标题

 lblVerTitle1Caption:=csChineseVer;//刷新提示信息

end;

成功运行时会将资源字符串csChineseVer、csEnglishVer的值相互交换。使程序达到只引用一个固定的

csChineseVer标识符就可以在两种语种的提示信息之间进行切换而无需修改源程序的效果。

运行效果如图1所示。

测试程序运行后,显示的标题为中文字符串,点击“切换”按钮后,标题如图2所示变为英文字符串。

1

 运行效果图图

2

 切换后效果图

3

 结束语

通过该技巧可动态的将原代码中的字符串资源全部替换而不影响其它代码,替换时只需要新建个管理

类然后将需要替换的单元引用

(

uses

)

进来即可,无论该资源串是放在同一执行文件中还是别的动态链接库

中都没有关系,读者可根据项目需要处理。

参 考 文 献:

[1]

李 维1

VCL

架构剖析

[M]

1北京

:

电子工业出版社

,2004

1

[2]SteveTeixeira,XavierPacheco

1

Delphi6

开发人员指南

[M]

1龙劲松

,

王瑜

,

谢尚书

,

译1北京

:

机械工业社

,2002

1

[3]

周爱民1

Delphi

源代码分析

[M]

1北京

:

电子工业出版社

,2004

1

(

责任编辑 赖君荣

)

本文标签: 资源字符串替换动态结构