前言:
当前大家对“delphi远程播放控件”大约比较关怀,看官们都需要学习一些“delphi远程播放控件”的相关资讯。那么小编在网络上网罗了一些有关“delphi远程播放控件””的相关资讯,希望你们能喜欢,各位老铁们一起来学习一下吧!在用Delphi开发软件的时候,会碰到需要支持多语言,这也是很多流行软件支持的特性。在网上搜了很多文章,没有一个能把整个过程讲清楚的,本文将结合实践,把Delphi的多语言支持的方法分享给大家。
多语言支持的第一步,就是收集需要翻译的文本,生成针对各种语言的文本模板。收集翻译文本大部人都会想到用TLang组件,实际上这个组件的功能实在有限,并不能完全的收集我们想要的所有文本,但是Delphi本身也提供了手动收集的方法。
在FMX.Types(Delphi 11.3)单元,存在以下几个函数(过程函数就不去分了,函数叫着顺口):
var CollectLang, Lang: TStrings;procedure CollectLangStart;begin ResetLang; if CollectLang = nil then begin CollectLang := TStringList.Create; // TStringList(CollectLang).Sorted := True; TStringList(CollectLang).CaseSensitive := True;end;procedure CollectLangFinish;begin FreeAndNil(CollectLang);end;function CollectLangStrings: TStrings;begin Result := CollectLang;end;procedure CollectLangSave;begin if CollectLang <> nil then CollectLang.SaveToFile(ExtractFilePath(ParamStr(0)) + 'lang.lng');end;
CollectLangStart:启动收集;
CollectLangFinish:停止收集
CollectLangStrings: 返回收集数据
CollectLangSave: 保存收集结果
在进行数据收集之前,还需要一些事情需要我们知道:
所有的TStyledControl对象的继承者都会自动翻译自身的Text和Hint属性,但是也可以通过设置AutoTranslate=False来阻止自动翻译,这可以让我们来设置一些我们不需要翻译的控件不被自动翻译。所有翻译都会调用FMX.Types(Delphi 11.3)单元的Translate函数,函数原型如下:
function Translate(const AText: string): string;var Idx: Integer;begin if AText = '' then begin Result := ''; Exit; end; if Assigned(CustomTranslateProc) then begin if CustomTranslateProc(AText) <> '' then Result := CustomTranslateProc(AText) else Result := AText; Exit; end; if CollectLang <> nil then begin if CollectLang.IndexOf(AText) < 0 then CollectLang.Add(AText) end; if Lang <> nil then begin if not NeedResetLang then begin Idx := Lang.IndexOfName(AText); if Idx >= 0 then Result := Lang.ValueFromIndex[Idx] else Result := AText; end else begin Idx := IndexOfValueStr(Lang, AText); if Idx >= 0 then Result := Lang.Names[Idx] else Result := ''; if Result.IsEmpty then Result := AText; end; end else Result := AText;end;
通过Translate函数代码我们可以看出,该函数包含了文本收集的功能,所以我们需要进行文本收集,就需要在软件开始收集后,尽可能多的显示(实际上控件只要创建了就可以了)需要翻译的控件所在的界面,显示的越多,收集的信息就越全面。
有了前面的信息,对于不是控件Text和Hint属性的文本,比如一些错误信息等如果需要自动翻译,我们需要在显示消息的地方把错误信息用Translate函数括起来,这样就可以自动翻译我们输出的文本信息,也可以在信息收集的时候把这些信息自动加入收集模板。
收集代码我是这样写的:
procedure TMainForm.FormCreate(Sender: TObject);begin{$IFDEF DEBUG} CollectLangStart;{$ENDIF}end;procedure TMainForm.FormDestroy(Sender: TObject); {$IFDEF DEBUG} CollectLangSave; CollectLangFinish; {$ENDIF}end;
生成的模板内容如下:
&ToolsConsoleSearchDebugBookMarkGeneralShortCut The file '%s'has been modified, do you want to save it?
生成的模板就只是一行行的文本,如果要进行翻译,需要每行后面加一个=后面跟翻译内容,比如:
&Tools=工具Console=控制台Search=搜索Debug=调试BookMark=书签General=通用ShortCut=快捷键 The file '%s'has been modified, do you want to save it?=文件'%s'已修改,是否保存?
在这里需要注意的是系统自动收集的文本中带字符引号的文本,比如前面模板中的
The file '%s'has been modified, do you want to save it?
会自动把Pascal字符串中的两个字符引号转换成一个字符引号即''%s''换成了'%s'。
The file '%s'has been modified, do you want to save it?文本在实际使用的时候是如下这样用的:
const sCloseFileQuery = 'The file ''%s''has been modified, do you want to save it?';
程序中会如下调用:
TDialogService.MessageDialog(format(Translate(sCloseFileQuery),[ExtractFileName(EditorItem.FileName)]),TMsgDlgType.mtConfirmation,[TMsgDlgBtn.mbYes,TMsgDlgBtn.mbNo,TMsgDlgBtn.mbCancel],TMsgDlgBtn.mbYes,0,(procedure(const AResult: TModalResult)begin ConfirmResult := AResult;end));case ConfirmResult of mrYes: begin Result := EditorItem.Save; end; mrNo: begin //Result := True end; mrCancel: begin Result := False; end; end;end;
为什么要说这个,是因为如果手动添加需要翻译的文本,一定注意把文本中的两个字符引号换成一个字符引号,否则翻译不了.
翻译后的语言文件,还需要注意编码的问题,默认的ANSI编码使用会有问题,最好是保存为UTF8编码保存,在使用时同样用UTF8编码读取.
在为程序添加多语言支持功能之前,还需要知道,Delphi中每种语言都有一个两个字符的ID,比如英语是'en',中文是'zh'.
下面我们为程序添加多语言支持。本来Delphi提供了一个函数,直接从文件中加载语言文件
procedure LoadLangFromFile(const AFileName: string);
但是该函数只能使用默认编码,所以不能直接使用这个函数,不过Delphi还提供了另一个函数
procedure LoadLangFromStrings(const AStr: TStrings);
所以加载语言文件的函数如下:
procedure LoadLocal;var Lang: String; LocaleSvc: IFMXLocaleService;begin Lang := 'en'; if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, LocaleSvc) then begin Lang := LocaleSvc.GetCurrentLangID; if Lang='zh' then begin if TEncoding.Default.CodePage=936 then Lang := Lang+'_Simplified' else Lang := Lang+'_Traditional' end; end; LoadLocal(Lang);end;procedure LoadLocal(const Lang: String);var List: TStrings; FileName: String;begin if Lang='auto' then LoadLocalelse if Lang='en' then ResetLangelsebegin FileName := TPath.Combine(TVPLUtils.LocalesDir,Lang+'.lng'); if TFile.Exists(FileName) then begin List := TStringList.Create; try List.LoadFromFile(FileName,TEncoding.UTF8); LoadLangFromStrings(List); finally FreeAndNil(List); end; end; end;end;
ResetLang函数是将所有控件的文本恢复到初始状态,这也是Delphi自身提供的函数。
if TEncoding.Default.CodePage=936 then
这句代码我用来判断是否是中文简体系统,不知道还有没有其他方法来判断。
到这里,Delphi多语言支持的整个过程就实现完了,希望能帮到你.
标签: #delphi远程播放控件