Martin Ba
Martin Ba

Reputation: 38785

Is it possible to dynamically change the language of a modal dialog?

Say you have a dialog based MFC application that displays it's main dialog from the MyWinApp::InitInstance() function via calling dlg.DoModal().

Further, this application contains localized resources (all in the project, no satellite DLLs for this test-case), that is, the IDD_TEST_DIALOG resource is there twice, once in English and once in German.

What I want to do now is add a button to this dialog that toggles the language of the displayed dialog between the available languages in the resources. Is this possible? (Remember: The dialog is currently displayed through the DoModal() function.)

When you want to change the resource language used by MFC, you call SetThreadUILanguage (works on WIn7 and XP) or you can also call SetThreadPreferredUILanguages if only targeting Win7 (Vista+). So really, if you're able to reopen the dialog, changing the language is very easy. The question for me is whether it's possible at all to somehow reload a displayed Window with different resources.


Note that one could just make sure that all strings are reloaded, that is, somehow walk through all controls in the application and call SetWindowText to change the text of the windows.

However, this is counter to what a localized dialog (resource) is supposed to provide, namely not only translated strings, but also the necessary changes in dialog layout: Different language strings will likely be of different length, so the control have to be spaced differently. (I also could imagine that when supporting right-to-left languages or aisian scripts, the layout has to be adopted accordingly.)

Upvotes: 3

Views: 2111

Answers (1)

Jabberwocky
Jabberwocky

Reputation: 50822

The easiest thing is probably not using another dialog template but changing programmatically the texts of your dialog controls one by one by using a table that maps each control id of the dialog to a string resource.

A better solution for you would be to parse the other language's dialog template and replace the text of each control in your displayed dialog by the text found in the template and also resize and reposition the controls according to the size and position in the template dialog.

Unfortunately there is no API in Windows for parsing dialog templates, but there is a pretty good blog entry by Raymond Chen that deals with dialog templates.

Pseudo code :

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      
}

Upvotes: 2

Related Questions