張 鵬,陳景光,胡選仲,于文學
(中機試驗裝備股份有限公司,吉林 長春 130103)
工業(yè)自動化控制系統(tǒng)具有提高效率、節(jié)能降耗、節(jié)省人力成本、促進產業(yè)升級的明顯效果,其發(fā)展?jié)摿薮蟆9I(yè)自動化控制系統(tǒng)可大致劃分為硬件系統(tǒng)與軟件系統(tǒng),其中,硬件系統(tǒng)負責動作命令實際執(zhí)行,軟件系統(tǒng)主要負責數(shù)據(jù)計算分析及與使用者之間的人機交互。智能化的人機交互是自動化設備被市場認可的關鍵。
隨著我國自主研發(fā)的自動化控制設備越來越多地出口到不同的國家,測控系統(tǒng)軟件人機交互語言轉化工作日益繁重,且擁有龐大多元化的國際市場需求。打破出口設備的不同國家語言交互障礙,提高軟件開發(fā)效率,縮小我國工業(yè)自動化控制與歐美等發(fā)達國家的差距,對提升我國工業(yè)自動化技術水平及國際市場競爭力意義重大[1]。
開發(fā)軟件所需的計算機硬件和操作系統(tǒng)要求如下:
(1)計算機硬件:微型計算機;
(2)操作系統(tǒng):Windows 7及以上版本;
(3)開發(fā)工具:Microsoft Visual Studio 2017、WPF;
(4)開發(fā)語言:.NET/C#;
(5)使用控件:DevExpress最新版本;
(6)語言工具:GNU Gettext+Poedit。
WPF是微軟新一代圖形系統(tǒng),運行在.NET Framework 3.0及以上版本,為用戶界面、2D/3D圖形、文檔和媒體提供了統(tǒng)一的描述和操作方法。
DevExpress全稱Developer Express,DevExpress控件以界面美觀和功能強大著稱,此控件中有大量的示例和幫助開發(fā)的文檔,能夠讓開發(fā)人員快速入手。DevExpress控件已廣泛應用于項目進程監(jiān)督、企業(yè)管理、成本管控、生產控制等軟件中。
開發(fā)框架采用GNU Gettext+Poedit的方式實現(xiàn)多語言管理。
i18n源自英文單詞internationalization,其首末字符為i和n,18為中間的字符數(shù),是國際化的簡稱。L10N為資源本地化,全稱為Localization,因首字母L與末字母N之間共10個字母。資源本地化就是讓軟件產品使用當?shù)氐沫h(huán)境,如語言、文化、使用習慣等,一般涉及到具體國家的語言文件,以L10N表示,而多國語言相關的解決方案以i18n表示[4]。
GNU Gettext是軟件國際化的解決方案之一,類似的還有IBM的ICU4C,但ICU4C比較龐大。GNU Gettext最早使用在Linux上,現(xiàn)已支持全面Windows平臺[5]。
Poedit依賴GNU Gettext,實現(xiàn)了圖形化的操作。和普通翻譯相比,不需要再手動輸入Key,Poedit可自動進入源文件,根據(jù)一定的規(guī)則提取key。Poedit工具界面如圖1所示。
圖1 Poedit工具界面
例如,可以將_(“”)中包含的內容搜索出來形成Key,并可通過Poedit界面工具進行翻譯。同時,Poedit還提供輔助翻譯功能。Poedit工具翻譯搜索界面如圖2所示。
圖2 Poedit工具翻譯搜索界面列表
GNU Gettext+Poedit的解決方案真正意義上實現(xiàn)了編碼與翻譯分離,翻譯過程中不需要修改源代碼,只需要將MO結果文件修改到程序指定位置,程序啟動時將自動獲取新的翻譯信息。開發(fā)人員通過VS代碼編寫工具編寫代碼,提供給Poedit工具進行代碼查詢,并生成執(zhí)行程序。Poedit對代碼進行遍歷查詢,按照一定的規(guī)則搜索需要翻譯的代碼,形成PO文件。PO文件以Key-Value的形式展示給翻譯人員,翻譯人員只需要使用Poedit對指定的PO文件進行翻譯,將Key對應的Value填寫正確的翻譯。最后通過Poedit翻譯生成MO文件,再將MO文件提供給執(zhí)行程序使用[4,5]。翻譯轉化架構如圖3所示。
圖3 編碼與翻譯轉化架構
多語言幫助工具存放在EVAF.Framework.Core中,包括LNG類和GettextExtension類。LNG類聲明:
public static class LNG //類聲明
{
private static Catalog _currentCatalog;
public static string _(string key)
{
try
保時捷是最后登場的一員。單從紐博格林北環(huán)的圈速排名來看,它必將在本場測試中創(chuàng)造紀錄。但常規(guī)道路不同于賽道,我們對911 GT2 RS車主能否在日常生活中觸及這輛保時捷的極限心存疑慮。但本次測試打消了我們的顧慮—保時捷車主完全可以將這輛跑車推向極限,但前提是改變自己的駕駛風格并能適應后置后驅的車輛布局。如何在強大的制動力和牽引力的幫助下保持自若與從容,同樣是駕駛者必須掌握的能力。
{
if (_currentCatalog == null)
{
return key;
}
return _currentCatalog.GetString(key);
}
catch (Exception e)
{
Console.WriteLine(e);
}
return key;
}
}
LNG類重寫了下劃線“_”操作,用于在CS類中代碼翻譯的幫助,GettextExtension類用于對xaml中代碼翻譯的幫助。GettextExtension類聲明中的關鍵變量與函數(shù):
public string Value //實現(xiàn)方法,通過上面的Key就能成功地找到對應內容
{
get
{
if (!string.IsNullOrEmpty(Key))
{
return LNG._(Key);
}
return _value;
}
set
{
_value = value;
}
}
每處標記是通過調用ProvideValue方法來實現(xiàn)在運行時使用IServiceProvider,然后再通過查詢此IserviceProvider服務內容來獲取傳遞信息。
XAML處理器在處理具有標記的類型節(jié)點和成員值時,會直接調用ProvideValue方法,從而實現(xiàn)語言的互相轉化。
public override object ProvideValue(IServiceProvider supplier)
{
var TempSupplier = supplier.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (TempSupplier!= null) //判讀是否為空,如果不為空
{
var temp1 = TempSupplier.TargetObject as Setter;
if (temp1!= null) //判讀是否為空
{
return new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
}
}
Else //判讀是否為空,如果為空
{
return new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
}
var temp2 = new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
return temp2.ProvideValue(supplier);
}
語言改變進入觸發(fā)事件,每次打開軟件初始化的時候,都會自動綁定到已經(jīng)定義好全局的GlobalClass.LanguageChangeEvent事件。
private void Language_Event(object sender, EventArgs e)
{
NotifyValueChanged();
}
確定翻譯位置。如圖4所示,需要翻譯的位置為窗口標題“測試窗口”,測試按鈕“發(fā)送”。
圖4 軟件前端WPF界面
增加引用:
xmlns:multiLanguage="clr-namespace:EVAF.Framework.Core.MultiLanguage;assembly=EVAF.Framework.Core"
修改Title為Title="{multiLanguage:Gettext 測試窗口}",修改Button的Content為Content="{multiLanguage:Gettext 發(fā)送}"。
其中,multiLanguage:Gettext為翻譯標識,其后內容為需要翻譯的內容。
代碼修改前后對比如圖5所示。
圖5 代碼修改前后對比
multiLanguage:Gettext中multiLanguage為引用的縮寫,在本例中為multiLanguage。該縮寫智能修改為LNG和multiLanguage,為方便后面的工具使用。
如果需要修改為LNG,則需將引用修改為:
xmlns:LNG="clr-namespace:EVAF.Framework.Core.MultiLanguage;assembly=EVAF.Framework.Core"
確定翻譯位置,需要對圖6中彈出消息進行翻譯。修改CS類中代碼,需引用EVAF.Framework.Core.MultiLanguage,同時,將MessageBox中需要彈出的代碼加上LNG._(" ")即可。
圖6 彈出對話框消息翻譯
打開POEdit程序,按步驟提示生成PO文件,將PO文件生成在工程目錄的Languages目錄下(主要方便管理),也可以放在其他自定義位置。點擊保存后,在Languages文件夾中包含一個en_US.po文件(可雙擊打開)。源關鍵字用于匹配需要翻譯的字符串,采用下劃線、括號與雙引號的方式_(“”),因此輸入額外關鍵字為下劃線“_”。上面只有CS里面下劃線括號_(“”)包含的字符,但是XAML中不能出現(xiàn)這樣的描述,需要運行SearchXMAL.exe工具。翻譯結果視圖界面如圖7所示。
圖7 Poedit翻譯結果
在Debug目錄下創(chuàng)建一個Languages文件夾,并在Languages文件夾中創(chuàng)建一個“en-US”文件夾,將生成的MO文件拷貝到該文件夾中。en-US中可以有多個MO文件,支持框架、模塊為獨立的MO文件,以實現(xiàn)多種語言的互相切換。
void App_Startup(object sender, StartupEventArgs e) //程序啟動入口
{
LNG.ChangeLanguage("en-us");//導入多語言開發(fā)包
Process proc = Process.GetCurrentProcess();
if (Process.GetProcessesByName(proc.ProcessName).Length > 1)
{
MessageBox.Show(LNG._("應用程序實例已啟動!"), LNG._("提示");
Application.Current.Shutdown();
return;
}
}
程序運行效果示意圖界面如圖8所示。
圖8 多語言切換運行效果
本文利用GNU Gettext+Poedit框架結構,在無需修改原始代碼的基礎上,可自由切換多國語言,實現(xiàn)編碼與翻譯分離,提高了二次開發(fā)的效率,使自動化人才更好地投入到高精尖領域,打破自動測控系統(tǒng)國際化語言交流障礙,提高了產品的國際市場競爭力。