2013-04-26 112 views
3

假設您有一個基於對話框的MFC應用程序,它通過調用dlg.DoModal()來顯示MyWinApp::InitInstance()函數的主對話框。是否可以動態更改模態對話框的語言?

此外,此應用程序包含本地化資源(全部在項目中,此測試用例不包含附屬DLL),即IDD_TEST_DIALOG資源有兩次,一次是英文,一次是德文。

我現在想要做的是在該對話框中添加一個按鈕,用於切換資源中可用語言之間所顯示對話框的語言。這可能嗎? (記住:當前通過DoModal()功能顯示的對話框。)

當你想改變由MFC使用的資源的語言,你叫SetThreadUILanguage(可在Win7和XP),或者你也可以,如果只針對Win7的調用SetThreadPreferredUILanguages (Vista的+)。所以,如果你能夠重新打開對話框,改變語言非常簡單。對我而言,問題在於是否有可能以某種方式重新加載具有不同資源的顯示窗口。


注意,一個可以只是確保所有的字符串被重新加載,就是somehow穿行在應用程序中的所有控件,並呼籲SetWindowText改變窗口的文本。

然而,這是反什麼本地化的對話框(資源)應該提供,即不僅翻譯字符串,而且在對話框佈局進行必要的修改:不同的語言字符串將可能有不同的長度,所以控制必須有不同的間距。 (我也可以想象,支持從右到左的語言或aisian腳本時,佈局必須相應地採用。)

+0

這是一個毫無意義的演示功能。只要他還活着,你的用戶就會說同一種語言。當他看着你的對話時,他不會改變它。如果您需要測試本地化,請使用控制面板更改系統區域設置。 – 2013-04-26 11:39:21

+0

@HansPassant:不,這不是沒有意義的功能。當然,這是一個簡化的測試案例,但是在應用程序運行時能夠切換UI語言可能是必要的(即使(很大)如果它只是一個「政治」要求,仍然需要銷售該軟件)。 (我確實認爲它可能*不一定是實際上在動態地改變模態對話中的語言所必需的,但我想我會開始詢問*某個*點,這看起來相當好,因爲它看起來很好對我來說是更復雜的用例之一。) – 2013-04-26 11:45:08

+0

本地化是功能列表中的一個項目符號。是的,我們這樣做。通過提醒他們銷售給50億用戶而不是5千萬用戶,您可以讓銷售人員滿意。而且如果他們要求毫無意義的花裏胡哨的話,他們將不得不等待更長時間的出售。這只是失去了銷售,使一個功能,沒有人實際上曾經使用一個相當昂貴的奢侈品。他們不明白這一點,你必須說出來。 – 2013-04-26 11:57:23

回答

2

最簡單的事情可能不是使用其他對話框模板,而是以編程方式更改對話框控件的文本通過使用一個表將對話框的每個控件ID映射到一個字符串資源。

更好的解決方案是解析其他語言的對話框模板,並使用模板中的文本替換顯示對話框中每個控件的文本,並根據大小和位置調整控件的大小和位置模板對話框。

不幸的是,在Windows中沒有用於解析對話框模板的API,但有一個漂亮的good blog entry by Raymond Chen處理對話框模板。

僞代碼:

foreach (control in the other language's dialog template) 
{ 
    string = control.GetText() ;   // Get text from dialog template's control 
    CRect rect = control.GetRect() ;  // Get rectangle from dialog template's control 

    CWnd *pCtrl = GetDlgItem(control.id) ; // Get pointer to control in dialog 
    pCtrl->SetWindowText(control) ;   // Set new text of control 
    pCtrl->MoveWindow(rect) ;    // resize and reposition control  
} 
+0

我會編輯問題以解釋爲什麼我認爲這不太理想。 – 2013-04-26 09:53:46

+0

您實際上也可以更改對話框中控件的大小和位置,而不僅僅是文本。所有這些信息都可以從對話框模板中獲取。我會根據這個編輯我的答案。 – 2013-04-26 12:26:07