2011年12月30日

[心得]如何建立支援全球化與在地化的多國語系 WP7 (Mango) App

一般來說,製作手機上的 App,首先會面臨到的就是 全球市場 這件事情
很多時候,一個好的創意或是想法,是不分國界的(換句話說就是大家都會爭相模仿)
如果設計出來的手機程式,只能在自己母語的地區發行,事實上會受到諸多限制
即使沒有想要推出所謂多國語言版本,至少弄個英文版本出來,曝光率也相對高

至於原本就想要製作多國語言版本的人,更應該遵循既定的規則來製作
雖然有點麻煩,不過這會解決掉將來更多的麻煩與問題,相信努力絕對是值得的

這邊,要先分兩大主題:

1. Globalization (全球化)
讓程式能夠支援多國語系的內容顯示,包含系統上的日期時間與金錢表示法等
在切換語系設定之後,能正確地顯示該語系相對應的內容

2. Localization (在地化)
讓程式能夠在每個地區獨立存在,並且顯示預設的語系內容
在市集上架的時候,能正確地設定各地區的顯示內容,而不用另外包裝程式



全球化比較單純,只要依照這邊的範例練習一次應該就沒問題了:
How to: Build a Globalized Application for Windows Phone

(這邊假使有空我再來補完這部分的中文,不好意思)

讓我們來看看在地化的製作步驟:
How to: Build a Localized Application for Windows Phone

a. 建立一個 Windows Phone 應用程式 專案


b. 選擇 Windows Phone OS 7.1


這樣一個 WP7 App 就完成了~ (喂!)
按下 F5 就能夠在模擬器上看到應用程式正常運作 (請先確認可以正常運作)

c. 先將中性語言設定成為 英文 (美國)


組件資訊的位置:
在專案按右鍵之後選屬性,頁面右側就有一個組件資訊的按紐

d. 為專案加入中性語言的語系資源檔 AppResources.resx


加入方法:
在專案按右鍵之後選 加入>新增項目 ,就會看到了

e. 為專案加入支援語系的描述,假設這邊需要繁體中文以及日文語系支援


設定方法:
前一個動作完成之後,請先關閉專案,並且在外部使用一般文字編輯器(記事本)打開專案檔(*.csproj)
找到 <SupportedCultures> 以及 </SupportedCultures>
並且在中間加上 zh-TW;ja-JP;

存檔之後就可以重新打開專案了~

f. 設定資源檔案的存取修飾詞為 Public


這邊一定要記得將存取修飾詞變更為 Public
為求保險,也順便按一下編譯,讓專案自動產生一個對應的 AppResources Class

g. 新增一個類別 LocalizedStrings,負責存取資源


這邊要宣告一個私有的靜態變數,是由語系資源的類別所產生的實體
另外,宣告一個公開的屬性,負責回傳語系的內容

h. 加入應用程式的資源參考描述


開啟 App.xaml 檔案
並且在 <Application.Resources> 與 </Application.Resources> 之間,插入

<local:LocalizedStrings xmlns:local="clr-namespace:GlobalizationAndLocalizationDemo" x:Key="LocalizedStrings" />

注意:這邊的 clr-namespace 預設就是專案的名稱,如果有不同,請自行修改

i. 設定應用應用程式標題以及頁面標題字串


回到 AppResources.resx 檔案,這邊加上兩個字串的名稱與內容值
分別代表應用程式標題以及頁面標題

注意:設定完成存檔之後,別忘了按一下編譯,重新產生新的 Class 內容對應
不然撰寫程式的時候,有可能會找不到對應的資源


j. 將標題字串與資源綁定


在 MainPage.xaml 檔案中找到 ApplicationTitle 的 Text 屬性
將其設定為 "{Binding Path=Res.AppTitle, Source={StaticResource LocalizedStrings}}"

Binding Path 是用來設定資料綁定來源
其中 Res 就是之前在 LocalizedStrings Class 設定的公開屬性名稱
而 AppTitle 則是資源檔設定的資源名稱,會自動綁定到相對應的資源內容值
(中間是透過工具自動產生的 AppResources Class 來運作)

Source 則是用來指定來源的類別, 這在步驟 h. 有指定過

這時候,你就會馬上看到預覽畫面已經出現你設定好的標題文字了
如果不放心,可以按下 F5 放到模擬器上面看看結果

k. 利用程式設定頁面標題

之前的步驟是透過 xaml 設定 binding, 這邊示範使用 code 來讀取資源的字串

先為 MainPage 加上 Loaded 事件處理
接著在事件處理中,加上 PageTitle.Text = AppResources.PageTitle; 就可以了


看,很簡單對吧?(笑)

基本上,在地化的 準備工作 到此告一段落了 XD

接下來讓我們加上中文語系以及日文語系的資源檔
方法就跟之前在專案中加入 AppResources.resx 一樣
只不過檔案名稱的命名要是 AppResources.[語系代碼].resx

注意:因為中性語言是設定為 英文 (美國),所以不需要特別加上 en-US 語系檔案

如圖所示:


注意:其他語系資源的存取修飾詞在這邊應該是預設的 沒有程式碼 才對,請不要變更這個設定


並且在不同語系檔內,設定相同的名稱,並且針對內容值做適當的翻譯

中文:

日文:

(記得存檔後重新編譯)

接下來,按下 F5 放到模擬器上面之後,就能看到中文的語系內容了 XD

變更手機語系的測試方法可以參考這邊:
How to: Test a Localized Application for Windows Phone

