This add-in demonstrates how to support multiple languages using a single XLL, and multiple resource-only DLLs. The add-in will start with the language that matches the user's current regional settings in the Control Panel. The user can switch between languages using a menu.
The program logic is almost identical to that in the Localized (Single DLL) sample, and the code of the two projects may usefully be compared.
See Deployment for a discussion of using resource-only DLLs to support multiple languages. For step-by-step instructions on how to convert an existing project to support multiple languages, see Conversion of an existing project in the User Guide.
The project InterMultiRes_1036 can be found in the sub-directory Samples\InterMulti\InterMultiRes_1036. This project builds a French language resource-only DLL for the InterMulti sample.
The resource file InterMulti.rc contains resources in one language only - English (US).
The resource-only DLL InterMultiRes_1036.DLL contains a resource file InterMultiRes_1036.rc with resources in one language only - French (France).
In contrast to a standard XLL, this one uses resources IDs such as #202 instead of strings wherever possible. See the discussion in Localized (Single DLL) sample : Resource IDs for details of the code.
InitLanguageList() is called once, during OnXllOpenEx(), to initialize a list of languages supported by the XLL. The function searches the directory of the XLL for files which match InterMultiRes_*.dll.
In order to change the language at run-time, you need to consider all the areas of behavior that are localized:
Normally much of this code is handled in the event handlers, OnXllOpenEx() and OnXllClose(), so that it is called when the add-in is opened or closed. In the add-in, the relevant code is removed from the event handlers and placed in RegisterLocalized() and UnregisterLocalized().
void CInterMultiApp::RegisterLocalized() { // Set up menu m_menu.SetTexts("#2"); m_menu.AddItem("#3", "BuyWater"); m_menu.AddItem("-", ""); // Separator for (size_t i = 0; i < m_languageNames.size(); i++) m_menu.AddItem(m_languageNames[i], "SelectLanguage"); m_menu.Create(); // Save position of 1st language menu item m_nFirstLanguageMenu = 3; // (Menu item positions are zero based) // Create toolbar CXlToolbar::AddToolbar(m_pszToolbarName); CXlToolbar::AddTool(m_pszToolbarName, 1, "BuyWater", "#5"); CXlToolbar::SetToolBitmap(m_pszToolbarName, 1, IDB_BITMAP1); CXlToolbar::ShowToolbar(m_pszToolbarName, true, CXlToolbar::DockRight); // Save actual toolbar name, for deregistration m_strToolbarNameUsed = ::XllGetTranslatedString(m_pszToolbarName); // Reregister functions using new texts RegisterFunctions(); } void CInterMultiApp::UnregisterLocalized() { // Delete menu m_menu.Destroy(); // Delete toolbar CXlToolbar::DeleteToolbar(m_strToolbarNameUsed); // Unregister functions UnregisterFunctions(); }
The program logic of switching languages is done handled by SetLanguageID(), using XllSetStringResourceHandle():
void CInterMultiApp::SetLanguageID(LANGID langid, BOOL bFirstTime) { if (bFirstTime) // Unregister functions: the framework has already registered // them and they may be in the wrong language UnregisterFunctions(); else // Unregister everything UnregisterLocalized(); HINSTANCE hinstRes = GetLanguageResources(langid); if (hinstRes == NULL) hinstRes = XllGetResourceHandle(); XllSetStringResourceHandle(hinstRes); RegisterLocalized(); }
::XllSetStringResourceHandle |
::XllGetTranslatedString |
If you are using MS Developer Studio 6, then you should open the project file InterMulti.dsp.
If you are using MS Visual Studio .NET 2002, then you should open the solution file InterMulti.sln or the project file InterMulti.vcproj.
If you are using MS Visual Studio .NET 2003, then you should open the solution file InterMulti71.sln or the project file InterMulti71.vcproj.
If you are using MS Visual Studio 2005, then you should open the solution file InterMulti8.sln or the project file InterMulti8.vcproj.
List of Sample Projects
| Samples and Walkthroughs
| Localized (Single DLL) sample