************制作多国语言支持过程中,需要注意的几点问题,兼散分*************

IORILI 2003-11-04 01:38:20
最近刚进新公司,赶上公司开发外包项目,本来在以前公司也是做外包的,但没有接触到多国语言支持,本来这篇文章早就要写出来的,但我的大部分朋友都知道,前几天我被封号了,原因就不说了,不过塞翁失马焉知非福,以前我的信誉分本来就是105,但csdn上老是显示100,经过这次事件,变成了105,出乎我的意料^-^.
谨以此篇文章,献给我的csdn版的好朋友们,谢谢他们的支持。
人员名单:
FrameSniper:fs
非技术版版主,听说此人技术过硬,一直没有机会讨教。(是铁公鸡)
阿德:
此人异常活跃,不过上次csdn排名竟然排在俺之后,活跃程度下降不少,有待提高
2星不过信誉制过低,不知道他在哪方面比较有研究?(有机会讨教几招)
duxin(小伍)
此人在青岛,离我很近,赫赫,是领导,不知道此人擅长什么,不过肯定有过人之处,不过有机会要和他喝两杯,(我在csdn上最早的朋友)
qxj(Borland中国&游民):
呵呵,刚认识不久,经常在qq上聊,不过可能我以后都不会上qq了,此人看名字很酷,呵呵。
reallike(认真学习Cpp用Cpp考虑delphi):
听说叫:爱翔,现在在上海,以前开公司,厉害人物,现在专心研究技术,呵呵,我向他请教过,受益非浅,以后还要向他提问^-^
jpyc(九品御厨-进军嵌入式):
图形处理版主,呵呵,对菜肴很有研究,等结婚要他掌勺 呵呵
lw549(那个孩子他爹):
此人也是技术高人,大家有机会一定要认识他!!!等有机会我会慢慢向他请教
hkbarton(宁静至远||淡泊明志):
呵呵,跟他是在qq上认识的,不过以后可能就机会少了,以后多指教
tiexinliu(铁心刘):
技术高人,呵呵挺热情
noil0125(珏心)
技术高人,有机会讨教几招
pankun(剑神一笑 ^_^)
经常在网上探讨技术,呵呵
dickeybird888(于伟刚)
经常在网上探讨技术,呵呵,他最近升星,好像回答问题少了
delphi_xizhousheng(西周生)
技术高人,不过怎么性欲之那么少了???
Shiyl((云淡)||(风清))
经常在网上探讨技术,呵呵
zhoutian618(秦失其鹿,天下共逐,唯胜者得鹿而割之)
技术高人,有机会大家一定要问他!!!。
huojiehai(海天子)
没怎么聊过,不过技术很高
yoic(我是一棵菠菜,菜,菜,菜,菜,菜,菜)
不知道现在干什么了,最近不怎么见他
theone_jxm() ( )
以前一个公司的,做数据仓库的,大家有什么问题可以问他,呵呵
CDSoftwareWj(95927)
呵呵,最近经常在qq上见他,聊得很开心
CloneCenter(复制中心)
最近不怎么见他,我刚开始来csdn的时候,他就是星星了
jackie168(玉面書生)
好像在灌水区吧,呵呵

不过以上的高人们最近好像都不在技术区露面了??不知何解,

...全文
120 125 打赏 收藏 转发到动态 举报
写回复
用AI写文章
125 条回复
切换为时间正序
请发表友善的回复…
发表回复
stbrine 2003-12-27
  • 打赏
  • 举报
回复
感谢reallike(认真学习Cpp用Cpp考虑delphi) 提供的代码,在什么不明之处再请教。
收藏。
inforum 2003-12-15
  • 打赏
  • 举报
回复
Mark
tiger19760407 2003-11-17
  • 打赏
  • 举报
回复
学习,谢谢!
siwuge 2003-11-17
  • 打赏
  • 举报
回复
迫不及待地收藏。虽然我一点不懂,哈,我是初学。
tonylk 2003-11-17
  • 打赏
  • 举报
回复
http://www.playicq.com/dispdocnew.php?id=8308
  • 打赏
  • 举报
回复
up
IORILI 2003-11-13
  • 打赏
  • 举报
回复
delphi内的多国语言支持好象不行啊
reallike 2003-11-12
  • 打赏
  • 举报
