Monday, August 18, 2008

Dynamically Changing Cultures and String Resources

I'm working on a project that allows the user to dynamically specify the language used in the UI. This can be set independent of the operating system language settings, and is immediately applied.

In our case, most of our strings are retrieved from resources using ResXFileCodeGeneratorEx tool-generated code. When the user switches the language, we simply set the application CurrentCulture and CurrentUICulture, and refresh the display.

However, I currently ran into an issue where a dialog box wasn't displaying text in the alternate languages. The localized text was in the resource, and everything should have been working as expected.

After a little digging, I realized that the dialog was being displayed in the context of another thread. I would have expected that the .Net framework thread initialization code would use the culture of the executing thread, but rather it defaults to the current OS culture. Subsequently, attempts to retrieve a localized string on that new thread would return text in current OS culture (English) -- not what was anticipated.

The solution was to simply set the Thread.CurrentUICulture (and Thread.CurrentCulture) properties to the values from the executing (main) thread:
thread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
thread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;

Thursday, August 14, 2008

Failed string.Format w/ Parameters using CJK

I recently ran into an issue in a localized application that was using the C# .Net Framework string.Format("blah-blah {0}", parm1).

In English, everything worked fine and as expected. However when using a localized format string (Japanese), the parameter substitution failed:

string.Format("数字は、{0}", parm1);

(If you don't have the necessary language pack installed, here is a image representation of the text: )

It turns out that the translated text was using different braces than 0x7B and 0x7D. In the translated text the left brace was 0xFF5B. Looks like a brace, but isn't for the purposes of string.Format. Further, in looking at the MS Mincho char set, I couldn't find that particular brace. Using the Alt+65371 trick for that character in notepad, I'd get a left bracket -- don't know what/where the brace comes from...

The simple fix was to change the 0xFF5B brace to the correct 0x7B, and then string.Format worked as expected.