首页  编辑  

用Expert来汉化Delphi

Tags: /超级猛料/IDE.集成开发环境/第三方工具和Expert/   Date Created:

Delphi 集成开发环境的中文化

西安交通大学计算机系刘明华

----Delphi从1995年推出到如今已经历了4个版本,但Inprise公司似乎从没有试图把Delphi界面进行本地化。对于国内许多Delphi用户来说,我们毕竟对中文的感觉比对异国文字要亲切得多,我们更希望自己所喜爱的Delphi换上用我们自己的文字装扮的界面。笔者通过对Delphi环境内部的探索与研究,摸索出一种汉化Delphi的极为巧妙的途径。现在,我们竟然可以在Delphi的集成开发环境中自由地切换中文和英文了!

----实现原理

----Delphi在启动时(运行Delphi32.exe),它首先创建它的主窗口,之后开始加载集成开发环境的设计时包(Design-timePackages),以便向组件板安装组件和创建属性编辑器。Delphi的包(扩展名为*.BPL)是一种特殊的动态连结库,它可以与应用程序中的其它模块可以共享全局数据。

----为Delphi提供集成开发环境的是Delphi32.exe这个程序,它是使用Delphi的类库建立的,故而它具有Delphi程序的典型特点。由于集成开发环境(Delphi32.exe)用到了许多设计时包,所以,这些包中的代码便可以访问Delphi32.exe中的全局数据;Delphi32.exe中的Application对象是一个全局对象,因此,它对设计时包中的代码是可见的。通过Delphi32.exe的Application对象,我们便可以访问程序的主窗口、菜单等许多重要的属性。

----Delphi中有一类被称为Expert或者Wizard的模块,它们的主要用途是为了更方便的创建应用程序或者构件的,Expert的代码被编译在Delphi的运行时包中。我们可以编写一个特别的Expert来实现对集成开发环境的修改。为了实现Delphi一启动就能换上中文界面,我们可以设法使Expert中的某些代码在Delphi加载包后就立即运行。

----构造Expert

----所有的Expert都继承自一个名为TIExpert的虚基类。这是一个比较简单的类,它在exptintf单元中的定义如下:

TIExpert=class(TInterface)

public

{ExpertUIstrings}

functionGetName:string;virtual;stdcall;abstract;

functionGetAuthor:string;virtual;stdcall;abstract;

functionGetComment:string;virtual;stdcall;abstract;

functionGetPage:string;virtual;stdcall;abstract;

functionGetGlyph:HICON;virtual;stdcall;abstract;

functionGetStyle:TExpertStyle;virtual;stdcall;abstract;

functionGetState:TExpertState;virtual;stdcall;abstract;

functionGetIDString:string;virtual;stdcall;abstract;

functionGetMenuText:string;virtual;stdcall;abstract;

{LaunchtheExpert}

procedureExecute;virtual;stdcall;abstract;

end;

----Expert必须实现TIExpert虚基类中所定义的纯虚函数,这些函数将被Delphi集成开发环境调用。Delphi在安装Wizard时将以如下顺序调用Expert中的方法:GetName,GetIDString,GetStyle,GetState,GetMenuText。其中GetName方法只在Expert初始化时被调用一次,其它一些方法则会被调用多次。

----本文中为了简单起见,笔者所给的例子只翻译了File,Edit,Search和View这几个菜单。你可以向例子中增添少许代码把其它的菜单也进行翻译。

----在编译并安装好该Expert后,你的Delphi便可以在中英文界面之间切换了(从Help菜单中选择"中文菜单/English")。

----Expert的单元代码(Localize.PAS)及其注释如下:

unit Localize;

//

//Chinese Localization of Delphi

//Written Jan 1999 by SimonM.LIU

//The author can be reached at:

//email:minghua_liu@263.net or simon_liu@263.net

interface

uses

 ExptIntf, Windows, Messages, classes, Forms, menus, Extctrls,

 ShellAPI, comctrls, controls, Dialogs, ToolIntf, SysUtils;

type

 TChinese = class(TIExpert)

 public

   function GetStyle: TExpertStyle; override;

   function GetName: string; override;

   function GetAuthor: string; override;

   function GetComment: string; override;

   function GetPage: string; override;

   function GetGlyph: HICON; override;

   function GetState: TExpertState; override;

   function GetIDString: string; override;

   function GetMenuText: string; override;

   procedure Execute; override;

 end;