你可以嘗試變更到日文語系,然後測試你剛剛設定的結果 ^_^
BUT!!寫程式最討厭的就是那個BUT!!
相信你應該有注意到,在手機上的應用程式標題,永遠都是英文的!!

這下糟了,程式執行後的多國語系沒問題了,那程式執行之前呢?市集呢?
難道我們必須要每一種語言製作一個打包檔案嗎?
答案是否定的!!

我們可以透過以下方式來設定應用程式的標題字串:
How to: Localize an Application Title for Windows Phone

注意:範例中的名稱不要隨意更動,像是 AppResLib, AppTitle, AppTileString ... 等

a. 建立資源 dll 檔的建置專案


方案 中新增一個新的 專案
範本要選取 已安裝的範本 裡面的 Visual C++Win32 專案範本
名稱就取為 AppResLib ,確認目錄位置後,按下確定

b. 設定應用程式精靈


在應用程式設定頁面裡,把 應用程式類型 設定為 DLL
另外記得要把 其他選項空專案 打勾
按下完成,新的專案就建立好了

c. 設定專案屬性


在專案按下右鍵,打開屬性設定頁面
組態屬性 中找到 連結器 裡面的 進階
無進入點 的選項設定為 是(/NOENTRY)
按下確定就完成了

d. 加入字串資源


在專案按下右鍵,選擇 加入 資源
在資源類型這邊選擇 String Table (字串表)
按下新增就完成了

e. 設定字串內容並且產生動態連結資源


這邊我們要設定兩個 String ID : AppTitle 以及 AppTitleString
其中的值我們變更為 100 以及 200
而標題就先使用中立語言選項(英文)填入,你也可以直接從 AppResources 那邊複製過來貼上

都設定好了之後就可以存檔然後編譯
編譯完成後,會在輸出目錄下產生一個 AppResLib.dll 的動態連結檔案


直接將這個檔案複製到專案目錄下


f. 建立多國語系用的動態連結資源 MUI 檔案


接著再產生一次動態連結檔,這次先重新命名檔案為 AppResLib.dll.0409.mui
(0409 是 en-US 的代碼)
完成之後一樣複製到專案目錄下

g. 重複步驟 e. 與 f. 並且將標題的文字改成對應的內容


(0404 是 zh-TW 的代碼)
(0411 是 ja-JP 的代碼)

h. 將資源檔加入專案中


只是把檔案複製到目錄下是不夠的,我們還必要加檔案加入到專案中
無論是選擇新增現有項目,或是直接從檔案總管拖曳進去都可以

i. 設定資源檔屬性


新增進去的項目,要記得打開屬性視窗,確認該項目的 建置動作 是否為 內容

注意:因為 MUI 檔案並沒有預設的建置動作,所以一定不能忘記變更這些檔案的屬性,不然你會看不到結果

j. 設定標題字串


打開 WMAppManifest.xml 檔案
在 App 標籤的 Title 屬性值那邊替換為 "@AppResLib.dll,-100"

小心:像是"@AppResLib.dll,-100"這類的設定字串,逗號後面不要有空白,以免造成悲劇


同時我們也要將下方的 Tokens 標籤裡面的 Title 設定為 @AppResLib.dll,-200
(一樣記得字串中間不要有空白字元!!)

存檔後重新編譯專案,就大功告成了~~
這邊建議一定要讓專案重新編譯一次,避免有資源漏掉,導致顯示結果不正常
另外就是原本的專案如果沒有被重新安裝(解除安裝),也是看不到結果的

按下 F5 執行後,你就可以看到模擬器上的應用程式標題變成中文 !


釘選到開始畫面也是一樣 OK !


注意:標題的字串長度,英文不要超過15個字元,中文等寬字不要超過8個字元
才不會造成標題字串超過邊界的問題


透過這種方式製作好的 XAP ,上傳到市集的時候
市集會自動辨識你的 XAP 中所包含的相關語系設定與檔案
並且提供可以分別填寫不同語系內容的欄位

你不用再為了每一種國家的語系,重新包裝一次 XAP 然後重新送審一次
語言的問題,就交給內部機制去運作,怎樣,很方便吧 XD

例如:我的這支 App 送件一次就能有三種語系支援 (原本有四種,但簡體中文似乎未開放)
http://www.windowsphone.com/zh-TW/apps/bcfb3a31-1140-48da-bd48-cc304b3ea81c
http://www.windowsphone.com/en-US/apps/bcfb3a31-1140-48da-bd48-cc304b3ea81c
http://www.windowsphone.com/ja-JP/apps/bcfb3a31-1140-48da-bd48-cc304b3ea81c

(p.s. 標題悲劇就是上面那個"不小心加了空白"的結果,目前還沒找到解法
已經確認的是應用程式都沒問題,只有市集會出現錯誤標題)


建議大家有機會就自己從頭到尾練習一次,熟悉一下應用程式國際化的方法
雖然這樣專案中會有很多額外的設定與程式碼
寫作起來,也許跟以前直接把字串打在等號後面的習慣差很多
不過這都是為了將來維護的彈性著想,前期的一點點辛苦
可以省去後面一卡車的麻煩,我個人覺得是相當值得的!!

假使你的程式只提供給一種語言使用者,或許,你可以忽略這篇文章
不然,即使是只有英文與中文兩種語言,史萊姆還是建議大家要直接採用多國語言的方式製作
萬一將來哪天突然冒出需要其他更多語系的需求,不就水深火熱了嗎XD

[ 範例下載 ]

相關參考資料:
Globalization and Localization for Windows Phone

===

以上為心得分享,如有謬誤還請多指教