• 试用GNU Gettext 开源多语组件包 标签: delphi语言file文本编辑domainstring 20080428 17:54 1330人阅读


    尝试过CnPack中的CnMultiLang组件和国外的GNU Gettext组件后,感觉GNU Gettext做多语言要方便些。

    这两者都是开源免费的多语言组件,而且都采用语言文件保存的字符串替换的方式,不同的是CnMultiLang采用的是[元件.属性]=[字串]的方式,而GNU Gettext采用的是[旧字串]=[新字串]的方式。

    CnMultiLang虽然比较成熟对中文化的支持比较好,而且是以控件的方式出现在组件面板中,可以可视化编辑属性,但是其多语化的方式为[元件.属性]=[字串]的方式,不方便的地方有两点:1、会有很多重复的地方 2、静态字符串,例如对话框、输入框的字符串的多语化非常不方便。

    GNU Gettext采用的是字典方式,按照词汇对应。而且,各个细节都非常贴心。安装后,在工程目录文件夹上点右键即可生成字典模板,然后在某个特定语言文件上右键合并,即可智能合并刚生成的模板,字典文件采用通用的PO格式,可以采用通用编辑器编辑(推荐Poedit,很好用)。另外,最贴心的地方就是,对于混杂在代码中的字符串,只要使用一个函数_()将字符串扩起来,再重新生成字典模板即可将其加入翻译字典;对于一些动态生成的按钮、对话框标题等,只要将其加入resourcestring即可。当然,缺点也是有的:1、没有图形化方式编辑,需要自行添加代码(其实没几行)2、对中文化支持不好,需要自行添加代码解决(设置一下全局默认字体大小即可) 3、一词多义的情况不好处理(加空格或者放到新的domain里)

    下面说一下GNU Gettext使用中需要注意的个别地方:

    下载地址http://dybdahl.dk/dxgettext/

    1、 在FormCreate中添加初始化代码
    这些代码一般比较固定:
        {Initialazation for locales}
         // 设置忽略列表
        TP_GlobalIgnoreClassProperty(TAction,'Category');
        TP_GlobalIgnoreClassProperty(TControl,
    'HelpKeyword');
        TP_GlobalIgnoreClassProperty(TNotebook,
    'Pages');
        TP_GlobalIgnoreClassProperty(TControl,
    'ImeName');
        TP_GlobalIgnoreClass(TFont);
         
    // 开始翻译组件
        TranslateComponent(self);


    2、主菜单要加"&"
    因为Delphi会自动给主菜单文字前面加一个"&"字符,如果你没有手动加的话,这样会造成主菜单这些单词无法被翻译。
    例如:主菜单"File"最好写成"&File",否则生成的字典为“File”,但Delphi会编译时自动将菜单名替换为"&File",这样就无法匹配了。

    3、resourcestring
    常用的resourcestring举例:
    resourcestring
        yes
    ='&Yes';no='&No';ok='OK'// 对话框按钮
        warning='Warning';error='Error'// 对话框标题

    MessageDlg示例:
        MessageDlg(_('Exit without saving ?'), mtWarning, mbOKCancel,0)

    4、切换语言的方法
    procedure TMainForm.mniLangCnClick(Sender: TObject);
    begin
        UseLanguage(
    'zh_CN');
        RetranslateComponent(Self);
    end;

    对话框文字被截断问题补充

    上文中介绍的方法,即在FormCreate方法中设置DefFontData.Height属性,经过证实无效。
    经考证,其实字符被截断的关键是设置了错误的Charset。例如,简体中文字符应该设置为GB2312_CHARSET,如果设置为ANSI_CHARSET则会计算字符宽度不准确,造成字符被截断的问题。

    那么,介绍我现在使用的解决办法,就是当改变语言时自动读取并设置po文件中的字体信息,这种方法需要自己用文本编辑器添加一个自定义Property,例如"Default-Font: Size=9; Charset=GB2312_CHARSET/n"。

    具体改写方法如下:

    1、在gnugettext.pas文件中找到TGnuGettextInstance.WhenNewLanguage函数,并改写为
    procedure TGnuGettextInstance.WhenNewLanguage(const LanguageID: string);
    var
        s:
    string;
        font:TStrings;
        i,code:Integer;
    begin
        
    // This is meant to be empty.
        {Read font info from po file, by Zero File}
        
    // reset charset first
        DefFontData.Charset:=DEFAULT_CHARSET;
        
    //read properties
        s := GetTranslationProperty('Default-Font');
        
    if s = '' then Exit;
        font:
    =TStringList.Create;
        font.Delimiter:
    =';';
        font.DelimitedText:
    = s;
        
    for i:=0 to font.Count-1 do
        begin
            s:
    =LowerCase(font.Names[i]);
            
    if 'name' = s then
                DefFontData.Name:
    =font.ValueFromIndex[i]
            
    else if 'size' = s then
                DefFontData.Height:
    = -MulDiv(StrToInt(font.ValueFromIndex[i]),
                        GetDeviceCaps(GetDC(
    0), LOGPIXELSY), 72)
            
    else if 'charset' = s then begin
                
    if IdentToCharset(font.ValueFromIndex[i],code) then
                    DefFontData.Charset:
    = code;
            end;
        end;
    end;

    2、在每个语言包的po文件中添加一条Property
    例如:
    简体中文:"Default-Font: Size=9; Charset=GB2312_CHARSET/n"
    繁体中文:"Default-Font: Size=9; Charset=CHINESEBIG5_CHARSET/n"
  • 相关阅读:
    自编jQuery插件实现模拟alert和confirm
    5.7 Windows常用网络命令
    学历查询和专业代码查询
    学习动态性能表(22)V$resource_limit
    学习动态性能表(21)v$lincense
    学习动态性能表(20)--v$waitstat
    学习动态性能表(19)--v$undostat
    学习动态性能表(18)--v$system_event
    学习动态性能表(17)--v$segstat&v$segment_statistics
    学习动态性能表(16)--v$rowcache
  • 原文地址:https://www.cnblogs.com/zerofire/p/7162177.html
Copyright © 2020-2023  润新知