资源文件与多国语言(200分)

  • 主题发起人 主题发起人 dependmyself
  • 开始时间 开始时间
D

dependmyself

Unregistered / Unconfirmed
GUEST, unregistred user!
我想利用资源文件制作多国语言的软件,我看过在Delphi demo/Rich Edit 里面有类似的功能
可是小弟不才,看不太懂,要是哪位仁兄能帮我解释一下的话,小弟感激不尽。

1、它里面用的资源是窗体,要怎么把Delphi做好的界面做成资源呢?
2、解释一下里面的代码,分数可以加,或有其它要求,只要小弟只做的也行

期待……
 
Delphi的菜单里面就有Add Language...的,你看看怎么用吧。
 
你好,我网站上有利用资源文件做多国语言的程序,你可以下载。里面有详细的说明。
地址:http://wolfsoft.nugoo.com/srcdetail.asp?flag=2&id=92
 
to:shenloqi,飘摇客
在两位的指导下制作窗体资源文件的问题已经解决,不知谁可以解释一以下这段代码?
帮我加加注释就行了:),以下这段代码是在由飘摇客提供的地址里下载的,由tao zhiyu
写的。先谢谢过

{
Title : MutilLanguage
Author : Taozhiyu
Email : taozhiyu@21cn.com
Homepage : http://www.angelfire.com/super/taozhiyu
}

unit MutilLanguage;

interface

uses
Registry, Forms, SysUtils, Windows, reinit;


function SwichLanguage(AForm : TForm ; Language : string) : boolean;
function ReadStr(StringID : integer) : string;

implementation

{$R Mystr.RES}

const
ENGLISH = (SUBLANG_ENGLISH_UK shl 10) or LANG_ENGLISH;
CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;

CurrentEnglish = 10;
CurrentChinese = 20;


function WriteRegistry(Name,Value:string):boolean;
var
RegisterTemp : TRegistry;
begin
result := false;
RegisterTemp := TRegistry.Create;
with RegisterTemp do
begin
try
RootKey:=HKEY_CURRENT_USER;
if OpenKey('Software/Borland/Locales',true) then
begin
WriteString(Name,Value);
result := true;
end;
CloseKey;
finally
Free;
end;
end;
end;

function ReadRegistry(Name : String): string;
var
RegisterTemp : TRegistry;
begin
result := '';
RegisterTemp := TRegistry.Create;
with RegisterTemp do
begin
try
RootKey:=HKEY_CURRENT_USER;
if OpenKey('Software/Borland/Locales',true) then
result:= ReadString(Name);
CloseKey;
finally
Free;
end;
end
end;

function CheckCurrentLanguage : integer;
begin
result := 0;
if ReadRegistry(Application.ExeName) = 'ENG' then
result := CurrentEnglish
else
result := CurrentChinese;
end;

function ReadStr(StringID : integer) : string;
var
txtCaption : array[0..255] of char;
begin
result := '';
StringID := StringID + CheckCurrentLanguage;
if LoadString(HInstance, StringID , txtCaption,SizeOf(txtCaption))>0 then
result:=StrPas(txtCaption);
end;

function RefreshFormFace(AForm : TForm ; Language : string) : boolean;
var
LoadSuccess : integer;
FormRect:TRect;
begin
result := false;
LoadSuccess := 0;
FormRect:=AForm.BoundsRect;
if Language = 'CHN' then LoadSuccess := LoadNewResourceModule(CHINESE);
if Language = 'ENG' then LoadSuccess := LoadNewResourceModule(ENGLISH);
if LoadSuccess <> 0 then
begin
LockWindowUpdate(AForm.Handle);
ReinitializeForms;
AForm.SetBounds(FormRect.Left,FormRect.Top,FormRect.Right-FormRect.Left,FormRect.Bottom-FormRect.Top);
LockWindowUpdate(0);
end;
result := true;
end;

function SwichLanguage(AForm : TForm ; Language : string) : boolean;
begin
result := false;
WriteRegistry(Application.ExeName , Language);
RefreshFormFace(AForm , Language);
result := true;
end;

end.
 
我一直就用这个,很好用。。:)

大多数严肃的的程序员需要建立多语言程序至少有三条理由:

你想要建立专业的、将流行全世界的软件。
你的顾客在外国,与你的母语不同。
你的国家有两种或更多的官方语言。

用Delphi建立多语言程序也至少有三种方法:

你可以用Delphi的Resource DLL Wizard(如果你有Delphi 4或更高版本)。
你可以设计你自己的技术并实现它。
你可以利用第三方组件。

使用Delphi的Resource DLL Wizard有许多好处也有许多坏处。因此,每一个开发者都要自己决定是否利用 Delphi的这一特性。Delphi在线帮助中有许多关于Resource DLL Wizard的文档。所以我们只讨论另两种方法。

在你开发你自己的多语言程序技术以前,你必须分析两个方面:

