Tuesday, October 03, 2006

Single Worldwide Binary: What's the Problem?

It is commonly accepted that the best strategy to provide support multiple languages with one single EXE is to use resource DLLs (a.k.a. Satellite DLLs). By the way, generating such resource DLLs with appTranslator is as easy as filling one checkbox!
But why do we have to bother playing with a whole set of DLLs? After all, several translations of one given resource (such as a string or a menu) can easily be stored in a single EXE. And if you call SetThreadLocale() to select your language, voilà, your resources will be loaded in the expected language. Not!

SetThreadLocale() is not the solution

Once upon a time, there was Windows NT4 (and even, 3.51, 3.5,...). In these times, the single worldwide binary was a realistic option... as long as you didn't have to target Win9x, under which SetThreadLocale() was a no-no!Then came Windows 2000 and its vastly improved support for internationalization. Paradoxically, the single worldwide binary was no longer an option. Because one could no longer rely on SetThreadLocale() to globally select the language for resources, as the docs say:

Windows 2000/XP: Do not use SetThreadLocale to select a UI language. To select the proper resource that is defined with a LANGUAGE statement, use FindResourceEx.

Docs say 'don't touch!' but they don't say why. And if you try to look further, you won't find much info. As always, Michel Kaplan's blog is a good place to look up, even if it's to get confirmation that there's not much to find out.

Well, there are a few lines somewhere: This article briefly explains that when MUI was first introduced back in Windows 2000, the Microsofties had to modify the way resources are loaded (If you know why, please let me know). Actually, they modified the default language selection algorithm used to load resources :

The catch here is that if the thread locale is the same as the currently selected user locale, system’s resource loader will by default use the language ID 0 (neutral). If the desired resource is defined as a neutral language, then this value will be returned. Otherwise, all of the language resources will be enumerated (in language ID order) and the first matching resource ID – regardless of its language – will be returned.

In other words, Windows will not load resources the way you expect if you happen to ask for the same language as the user preference (user default locale)! Yikes! You don't believe me? Fair enough, me neither! :-) Let's make a test.

The Sample Program

  • The program contains a String Table with a string in German, French (Belgium) and English.
  • The program selects German as its default UI language : SetThreadLocale(German)
  • It then loads a string from the String Table(displayed in the message box title).

(Download source).

You expect the loaded string to be "German string". Play with you user locale and you'll see that the docs are unfortunately right.

Here is what I get with User Locale = French (Belgium): The german string is correctly loaded.

Then I modify my user locale and select German:

When I re-run the program, I still expect "German String" but I get something else :-(

What language does it pick then?

If you look carefully at the screenshots above, you might notice something weird: The docs (quoted above) say that in case of ThreadLocale==UserLocale, the language picked should be the first one in ID order, which for my program is... German! (German=0x407, French-Belgium =0x80C and English=0x409).So in this case, German should have been picked, as a side effect. But it was not: English was picked. How come?

I made further tests and it appears that when UserLocale==ThreadLocale, Windows tries to load the resources in its own UI language (even if it's different from User/Thread Locale). Anyway, this irrelevant since we just demonstrated that SetThreadLocale() cannot be trust to achieve the Single Worldwide Binary dream.

BTW, why would FindResourceEx help?

Remember the remark in the docs? Use resource DLLs or use FindResourceEx().

The reason FindResourceEx() would help is simply because it takes an explicit langiuage ID, as opposed to the most usual resource-loading APIs such as LoadString(), CreateDialog() et al. But it's not a realistic solution because it would mean that you must re-implement your own LoadString() et al using FindResourceEx().

No, you don't want to do that! So we'll keep with resource DLLs.


At 8:05 AM, Blogger Daniel said...

Thanks Serge, you did quite some research on that! What an eye-opener...

That's unbelievable. That's absolutely unbelievable!
This "new" resource lookup mechanisms really sound like a bug, but it seems they did it intentionally...

(BTW I do not agree to Michel Kaplan's litany about the idea of thread locales. I always found them quite natural in an environment where different threads can do security relevant actions on behalf of different (remote) users via impersonation. They may as well have to do resource-lookups on behalf of the very same different users.)

I just tested it on with my NetExec tool - same results as with your test app.
Interestingly, I have never got a single complaint that language selection in NetExec is not working. And we are talking about more than 15k installations.
Seems that the situation user-locale != winUI-locale is kind of uncommon, so the "fallback" [if (thread-locale == user-locale) then winUI-locale] "rescues" me.

At 9:27 PM, Anonymous Anonymous said...

I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!

Sorry for offtopic

At 12:06 PM, Anonymous Anonymous said...

[url=http://platinconne.freehostia.com/map.html]free movies download[/url] parampampam!

At 10:28 AM, Anonymous Anonymous said...

[url=http://ups.uoftpharmacy.com/aboutus/]Where Can I Buy Viagra[/url]

At 9:34 AM, Anonymous Anonymous said...

[b][url=http://pohudey.in]ХУДЕЙ БЕЗ ПРОБЛЕМ!![/url][/b]

молочная диета я похудела форум
быстрое похудение диеты лучшие
новая экспресс диета доктора агатстона
метод похудения монтиньяка скачать
как похудеть с помощью велотренажера
гречневая диета результат
квашенная капуста диета
аэробика для похудения видео онлайн
школа здорового питания
диета при заболеваниях желчного пузыря
похудеть с помощью сельдерея
журнал худеем правильно
диета по гликемическому индексу
похудеть за недельку
эфиктивные диеты
видео как быстро похудеть
таблетки для похудения линдекса
хронический гастрит диета
методы похудения
самая самая диета
корсет для похудения
методика похудения с помощью бадов
лишняя кожа после похудения
средства для похудения диеты
как заставить себя похудеть
вкусная диета
диета 45 плюс
простая диета
эффективная система похудения
убрать живот за 10 дней
препарат для похудения идеал отзывы
диетические рецепты для похудения
таблицами калорийности продуктов
варикозное расширение вен диета
правильное и здоровое питание
секрет похудения в одном стакане
диеты протасова
похудение на гречке
аллен карр аудиокнига как похудеть
способы похудения для ленивых
диета по дням
похудеть за 15 минут
правильное питание с чего начать
я похудела на 30 кг
правильное питание меню на неделю
анекдоты про похудение
похудение ног
25 кадр похудение торрент
как похудеть без диет дома
как не сорваться с диеты
бессолевая рисовая диета
диет система 30 плюс
100 способ похудения
здоровое спортивное питание
диета для снижения холестерина
диета на хлебе
100 способов похудеть
какие есть диеты
таблица калорийности продуктов по борменталю
методики похудения ямакиро
таблица роста и веса ребенка
правильное питание для котов
назарова елена дмитриевна похудение
кто сидел на рисовой диете
диета при гастродуодените
каллорийность продуктов таблица
конкура чай для похудения
кулинарные рецепты здоровое питание
книга владимира соловьева о похудении
эффективная экспресс диета
способы похудения для мужчин
похудение 25кадр скачать бесплатно
перловая диета
иога для похудения
помогает ли массаж похудеть
ален кар похудение
как сбросить вес за неделю
курс похудения бесплатно

[url=http://lengbadlipank.freehostia.com]как похудеть[/url]


Post a Comment

<< Home