Making things better out from under people: the story of MUI

by Michael S. Kaplan, published on 2007/10/31 10:16 -04:00, original URI:

Over in the Suggestion Box, Kriz asked a question related to something I have been wanting to cover for some time:

Can you please shed some light on the inner workings of SHLoadIndirectString ()?

I'm trying to "MUI enable" some of my application and it looks like SHLoadIndirectString() plays a key role in understanding how language switching works in Windows (Explorer).

The documentation on MSDN ( is rather lacking especially the filename part of an indirect string and how the resource dlls should be named and I need to put those dlls.

I'll start by pointing out that at the moment, that link does not work. Just a residue of some pages moving around for some reason or another. But if you use this other SHLoadIndirectString link instead, you'll have much better luck.... :-)

Now when you look at MUI in terms of coverage, Windows 2000 claimed about 90% coverage if you look at most resources. The remaining 10%? As discussed in Question #4 of the MUI FAQ:

Much of the additional localized coverage in Windows XP is achieved through "MUI-enabling" Windows XP system modules and applications, specifically by:

  1. Transferring User Interface strings from the registry to Windows resource files.
  2. Removing User Interface strings from the kernel.
  3. Using the MUI-enabled shell to display localized strings for Start menu items, desktop shortcuts, shell menu items, file type names and shell verbs (shell's right-click menu items).
  4. Making Windows services impersonate the current interactive user instead of the system default when displaying User Interface.
  5. Barring the use of hard-coded file paths when loading resource files including help files, so that an alternate resource path can be used to load the resource file.
  6. Provide special code in each component to install and load the User Interface resource if a non traditional Win-32 resource is used (such as XML or HTML based resource)

Now item #1 was largely handled by taking hard-coded registry strings in the registry and changing them to a new format that allowed one to redirect the resource loading to a DLL somewhere (and the DLLs by supporting MUI can handle multiple different languages).

This format works quite well not only for SHLoadIndirectString but also for the new RegLoadMUIString in Vista as well (since SHLWAPI is a bit higher in the food chain than some callers needed it to be for items like time zones and since in most cases the strings were indeed stored in the registry, this new function was quite a useful addition!).

But their use is definitely not central to MUI.

They can be thought of as one of the crucial percentages of the last 10% of MUI. :-)

Whether a user would need either of these functions is not entirely clear though -- the only way either one would be needed was if you were storing resources in a non-MUI friendly format like in the registry or a text file or an INI/INF file, and you wanted to redirect that string load without re-architecting the application. Which is not the most common scenario for most applications.

One of the most common scenarios where one wants to avoid re-architecting things is when one has a backcompat requirement. However, as I hinted at in Sometimes when sorting the index is the last thing you want to use, there is often a cost to taking this approach.

For example, if you look at the keyboard layout names (migrated in XP to this indirect format and a SHLoadIndirectString call as I discussed here) or time zone names (migrated in Vista to this indirect format and a RegLoadMUIString call in Vista as I discussed here), you have to compare the two models:

A good example of such an application is older versions of Outlook, which used the time zone strings in their own UI:

Now suddenly in Vista, those strings which were previously localized into the initial install language of Windows (which sucks since they did not respect the user's UI language of either Windows or Office) were now always English (which sucks worse since they now respected neither the initial install language nor the user's UI language) -- unless they made a code change.

The code change is not unreasonable for new applications and/or new versions, but asking Outlook all the way back to Outlook 97 to change after the fact might cross the line of reasonable request.

But wait a moment -- before you think of poor innocent downlevel Outlook, keep in mind that these registry keys were never documented or supported, and they were therefore just hitching an illegal ride with Windows. Nothing would have kept them from doing their own localization efforts in this space other than the desire to avoid the extra maintenance of keeping the strings in sync with Windows, therefore an honest an unbiased assessment of that fact will change such apps in our eyes from innocent martyrs injured by the big bad Vista to cynical bastards who had been existing on borrowed time for far too many versions.

Now I will talk more about SHLoadIndirectString and RegLoadMUIString soon, as there is some interesting under-the-covers stuff to talk about there, too. :-)


This post brought to you by ไท˜and ๐’ (U+4dd8 and U+12041, a.k.a. HEXAGRAM FOR INNOCENCE and CUNEIFORM SIGN BAD)

no comments

Please consider a donation to keep this archive running, maintained and free of advertising.
Donate โ‚ฌ20 or more to receive an offline copy of the whole archive including all images.

go to newer or older post, or back to index or month or day