你将花费多少时间来实现它?
它将满足你所有的要求吗?

当然,有些公司严格规定只能使用自己开发的程序,不能用第三方的代码和工具。但你会承认这样你的公司生产软件总会比其他公司慢一步。

Delphi的面向组件的环境允许你在自己的程序中使用现成的第三方组件,不需要花费大量时间开发你自己的。在我看来,当你要创造新东西前,你应确定一下世界上是否有相同功能的组件。当你发现有能满足你要求的东西后,你或你的经理应当分析一下怎样做对你的公司更有利:

把时间花费在建立相同的组件而停止开发主要的程序,而你的组件是现成有的。
去买现成的组件,继续开发主要的程序,它是你开发的重要目的。

如果你决定使用自己的技术来开发多语言程序,那你就不要继续读这篇文章了。因为我不能给你什么想法。我不明白你是怎么想的。

现在我就描述如何用TsiLang组件包来开发多语言程序。它可以从http://www.sicomponents.com/tsilang1.html下载。写这篇文章时最新的版本是4.9。

要利用TsiLang组件包你首先要将它安装到Delphi IDE中。如果你使用安装程序并且你有Delphi 3或以上版本,它已在Delphi IDE中安装好了。否则你可以阅读"INSTALL.TXT" 来指导你安装。

我们将用已包含在Delphi标准版中的Richedit例子来演示TsiLang组件包的几个特征。让我们用16步来建立多语言程序:

在Delphi中打开RICHEDIT.DPR工程。

从Delphi菜单中选择"Tools|TsiLang Expert",打开TsiLang Expert。 这时会出现TsiLang Expert窗口,其中有工程窗体的列表。

窗体列表中选择主窗体(MainForm), 你将看到停用的按钮现在激活来。点击标题为"0"(它指示选定窗体的语言数)的按钮,在出现的编辑框中填写你所需要的选定窗体的语言数,例如2,你将得到双语程序。

在窗体列表中双击MainForm,将出现TsiLang Captions Editor(标题编辑器),你可以输入组件"Caption"属性的第二种语言的翻译值。

输入第二种语言的翻译值。我们将德语作为第二语言,而将英语作为重要语言。

点击Expert上的工具条,用同样的方法翻译所有其他的属性。

对第二个窗体重复这些动作。

现在我们翻译原文件中的所有字符常量。选择MainForm并在Expert的菜单中选择 "File|Source|With form…",你将看到你的单元的原文件中出现的所有字符常量。

你可以从这一列表中删去你不想是多语言的任意常量:选择常量的所在行并点击"Delete" 按钮。正如你将看到的,第一列常量的字符串ID,相等的变量这个ID是一样的;第二列显示字符常量值;第三列显示替代文本,你可以任意修改;第四列显示常量在源文件中出现的行号。所有的字符串常量分别调用TsiLang组件的GetText()被替换。这一方法根据字符串ID和当前界面的语言返回字符串。在我们的例子中,我们将删除IDS_0、 IDS_2 和IDS_3 这几行,然后点击"Replace"按钮。

这以后,所有放置在窗体TsiLang组件的"Strings"属性的字符常量和你的源代码中的字符串,将被分别调用TsiLang的GetText()方法而替换。这样只要双击TsiLang组件的"Strings"属性打开TsiLang Strings Editor,就可以输入字符串的翻译。

为了建立真正的双语工程,需要将TSaveDialog, TOpenDialog, TFontDialog和TPrintDialog组件替换为"SiDialogs"面板页中的TsiSaveDialog, TsiOpenDialog, TsiFontDialog和TsiPrintDialog组件。设置"siLang"属性使它们与TsiLang链接。在Object Inspector中双击TsiLang组件的"DlgsCaptions"属性打开TsiLang Strings Editor,输入普通对话框字符串的翻译。

现在,将TsiLangDispatcher(它可以在组件面板的"SiComponents"页中找到)加入MainForm。设置NumOfLanguages属性为2并在LangNames属性中输入语言名字(英语和德语)。

选择窗体中的TsiLang组件并设置LangDispatcher属性。你可以看到TsiLang的LangNames属性随TsiLangDispatcher的同一属性变化。TsiLangDispatcher协助管理语言切换过程,当你改变了它的ActiveLanguage属性,所有与之相链接的TsiLang属性跟着改变。

激活工程的第二个窗体(AboutBox),在Reabout的uses子句中添加REMain。选择AboutBox的TsiLang组件并设置其LangDispatcher属性为主窗体的TsiLangDispatcher组件。

现在是最后也是最简单的一步:加入语言切换的实现。下面是一个例子:

在主窗体的主菜单中加入一"Language"的一级菜单,在其中加入"English"和"German"两个菜单项,设置它们的"RadioItem"属性为TRUE。设置"English"的"Tag"属性为"1","German"的为"2"。

