是否可以动态更改模态对话框的语言?

时间:2013-04-26 08:44:29

标签: winapi visual-c++ mfc localization internationalization

假设你有一个基于对话框的MFC应用程序,它通过调用MyWinApp::InitInstance()dlg.DoModal()函数显示它的主对话框。

此外,此应用程序包含本地化资源(项目中的所有资源,此测试用例没有附属DLL),即IDD_TEST_DIALOG资源有两次,一次是英语,一次是德语。

我现在要做的是在此对话框中添加一个按钮,用于切换资源中可用语言之间显示的对话框的语言。这可能吗? (请记住:对话框当前通过DoModal()功能显示。)

当您想要更改MFC使用的资源语言时,可以调用SetThreadUILanguage(适用于WIn7和XP),或者如果仅定位到Win7(Vista +),也可以调用SetThreadPreferredUILanguages。所以,如果你能够重新打开对话框,那么更改语言非常容易。对我而言,问题是,是否有可能以某种方式重新加载具有不同资源的显示窗口。


请注意,一个可以只是确保重新加载所有字符串,即somehow遍历应用程序中的所有控件并调用SetWindowText来更改文本窗户。

然而,这与本地化对话框(资源)应该提供的内容相反,即不仅翻译的字符串,而且还有对话框布局中的必要更改:不同的语言字符串可能是不同的长度,所以控制必须间隔不同。 (我也可以想象,当支持从右到左的语言或aisian脚本时,必须相应地采用布局。)

1 个答案:

答案 0 :(得分: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      
}