2013-04-26 83 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