没人回答,继续提问,如何利用Delphi5新特性制作多语言程序。(200分)

  • 主题发起人 主题发起人 CJ
  • 开始时间 开始时间
天啊,时间怎么过的这么快?????
sorry ,sorry ,sorrrrrrrry
我非常非常非常常常道歉。
明天我一定赎罪,一定一定。

(悄悄的把闹钟打到8点准备明天好好写一写)

可是真的过了20天啦,我干了些什么呢?要检讨,要检讨。
诸位请抓起鞭子打我屁股。我欠揍。

唉!真希望能克隆一个Energy。
(以前公司MM们的话,说我必须多多克隆才够他们用???)
(是做牛做马)
再次深表歉意。
不过-----都是你CJ惹的祸。
害得我长灯青盏,苦苦相思(如何公布你的密码)
 
多国语言之step

且说Energy受命之后,在Delphi5前苦苦讨教,这才发觉delphi5的技术比他
想象的还厉害,不禁冷汗直流:如果有什么闪失哪里逃得过这里大狭们的眼
睛啊。不由之间身形已经端了5尺。

Energy颤颤危危的New了一个Application,保存慌忙之间居然没起名字,
凭经验应该叫project1;然后放了一个菜单,一个按钮一个label,不禁暗自
思量到。在多国这够说明问题了吧。
想到CJ不觉在菜单的第一项中填下了caption=CJ,name=mnuChinese;呵呵,
既然有CJ也该有Energy,于是另一项中填下了 caption=Energy,name=mnuEnglish;

然后怎么办???
心中无限惶恐的Energy 调出了delphi的例子Demos/Richedit又看了看,立马又
气粗起来。呵呵,有一样好东西,可是让我可以省事不少,不禁又是一阵得意。
(Energy悄悄地把Demos/Richedit/reinit.pas往自己project目录一拷,在
project中又把它加了进来,自言自语道:50% over)

按他的意思先设置一下需要的语言页常数。
implementation

uses reinit;

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

{$R *.DFM}

做个初始化
procedure TForm1.FormCreate(Sender: TObject);
begin
mnuEnglish.Tag:=ENGLISH;
mnuChinese.Tag:=CHINESE;
end;


然后嘛(不就是菜单切换嘛)
于是把两了菜单都指到了一个地方
procedure TForm1.mnuLangClick(Sender: TObject);
begin
if LoadNewResourceModule(TComponent(Sender).Tag) <> 0 then
ReinitializeForms;
end;

呵呵;(90% over)

不会吧,让你step,你到现在都没说,就这么尽抄袭代码。Energy委屈的说,谁让
他是课代表的。想起当年是班里总课代表,我不做功课居然就没人做的年月,不禁
又是一阵感慨。
兄弟们还差10%,加油啊!
菜单[Project]-[Languages]-[Add...]
[Next>],选择中文(chs),英语(eng);(我只用了这两种语言);
[Next>],[Next>],[Next>],[Finsih],[Yes]
让你保存dpg时小心目录可能是chs,应该用上一级目录才好。

看到了吗,这是你可以修改所有的东西。别乱改。
其中有一些出错信息之类这里都后,放心改好了,改完后可以作为一个模板文件保留。
下次就不用改了。
请关闭吧!
现在可以看到你的project Manager中有3个项目,project1.exe,porject1.eng,project1.chs
后面两了是资源文件,你可以
1,双击project1.eng -- form1,然后修改一些东西。比如button1的caption="eng";改变一下它
的大小和字体。
2,双击project1.chs -- form1,然后修改一些东西。比如button1的caption="chs";改一下字体。
不过最好不要随意改动form的大小和位置!
选中project1.exe,设定为Activate;

然后(兄弟们99%了)
右键project1.chs--build;
右键project1.eng--build;
右键project1.exe--build;
run

噫,你会发现exe中的界面不起作用了。呵呵,系统自己自动选择了一个语言页嘛。
什么你不要自动,$#$%^%^&amp;,[project]-[Languages]-[set Active];
对了如果要在调出那个grid方式修改的工具可以[view]-[Translation Manager];

好了好了,顺便付上我写了说明的reinit.pas文件其实好好看一下就知道还有更强大
的功能等着你利用呢!
语言页的常数在windows.pas里开始于行218;且
+-----------------------+-------------------------+
| Sublanguage ID | Primary Language ID |
+-----------------------+-------------------------+
15 10 9 0 bit
 
// 申明,实在上传困难,真困难,只好分段传
unit ReInit;

interface

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

procedure ReinitializeForms; //重新设置form
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;

 
Energy完全处于崩溃的边缘,最后决定,从新开一个帖子。
 
// 调取新的语言资源 LCID为语言页;
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)); // 别紧张,只是取一下当前
// 的模块名,之所以如此是
// 由于可能本身是个dll。
GetLocaleInfo(Locale, LOCALE_SABBREVLANGNAME, LocaleName, SizeOf(LocaleName)); //取当前使的语言页
P := PChar(@FileName) + lstrlen(FileName); //指针运算而已 //可能是exe :-)
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;

//重新设置在显示中的所有from,;
procedure ReinitializeForms;
var
Count: Integer;
I: Integer;
Form: TForm;
begin
Count := Screen.FormCount;
for I := 0 to Count - 1 do
begin
Form := Screen.Forms;
ReloadInheritedComponent(Form, TForm); //重新刷新所有元件几其父对象
end;
end;

end.
 
去掉一个最高分,去掉一个最低分,energy最后得分200分
 
Here is a good article "<a href="http://www.undu.com/Articles/990817b.html" target="_blank">Multi-Language Support for Your Delphi Apps</a>" from UNDU.
 
thanx Dr. yysun too
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部