tags:

views:

1360

answers:

5

I have a MFC application in which I want to add internationalization support. The project is configured to use the "multi-byte character set" (the "unicode character set" is not an option in my situation).

Now, I would expect the CWnd::OnChar() function to send me multi-byte characters if I set my keyboard to some foreign language, but it doesn't seem to work that way. The OnChar() function always sends me a 1-byte character in its nChar variable.

I thought that the _getmbcp() function would give me the current code page for the application, but this function always return 0.

Any advice would be appreciated.

+2  A: 

And help here? Multibyte Functions in Microsoft C Run-time

boost
Well, I was hoping that changing the keyboard local would automatically change the code page in my application. Is my assumption wrong? Do we really have to always set the code page manually? If so, how do we make the code page fit the keyboard layout?
Martin Cote
Changing the keyboard layout changes the values or the meanings of the values (i.e. which characters are which) that are sent from the keyboard. Each byte is a numeric value. The application interprets values according to the application's code page.
Windows programmer
Ok, that's what I was afraid of.
Martin Cote
+1  A: 

As far as changing the default code page:

The default code page for a user (for WinXP - not sure how it is on Vista) is set in the "Regional and Languages options" Control Panel applet on the "Advanced" tab.

The "Language for non-Unicode programs" sets the default code page for the current user. Unfortunately it does not actually tell you the codepage number it's configuring - it just gives the language (which might be further specified with a region variant). This meakes sense from an end-user perspective, because I think codepage numbers have no meaning to 99.999% of end users. You need to reboot for a change to take effect. If you use regmon to determine what changes you could probably come up with something that specifies the default codepage somewhat easier.

Microsoft also has an unsupported utility, AppLocale, for testing localization that changes the codepage for particular applications: http://www.microsoft.com/globaldev/tools/apploc.mspx

Also you can change the code page for a thread by calling SetThreadLocale() - but you also have to call the C runtime's setlocale() function because some CRT functions don't talk to the Win API locale functions (and vice versa). See "Windows SetThreadLocale and CRT setlocale" by Chris Grimes for details.

Michael Burr
+1  A: 

For _getmbcp, MSDN says "A return value of 0 indicates that a single byte code page is in use." That sure makes it not very useful. Try one of these: GetUserDefaultLCID GetSystemDefaultLCID GetACP. (Now why is there no "user" equivalent for GetACP?)

Anyway if you want _getmbcp to return an actual value then set your system default language to Chinese, Japanese, or Korean.

Windows programmer
+1  A: 

As always in non Unicode scenarios, you'll get a reliable result only if the system locale (aka in Control Panel "language for non-unicode applications") is set accordingly. If not, don't expect anything good.

For example, if system locale is Chinese Traditional, you'll receive 2 successive WM_CHAR messages (One for each byte, assuming user composed a 2-char character).

isleadbyte() should help you determine if a 2nd byte is coming soon.

If your system locale is NOT set to Chinese, don't expect to receive correct messages even iusing a Chinese keyboard/IME. The misleading part is that some scenarios work. e.g. using a Greek keyboard, you'll receive WM_CHAR char values based of the Greek codepage even if your system locale is Latin-based. But you should really stay away from trying to cope with such scenarios: Success is not guaranteed and will likely vary according to Windows version and locale.

As MikeB wrote, MS AppLocale is your friend to make basic tests.

[ad] and appTranslator is your friend if you need to translate your UI [/ad]

Serge - appTranslator
A: 

There is actually a very simple (but weird) way of force the OnChar function to send unicode characters to the application even if it's configured in multi-byte character set:

SetWindowLongW( m_hWnd, GWL_WNDPROC, GetWindowLong( m_hWnd, GWL_WNDPROC ) );

Simply by calling the unicode version of "SetWindowLong", it forces the application to receive unicode characters.

Martin Cote