国际化问题 ( 积分: 50 )

  • 主题发起人 Bluewoods
  • 开始时间
不是啊,chenybin,我运行了你给我的那份,也没产生.fra和.deu文件,你是怎么产生的啊?!为什么啊?我都要受不了了,我要弃用Delphi了!你们忍心让Delphi失去一个使用者吗?[:(]
 
这50分得得可真辛苦,首先声明,你用什么工具自己爱好,我也很喜欢VC,就是不会而已,
你说的问题和版本应该没有关系,你可以打开单独fra目录下的工程,然后编译是一样的,这样可以单独长生文件,其他两个道理相同,就可以编译出来了
再转一位大虾的文章
http://www.delphibbs.com/delphibbs/dispq.asp?LID=608380
多国语言之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=&quot;eng&quot;;改变一下它
的大小和字体。
2,双击project1.chs -- form1,然后修改一些东西。比如button1的caption=&quot;chs&quot;;改一下字体。
不过最好不要随意改动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 <> nildo
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;

// 调取新的语言资源 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 - 1do
begin
Form := Screen.Forms;
ReloadInheritedComponent(Form, TForm);
//重新刷新所有元件几其父对象
end;
end;

end.
////////////////////////////////
 
用Delphi 5的Integrated Translation Environment (ITE)可以轻易得完成这个工作。
我们创建一个示意性的工程MultiLanguage, 在Form上放一个Label和一个Button, 分别把Caption赋值为“English Label” 和“English Button”。
选择菜单Project|anguages|Add ..., Delphi显示Add Languages对话框, 选择Next。
从语言列表中选中“英语(美国)” 和“中文(中国)”, 选择Next。
ITE会根据所选的语言创建子目录,目录名称是语言的缩写,选择Next。
第一次增加语言时, Update Mode固ㄎ狢reate new, 选择Next。
选择Finish。
Delphi会自动创建支持不同语言的资源动态库。
Delphi还会自动创建一个工程组, 其中包括原有的MultiLanguages.EXE, 还包括新建的两个资源动态库 (MultiLanguages.enu, MultiLanguages.chs)。 保存工程组。
Delphi启动Translation Manager, 左边是需要翻译的语言, 右边是完成百分比。
选择“中文(中国)”|Forms|Unit1, 在右边第15行和20行填写翻译后的中文。 保存并关闭。
打开Project Manager, 编译MultiLanguages.enu和MultiLanguages.chs, Delphi会在相应的子目录生成资源动态库, 但后缀不是DLL而是ENU和CHS。
 
我分开编译也没产生.fra和.deu文件!那两个文件还是你发过来时的时间!为什么啊?我一直用VC的,突然要我接Delphi的程序。我也问得不太好意思了。
还有啊,我是不是没说明白啊,我不是要在中文系统下显示日文按钮,那只要修改caption就可以啊,我是要在日文系统下显示日文按钮的。
 
不好意思倒没有,熟悉就好了,我去问别人VC的问题,别人也是一脸不屑,俺不在乎,嘿嘿。
你问是不是修改Caption就可以了,我是觉得应该修改Font属性里面的那些东西,CharSet等等,你先试了可以就可以了,日文系统没弄国,繁体中文我们以前是直接修改Caption就可以了,设置方法和其他语言应该是一样的,Delphi也不会有什么特别的,VC里面字符串资源不是也要设置画对应的语言集吗?
 
我试了的,日文修改Caption就可以了,在中文系统下运行显示就是日文了。
VC是支持Unicode的,只要程序选择Unicode编译,那就一切OK了,拿什么系统下都一样显示。
选择Caption的字体字符集也没有日文字符集可选择的啊。
 
那你可以通过ini文件动态修改caption的内容[:D][:D],结贴吧:)
 
Caption是没字符集的,但From有字符集只要选了From的字符集为日文Caption就能显示日文了。用INI的方式只要你操作系统装了日文语言字体无论你是用中文系统还是日文系统都一样能显示的。关键是你的CHARSET!
 
我知道关键是字符集啊,可我在中文系统下写的ini文件在日文系统下读取了赋值给Caption也能正常显示日文吗?
Unicode就不同啊,在什么系统下一个字就对应一个编码,当然不会乱码咯。
我试了可以了当然会结帖咯,可我现在都还没试呢,等等,不急啊!
 
你知道宋体下也可以显示日文假名的,也就是说GB2312下应该也是有日文假名的,但问题是一样的一个假名在GB2312和日文系统下的字符集中编码不同,所以在日文系统下显示会是乱码。
 
废话你用宋体的日文假名在日文系统下肯定是不能正常显示的,在中文系统下写的INI在日文下当然能正常显示,DELPHI和VC的处理字符集方式是不一样的别拿VC的来这套。
 
可你也不得不承认Delphi在出来这方面的问题时没有VC方便啊,你爱Delphi也该看到她的缺点吧,而且帮助也没VC的方便,在客户意识方面就是Microsoft强些,所以他才会有这么多的用户啊,我也不喜欢Microsoft,可该承认的还是要承认啊。
 
我做了很多多语言的项目,VC处理起来很麻烦特别是想动态切换的话简直让人烦死,而DELPHI处理起来确很轻松容易。如果用惯DELPHI的人去用VC做界面那是莫大的痛苦。DELPHI是有缺点,但和VC比绝不会是在做应用和界面层上。VC我认为更适合做WINDOWS相对底层的一些东西,DELPHI做应用界面VC做底层是一相不错的搭配。就客户意识这一点同意BORLAND做的是比MS差多了
 
大可不必为语言争论,解决问题才是正经事情[:D][:D][:D][:D],要讨论我另外开贴分分
 
有对应的richedit.xxx的文件,就是richedit.deu,richedit.enu,richedit.fra等3个,把3个文件都拷贝到和richedit.exe相同的目录,然后你再运行exe看看效果,
這幾個文件在執行文件地同一目錄下。
你應該編譯它地程序包。
我用的是d7不知道你用的是哪個版。
 
我现在用的是Delphi6,我整个包编译也罢,分开编译也罢,都没有产生那三个文件。我之前也用过Delphi7的Translation Manger来处理日文,好像是产生了日文的对应文件,可我拿到日文系统下照样是乱码!
我拜托各位老大,看清楚我的问题了啊,我不是要在中文系统下显示多种文字,那当然可以,我是要在中文简体、中文繁体、日文、韩文、英文系统下显示各自系统的文字!
还没来得及试ini方法呢,试试去啊!
 
我在ini文件里面写
[932]
File=ファイル
可在程序里面用MenuItem_File.Caption := IniFile.ReadString('932', 'File', '');读取,运行出来菜单的标题却是空,即默认值,为什么会读不到啊?
 
我找到一个方法,不过有些麻烦,
FileCaption: WideString;
FileCaption := 'ファイル';
MenuItem_File.Caption := FileCaption;
这样就可以在日文系统下正常显示了。
不过还是请问为什么我读不了ini文件啊。
 
widestring是双字节的,string不是,ini读取出来的好像是string类型的东西,个人看法是这样,那看来还真只有用资源DLL的方式了,昨天给你的例子应该可以设置widestring吧
 
chenybin,我丢了你的QQ号了呀,不好意思啊。再给我一次,以后多交流!
你昨儿的例子我还是编译不出那三个文件啊!
 
委屈以下,留下你的吧
 
顶部