多语言版本怎么做?(300分)

H

htw

Unregistered / Unconfirmed
GUEST, unregistred user!
Borland的国际版方案有什么好处和坏处?
使用语言文件的好处是什么?有什么问题吗?
 
用big2gb 和gb2big控件 可以實現瀪簡體轉換
 
你的軟件會同時在多個國家或地區出售吧﹐否則沒能這個必要。
我們現在做的這套系統就是多語言的﹐因為它會在香港﹐大陸﹐台灣同時使用。
這個套系統 的多語言的實現不是靠delphi language來實現的。而是用數據字典
來實現﹐轉換已經寫在控件里了。當然﹐還要考慮時間問題﹐數據庫要用格林日治
時間﹐否則數據很難merge的。
good luck ^_^
 
有一个VG的控件包里有一个多语言控件。好象是一个免费、有源码的控件包,里面有不少很
好的控件。
 
http://www.sicomponents.com/download.html
我是用INI文件的方法来解决多语言问题的。
 
>>VG的控件包里有一个多语言控件。
在哪下载呀???
 
一个程序,如果需要不同的语言版本,那么应该有一下几点需要注意的地方[]:
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 <> 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;

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 - 1do
begin
Form := Screen.Forms;
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编译所有的文件,这样才能保证你的程序正常运行。
 
wumeng :
你用的也是 Tsilang 的控件吧,来握握手。呵呵。
终于看到也有人用这个了。
 
http://wolfsoft.nugoo.com 上有一个多国语言的程序.
http://wolfsoft.nugoo.com/srcdetail.asp?flag=2&amp;id=92
 
>>Puma Wang,
我的程序中用的是INI,没有用Tsilang ,因为公司不想花钱买。。。
但我觉得Tsilang 还是听好的(只是看的介绍,没有真正的使用过)。
 
delphi 菜单中的Project-->language 不行吗?
我用的就是这个。
 
天哪!什么时候把我的冬冬转过去的呀!呵呵!
 
那个版本好像好有些问题。没工夫动他呢!谁要是修改了帮忙发给我一份呀!
taozhiyu@21cn.com
 
:) 老陶,是我把你的东西转了过去。不会介意吧,你的那个东东有什么问题?
1、如果自定义的字符多,需要修改一下你定义的const
2、好像关于Check之类的菜单更新有些问题
其它的挺好用的。
 
你可以看看playicq.com上面我那个下载页面上的评论就知道有什么缺陷了。
如果你的自定义字符多,只需要修改资源文件呀!如果你需要支持的语言种类多,那么常量
就多了!
谢谢你的支持!:)
 
还有亚!我还很年轻。小陶就可以了吧!:)
 
:) 是的,我昨天看了Playicq上的留言了。我是因为没有用到那种,所以没有发现。
我已经很老了,:) 25了。:)
 
有这么多的回答,提问者用了哪种方法呀???
 
谢谢各位了!
我用自定义语言文件来实现
5万行代码, 总供1500多行中文串(重复的不算)已经搞定了, 效果还不错
 
顶部