回复
kingron的文章。
用Delphi实现多语言界面
关键字:多语言界面,Delphi,国际化,本地化。

随着Internet在全球的普及,一个软件开发者,开发出来的产品可以随意发布到全球各个角落,然而与此同时,开发出来的产品也面临着一个新的问题:如何实现各种不同的语言界面,甚至根据最终用户的操作系统的语言版本,自动更改语言界面?难道为每一个不同的语言编写一个不同的版本?不,完全没有必要。Delphi 5.0作为一个优秀的快速RAD开发工具,可以很容易地实现国际化支持,因为Delphi 5.0内置了对多语言界面的支持。
一个程序,如果需要不同的语言版本,那么应该有一下几点需要注意的地方[]:
1. 必须允许你的程序代码能够处理好各种语言字符串,例如如果要中文化,必须能够处理双字节。
2. 你必须设计好你的程序界面,以便能够使你的程序界面元素有足够的空间显示语言文字信息。一般说来,在50个字节以内的英文单词所表达的意思,用其他的语言来描述的话,长度要超过50字节,但中文是一个例外。特别对于几个字节的英文单词,其他的语言的长度几乎百分之百要超过英文的长度!因此,必须在控件中留出足够的长度以便在更改语言之后,还能显示全部的语言文字信息。
3. 你必须翻译所有的资源。
本文将着重讨论如何用Delphi 5.0实现多语言的支持和切换,界面设计和上述要求不在本文讨论范围之内。
要为程序添加语言支持,只要在Delphi主菜单项Project下面选择LanguagesàAdd…即可。点击之后出现语言向导,读者按照向导进行操作即可。向导结束之后,会生成一个工程组文件(BPG),最后出现Translation Manager,软件开发者可以在这里翻译所有语言的所有资源,包括字体、位置、文字等等。说明一下:你可以随时随地用Project下面的Languages子菜单的功能来添加、删除、修改各种界面元素。
做完上述工作之后,我们现在就差切换语言的代码了。为了切换语言,大家可以使用下面的一个单元[],单元中提供了两个函数,用来更换语言界面元素,其中LoadNewResourceModule是用来修改文字信息等等,ReinitializeForms用来重新刷新窗体和控件以保证同步。
///文件名:MaltiLan.pas
unit MaltiLan;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;

procedure ReinitializeForms;
function LoadNewResourceModule(Locale: LCID): Longint;

implementation

type
TAsInheritedReader = class(TReader)
Public
procedure ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer); Override;
end;

procedure TAsInheritedReader.ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer);
begin
inherited ReadPrefix(Flags, AChildPos);
Include(Flags, ffInherited);
end;

function SetResourceHInstance(NewInstance: Longint): Longint;
var
CurModule: PLibModule;
begin
CurModule := LibModuleList;
Result := 0;
while CurModule <> nil do
begin
if CurModule.Instance = HInstance then
begin
if CurModule.ResInstance <> CurModule.Instance then
FreeLibrary(CurModule.ResInstance);
CurModule.ResInstance := NewInstance;
Result := NewInstance;
Exit;
end;
CurModule := CurModule.Next;
end;
end;

function LoadNewResourceModule(Locale: LCID): Longint;
var
FileName: array[0..260] of char;
P: PChar;
LocaleName: array[0..4] of Char;
NewInst: Longint;
begin
GetModuleFileName(HInstance, FileName, SizeOf(FileName));
GetLocaleInfo(Locale, LOCALE_SABBREVLANGNAME, LocaleName, SizeOf(LocaleName));
P := PChar(@FileName) + lstrlen(FileName);
while (P^ <> '.') and (P <> @FileName) do Dec(P);
NewInst := 0;
Result := 0;
if P <> @FileName then
begin
Inc(P);
if LocaleName[0] <> #0 then
begin
// Then look for a potential language/country translation
lstrcpy(P, LocaleName);
NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
if NewInst = 0 then
begin
// Finally look for a language only translation
LocaleName[2] := #0;
lstrcpy(P, LocaleName);
NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
end;
end;
end;
if NewInst <> 0 then
Result := SetResourceHInstance(NewInst)
end;

