HOWTO: Load the Right Resource Copy on both Windows NTand Windows 95 and Windows 98 (221209)



The information in this article applies to:

  • Microsoft Windows 98
  • Microsoft Windows 95
  • Microsoft Windows NT Server 4.0
  • Microsoft Windows NT Workstation 4.0
  • Microsoft Visual C++, 32-bit Professional Edition 5.0
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual Basic Enterprise Edition for Windows 5.0
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0

This article was previously published under Q221209

SUMMARY

For an application with multiple resource copies, it is expected that a different resource copy will be loaded on both Windows NT and Windows 95 or Windows 98 after it is changed in the regional settings of the Control Panel. For example, in an EXE with both English_US and French_France resource copies, by changing the regional setting from English_US to French_France you expect to see French_France resource but this is only true on Windows NT. On English Windows 95 or 98, the English_US resource copy will always be loaded independent of regional settings. Similarly, on French Windows 95 or 98, French_France resource copy will always be loaded.

MORE INFORMATION

This behavior is by design on both Windows 95 and Windows 98. The way the system loads resources on Windows 95 and Windows 98 is different from that on Windows NT. On Windows 95 and Windows 98 there is a registry key HKEY_USERS\.Default\Control Panel\Desktop\ResourceLocale\(default) which is set to the langauge ID of the operating system (0x0409 for English_US and 0x040c for French_France). Whenever there is a resource copy whose language ID matches this registry key value, it will be loaded from the resource copies.

On Windows 95 and Windows 98, if you want to load any specific resource whose language ID is not related to a locale or system locale, it is better to use one resource-only DLL for each language. However, if you just want to load the language resource copy according to the regional settings in the Control Panel, then use the following workaround while keeping a multilingual .rc file:

  • Change the sublanguage of the language ID of each resource copy to SUBLANG_NEUTRAL.
  • Use FindResourceEx to find the correct copy of the menu and use LoadMenuIndirect to load it, and update the menu in SMMSetup.dll.

Steps to Reproduce Behavior

  1. Open an .rc file and choose Text in the Open as field of the active dialogue box.
  2. Find the Language statement in the .rc file and replace the sublanguage with SUB_NEUTRAL (or 0x0).
  3. Save the .rc file.
  4. Open the .cpp file which handles the menu (MainFrm.cpp for the case of mainframe menu), and add the following code in PreCreatWindow():
            LANGID langid = GetUserDefaultLangID();
            LPTSTR id = MAKEINTRESOURCE(IDR_MAINFRAME);  //the resource id of the menu to be loaded
            HRSRC hrsrc = FindResourceEx(hinst,RT_MENU,id,langid);
            HGLOBAL hglb = LoadResource(hinst,hrsrc);
            LPVOID lpsz = LockResource(hglb);
            cs.hMenu = LoadMenuIndirect(lpsz);
    					
  5. Rebuild the project.

Modification Type:MinorLast Reviewed:12/21/2004
Keywords:kbDSXGlobal2003Swept kbhowto kbResource KB221209