Delphi ResourceString的用法

在Delphi编程的那段“古老”的日子里(就是在版本4之前),在程序中使用字符串有两个基本的方法。你可以使用字符串将它们嵌入到源程序中,例如:

MessageDlg( 'Leave your stinkin' mitts off that button, fool!',mtError, [mbOK], 0);

或者,你可以创建一个文本文件(使用.rc扩展名),例如:

STRINGTABLE DISCARDABLE

{

1 "Dialog Expert"

2 "Dialog Expert from demonstration Expert DLL."

3 "Application Expert"

4 "Application Expert from demonstration Expert DLL"

5 "&Create"

6 "&Next"

7 "An application name is required!"

8 "The application name is not a valid identifier."

9 "The path entered does not exist."

10 MAIN.PAS"

11 "MAIN.DFM"

12 "MAIN.TXT"

...

// Variable names.

20 "StatusLine"

...

}

然后你需要做的工作是将它编译成为资源文件,加入到Delphi的工程或者单元中,使用命令行工具Brcc32.exe编译,然后在程序中当你使用到这些字符串时,使用LoadStr等函数将它们从资源中提取出来。这看起来有点麻烦,而且你可能会被困在这麻烦的操作中,因此你可能会无休止地将字符串加入到你的源代码中而不是使用资源。

现在,resourcestring关键字的出现,可以帮助你摆脱这麻烦的工作。resourcestring带给我们两个好处:可以简单地加入字符串,而且所有的字符串集中保存在同一个位置;同时,使用resourcestring提供更好的内存管理,因为所有在resourcestring部分的字符串是以资源形式保存在应用程序中。

让我们赶快进入使用resourcestring关键字的新世界,增加一个单元到你的工程中,名字是ResStrngs(或者其它名字),然后将所有的字符串(特别是那些将会被用户看到的字符串:列表的内容,错误消息等等)加入到这个单元的接口(Interface)部分,就像下面一样:

unit ResStrngs;

interface

resourcestring

// 著名的军事家

SGeneralElectric = 'General Electric';

SGeneralMills = 'General Mills';

SGeneralUsage = 'General Usage';

SGeneralHospital = 'General Hospital';

SGeneralLedger = 'General Ledger';

SGeneralProtectionFault = 'General Protection Fault';

SGeneralSQLError = 'General SQL Error';

SGeneralLeeSpeaking = 'General Lee Speaking';

SCorporalPunishment = 'Corporal Punishment';

SSgtFury = 'Sgt. Fury';

SSgtCarter = 'Sgt. Carter';

SSgtSchultz = 'Sgt. Schultz';

SSargentShriver = 'Sargent Shriver';

SCaptKangaroo = 'Capt. Kangaroo';

SCaptUnderpants = 'Capt. Underpants';

SColonelKlink = 'Colonel Klink';

SPrivateBenjamin = 'Private Benjamin';

SPrivateProperty = 'Private Property';

SLeftenantDan = 'Leftenant Dan';

SMutineerChristian = 'Mutineer Christian';

SAtlantaHawks = 'Atlanta Hawks';

// 友好的提示

SDontSleepInTheSubwayDarlin =

'Don't sleep in the subway darlin'';

// 你还可以继续增加字符串

implementation

end.

在任何可能引用这些字符串的单元的实现(implementation)部分的uses语句中加入此单元。然后,你可以这样使用这些字符串:

if ItIsPetulasVirtualHusband and HeIsLate then

MessageDlg(SDontSleepInTheSubwayDarlin,

mtInformation, [mbOK], 0);

还有一个例子:Borland/Inprise同样使用字符串资源,你可以看看..\source\vcl目录下的consts.pas、dbconsts.pas等文件。

将字符串集中放在resourcestring部分还有一个好处就是,通常程序员并不是最适合写用户将会看到的反馈信息或者错误消息的人,他们写的往往太技术性,例如:“模块xyz:生成子线程时发生一个未预期错误”,这对用户来说等于没说,也许“请在开始前保存修改”会更好一些。

将这些消息字符串单独保存在一个分离的文件中,可以让那些适合编写用户消息的人来处理(当然,要有程序员来当顾问,以便确定每条消息表示什么含义)。如果你不想让这些非编程人员来修改你的.pas文件,你可以将这些字符串保存到一个文件文件中交给他们处理,当他们处理完成后,你再将他们修改后的字符串复制到你的resourcestring部分。

最后但是也非常重要的是,当把用户或以看到的字符串都收集在一个地方,可以让你很容易地让你的应用程序国际化和本地化。使用Delphi的ITE(Integrated Translation Environment 集成翻译环境),国际化和本地化你的应用程序的字符串几乎是半自动完成的。使用ITE,你可以为每种语言创建一个独立的.dll。如果你发布时带有多个.dll文件,通过程序运行的计算机系统的地区号,你的程序可以自动调用对应的.dll。

ITE主要的工具就是资源DLL向导(Resource DLL Wizard) (File | New | Resource DLL Wizard) 和翻译管理器(Translation Manager)。翻译管理器用于输入翻译的内容,可以查看Delphi的帮助文件的"Integrated Translation Environment"部分获得具体信息。

除Delphin提供的ITE外,还有第三方的相关工具。我喜欢使用来自 "in the box." 的工具,当然,像ITE一样,只要他工作得好。