var

//中/英文菜单项

 Citems            : array[0..10]of String =

   ('文件', '编辑', '查找', '查看', '工程',

   '运行', '组件', '数据库', '工具', '工作组', '帮助');

 Items             : array[0..10]of String =

   ('&File', '&Edit', '&Search', '&View', '&Project',

   '&Run', '&Component', '&Database',

   '&Tools', '&Workgroups', '&Help');

 CFileItems        : array[0..20]of String =

   ('新建...', '新建程序', '新建窗体', '新建单元', '-', '打开...',

   '打开工程', '重新打开', '-', '保存', '另存为', '工程另存为',

   '全部保存', '关闭', '全部关闭', '-', '引用单元', '-', '打印', '-', '退出');

 CEditItems        : array[0..20]of String =

   ('撤销', '恢复', '-', '剪贴', '拷贝', '粘贴', '删除', '全选',

   '-', '与格子对齐', '放至最前', '放至最后',

   '对齐...', '大小...', '比例...', '顺序...',

   '创建次序...', 'Flip C&hildren', '锁住控件',

   '-', '增加至Interface...');

 CSearchItems      : array[0..9]of String =

   ('查找...', '在所有文件查找...', '替换...',

   '再查找', '递增查找', '-', '跳至第...行',

   '查找错误...', '-', '浏览符号...');

 CViewItems        : array[0..17]of String =

   ('项目管理器', '对象观察器', '对齐样式', '浏览器', ' 代码浏览 ',' 组件列表 ',' 窗口列表... ',' 调试窗口 ',' - ',

   '切换Form/Unit', '单元...', '窗体...',

   '类型库', '-', '新的编辑窗口', '-', '工具条', '显示为Form');

 FileItems         : array[0..20]of String =

   ('&New...', 'New Applica&tion', 'New&Form',

   'New &Unit', '-', '&Open...', 'Open Pro&ject...',

   '&Reopen', '-', '&Save', 'Save &As...',

   'Sav&e Project As...', 'Sa&ve All', '&Close',

   'C&lose All', '-', '&Use Unit...',

   '-', '&Print...', '-', 'E&xit');

 EditItems         : array[0..20]of String =

   ('&Undelete', '&Redo', '-', 'Cu&t', '&Copy', '&Paste',

   '&Delete', 'Se&lect All', '-', 'Align to &Grid',

   'Bring to &Front', 'Send to &Back', '&Align...',

   '&Size...', 'Scal&e...', 'Tab O&rder...',

   'Creatio&n Order...', 'Flip C&hildren',

   'Loc&k Controls', '-', 'Add T&o Interface...');

 SearchItems       : array[0..9]of String = ('&Find...',

   'Fin&d in Files...', '&Replace...',

   '&Search Again', '&Incremental Search',

   '-', '&Goto Line Number...',

   'Find &Error...', '-', 'Browse S&ymbol...');

 ViewItems         : array[0..17]of String =

   ('&Project Manager', '&Object Inspector',

   '&Alignment Palette', '&Browser', 'Code E&xplorer',

   '&Component List', '&Window List...',

   '&Debug Windows', '-', 'To&ggle Form/Unit',

   '&Units...', '&Forms...', '&Type Library', '-',

   'New &Edit Window', '-', 'Toolba&rs', '&View as Form');

//当前界面是否为中文

 IsChinese         : Bool = False;

 MenuItem, SubItem : TMenuItem;

 MainMenu          : TMainMenu;

 Form              : TForm;

 procedure Register;

implementation

function TChinese.GetName: string;

begin

 Result := 'Chinese Delphi';

//更改Delphi的标题

 Application.Title := '中文Delphi';

//更改Delphi的图标

 Application.Icon.Handle := ExtractIcon(hInstance, 'Shell32.dll', 41);

//用变量Form指向Delphi程序的Application对象的主窗口

 Form := Application.MainForm;

//获取主窗口的主菜单

 MainMenu := (Form.FindComponent('MainMenu1')) as TMainMenu;

//如果你不想Delphi一启动就进入中文界面,则需去掉下行语句

 Execute;