选择两个菜单项并添加其OnClick事件处理函数,注意两项设置同一个事件处理函数。此函数代码为:

procedure TMainForm.German1Click(Sender: TObject);
begin
siLangDispatcher1.ActiveLanguage := TComponent(Sender).Tag;
TMenuItem(Sender).Checked := True;
end;

编译工程并执行,选择你的工程是双语的了。

按照上面方法你可以在一个可执行文件中包含多语言支持。你不需要附加文件、数据库之类的东西。但是你可以用TsiLangRT或是TsiLangRTSE来替代TsiLang,生成较小的多语言程序。这些组件允许使用存储多语言翻译的外部文件。TsiLangRT还有内置的编辑器,允许用户自己为程序修改和添加新的语言,不需要你的帮助。TsiLangRTSE为SIL Editor程序提供COM接口。由于SIL Editor程序是自由软件,你可以把它们随你的程序提供给用户,使他们方便的编辑SIL文件。

你还可以将翻译保存在附带的Dictionary Manager中,以便为将来的其他程序使用。所有的TsiLang编辑器都允许自动化翻译过程。你总是可以用储存在Dictionary Manager中的翻译,使工程的翻译自动化。

如你所看到的,用TsiLang Components Suite建立多语言程序是相当简单迅速的。你可以在SiComponents的主页(http://www.sicomponents.com/)找到在线帮助和更多的信息。
 
{
Title : MutilLanguage
Author : Taozhiyu
Email : taozhiyu@21cn.com
Homepage : http://www.angelfire.com/super/taozhiyu
}

unit MutilLanguage;

interface

uses
Registry, Forms, SysUtils, Windows, reinit;


function SwichLanguage(AForm : TForm ; Language : string) : boolean;
function ReadStr(StringID : integer) : string;

implementation

{$R Mystr.RES}

const
ENGLISH = (SUBLANG_ENGLISH_UK shl 10) or LANG_ENGLISH; //参看TaoZhiYu的英文帮助
CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE; //定义语言常量

CurrentEnglish = 10; //常量,用于读取资源文件中的字符
CurrentChinese = 20;


function WriteRegistry(Name,Value:string):boolean; //向注册表写数据。
var
RegisterTemp : TRegistry;
begin
result := false;
RegisterTemp := TRegistry.Create;
with RegisterTemp do
begin
try
RootKey:=HKEY_CURRENT_USER;
if OpenKey('Software/Borland/Locales',true) then
begin
WriteString(Name,Value);
result := true;
end;
CloseKey;
finally
Free;
end;
end;
end;

function ReadRegistry(Name : String): string; //从注册表读取数据
var
RegisterTemp : TRegistry;
begin
result := '';
RegisterTemp := TRegistry.Create;
with RegisterTemp do
begin
try
RootKey:=HKEY_CURRENT_USER;
if OpenKey('Software/Borland/Locales',true) then
result:= ReadString(Name);
CloseKey;
finally
Free;
end;
end
end;

function CheckCurrentLanguage : integer;    //根据从注册表中读取的数据选择英文还是中文。
begin
result := 0;
if ReadRegistry(Application.ExeName) = 'ENG' then
result := CurrentEnglish
else
result := CurrentChinese;
end;

function ReadStr(StringID : integer) : string;   //从自定义资源文件中读取字符,这部分非系统的。
var
txtCaption : array[0..255] of char;
begin
result := '';
StringID := StringID + CheckCurrentLanguage;  //注意这里,如果你自定义的需要实现双语的超过两位数,那么前面定义的CurrentEnglish 和CurrentChinese就要变成3位的。
if LoadString(HInstance, StringID , txtCaption,SizeOf(txtCaption))>0 then
result:=StrPas(txtCaption);
    //根据上面的StringID来从资源文件中选择相应的语言.
end;

function RefreshFormFace(AForm : TForm ; Language : string) : boolean; //刷新窗体和窗体中各控件
var
LoadSuccess : integer;
FormRect:TRect;
begin
result := false;
LoadSuccess := 0;
FormRect:=AForm.BoundsRect;
if Language = 'CHN' then LoadSuccess := LoadNewResourceModule(CHINESE);
if Language = 'ENG' then LoadSuccess := LoadNewResourceModule(ENGLISH);
if LoadSuccess <> 0 then
begin
LockWindowUpdate(AForm.Handle);
ReinitializeForms;
AForm.SetBounds(FormRect.Left,FormRect.Top,FormRect.Right-FormRect.Left,FormRect.Bottom-FormRect.Top);
LockWindowUpdate(0);
end;
result := true;
end;

function SwichLanguage(AForm : TForm ; Language : string) : boolean; //设定相应的语言过程
begin
result := false;
WriteRegistry(Application.ExeName , Language); //写入注册表以保存当前设置的语种
RefreshFormFace(AForm , Language);
result := true;
end;

end.
 
谢谢各位:)
 
接受答案了.
 
后退
顶部