function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
var
HRsrc: THandle;
ResStream: TResourceStream;
AsInheritedReader: TAsInheritedReader;
begin { avoid possible EResNotFound exception }
if HInst = 0 then HInst := HInstance;
HRsrc := FindResource(HInst, PChar(ResName), RT_RCDATA);
Result := HRsrc <> 0;
if not Result then Exit;
ResStream := TResourceStream.Create(HInst, ResName, RT_RCDATA);
try
AsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);
try
Instance := AsInheritedReader.ReadRootComponent(Instance);
finally
AsInheritedReader.Free;
end;
finally
ResStream.Free;
end;
Result := True;
end;

function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;

function InitComponent(ClassType: TClass): Boolean;
begin
Result := False;
if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;
Result := InitComponent(ClassType.ClassParent);
Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(
FindClassHInstance(ClassType)), Instance) or Result;
end;

begin
Result := InitComponent(Instance.ClassType);
end;

procedure ReinitializeForms;
var
Count: Integer;
I: Integer;
Form: TForm;
begin
Count := Screen.FormCount;
for I := 0 to Count - 1 do
begin
Form := Screen.Forms[I];
ReloadInheritedComponent(Form, TForm);
end;
end;

end.
测试程序窗体单元文件如下:
///单元文件名:unit1.pas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, MLanTool, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
File1: TMenuItem;
Exit1: TMenuItem;
Language1: TMenuItem;
Chese1: TMenuItem;
English1: TMenuItem;
Button1: TButton;
Memo1: TMemo;
ListBox1: TListBox;
GroupBox1: TGroupBox;
Panel1: TPanel;
procedure Exit1Click(Sender: TObject);
procedure Chese1Click(Sender: TObject);
procedure English1Click(Sender: TObject);
Private
{ Private declarations }
Public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
const
ENGLISH = (SUBLANG_ENGLISH_US shl 10) or LANG_ENGLISH;
CHINESE = (SUBLANG_CHINESE_SIMPLIFIED shl 10) or LANG_CHINESE;

procedure TForm1.Exit1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Chese1Click(Sender: TObject);
begin
if LoadNewResourceModule(CHINESE) <> 0 then
ReinitializeForms;
end;

procedure TForm1.English1Click(Sender: TObject);
begin
if LoadNewResourceModule(ENGLISH) <> 0 then
ReinitializeForms;
end;

end.
如果要自动切换语言,只要在FormCreate事件中添加如下代码即可:
if LoadNewResourceModule(SysLocale.DefaultLCID) <> 0 then
ReinitializeForms;
说明一点:在程序完成的时候,你应该用Luanguages子菜单的Update Resources DLL功能更新所有的窗体和代码,然后用Build All Project编译所有的文件,这样才能保证你的程序正常运行。
sandy110 2003-11-11
  • 打赏
  • 举报
回复
up
okook 2003-11-11
  • 打赏
  • 举报
回复


人太多,分太少,做回义务,
不过兄的吗,爱骂也狂顶 ^_^
IORILI 2003-11-11
  • 打赏
  • 举报
回复
up
ly_liuyang 2003-11-09
  • 打赏
  • 举报
回复
我都是用Delphi的Add语言来做的
这个简单了,但内部字符串还是不行,变成ResourceString才OK

Ini的,变量太多,很难搞

总之就是麻烦,都没有一个好方案

http://lysoft.7u7.net
myadvice 2003-11-09
  • 打赏
  • 举报
回复
眼睛兄的东西无条件狂顶
猛禽 2003-11-09
  • 打赏
  • 举报
回复
Delphi的Add语言就是所谓的ITE
IORILI 2003-11-09
  • 打赏
  • 举报
回复
up
halfdream 2003-11-08
  • 打赏
  • 举报
回复
关注加接分.
头几天我看见两个东西,
一个是EMULE的源码(C++),EMULE实现的多语言切换效果似乎还不错,不过处理可能麻烦点.
在网上可以找到.

二是DFM的动态处理技术..

大地精灵 2003-11-08
  • 打赏
  • 举报
回复
今天上来看了一下,收到眼镜兄的消息,过来看一下,呵呵,看来我来的比较晚
steve0531 2003-11-08
  • 打赏
  • 举报
回复
接分..
dickeybird888 2003-11-07
  • 打赏
  • 举报
回复
学习学习!
saien 2003-11-07
  • 打赏
  • 举报
回复
此乃高人业,有机会交流交流,学习....
加载更多回复(105)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