end;

function TChinese.GetStyle: TExpertStyle;

begin

Result := esStandard;

end;

function TChinese.GetAuthor: string;

begin

Result := 'SimonMLIU';

end;

function TChinese.GetComment: string;

begin

Result := 'Chinese Delphi interface';

end;

function TChinese.GetPage: string;

begin

Result := '';

end;

function TChinese.GetGlyph: HICON;

begin

Result := 0;

end;

function TChinese.GetState: TExpertState;

begin

Result := [esEnabled];

end;

function TChinese.GetIDString: string;

//返回用于标识该Wizard的串

begin

Result := 'SimonLiu.First Wizard';

end;

function TChinese.GetMenuText: string;

//此处返回的串将出现在Help菜单中

begin

Result := '中文界面/English';

end;

procedure TChinese.Execute;

var

i: integer;

begin

 IsChinese := not IsChinese;

 if isChinese

   then Application.Title := '中文Delphi'

   else Application.Title := 'English Delphi';

 for i := 0 to MainMenu.Items.Count - 1 do

 begin

   MenuItem := MainMenu.Items[i];

   if IsChinese then MenuItem.Caption := CItems[i]

     else MenuItem.Caption := Items[i];

 end;

//File菜单的中/英文转换

 MenuItem := MainMenu.Items[0];

 for i := 0 to MenuItem.Count - 1 do

 begin

   SubItem := MenuItem.Items[i];

   if IsChinese then SubItem.Caption := CFileItems[i]

     else SubItem.Caption := FileItems[i];

 end;

//Edit菜单的中/英文转换

 MenuItem := MainMenu.Items[1];

 for i := 0 to MenuItem.Count - 1 do

 begin

   SubItem := MenuItem.Items[i];

   if IsChinese then SubItem.Caption := CEditItems[i]

     else SubItem.Caption := EditItems[i];

 end;

//Search菜单的中/英文转换

 MenuItem := MainMenu.Items[2];

 for i := 0 to MenuItem.Count - 1 do

 begin

   SubItem := MenuItem.Items[i];

   if IsChinese then SubItem.Caption := CSearchItems[i]

     else SubItem.Caption := SearchItems[i];

 end;

//View菜单的中/英文转换

 MenuItem := MainMenu.Items[3];

 for i := 0 to MenuItem.Count - 1 do

 begin

   SubItem := MenuItem.Items[i];

   SubItem := MenuItem.Items[i];

   if IsChinese then SubItem.Caption := CViewItems[i]

     else SubItem.Caption := ViewItems[i];

 end;

//以下两行使Delphi在改变菜单后自动调整好各项菜单项的大小。

 ShowWindow(Form.Handle, SW_MAXIMIZE);

 ShowWindow(Form.Handle, SW_RESTORE);

 if IsChinese

   then

   Application.MessageBox('Delphi中文版','Delphi', MB_ICONINFORMATION)

else

 Application.MessageBox('Chinese Delphi!','Delphi', MB_ICONINFORMATION);

end;

procedure Register;

begin

 RegisterLibraryExpert(TChinese.Create);

end;

end.

----安装Expert:①选择菜单Componet|InstallComponent;②把Localize.pas单元安装到一个新的Package中。

----卸载Expert:选择菜单Componet|InstallPackages,卸载你不想使用的包。

----Delphi的版本

----以上所说的Delphi均指Inprise公司1998年秋季推出的Delphi4.0。由于各种Delphi版本所提供的菜单不尽相同,所以把上述代码移植到Delphi2.0、3.0等版本时,需要对菜单项的数目和菜单文字作一些相应的调整。

----用大致相同的方法笔者编写了一个可以在多种语言之间进行切换的Delphi"插件"(如图所示)。不同的是它不再是建立在TIExpert的基础上的了。鉴于篇幅原因,在此就不详细介绍它的实现过程了,笔者准备将它放到http://delphians.yeah.net站点上。如果读者有兴趣更多地了解这方面知识,可以通过电子邮件与我联系(simon_liu@263.net)。

----通讯地址:西安交通大学9649#

----邮政编码:710049

----电子邮件:minghua_liu@263.net

-中国计算机世界出版服务公司版权所有