Re: Internationalizing an app
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sat, 02 Dec 2006 18:54:58 -0500
See below...
On Sat, 02 Dec 2006 13:23:11 -0800, flect <flect@xxxxxxx> wrote:
Tom Serface wrote:****
If you are using RC files and MFC this is the easiest way to do it:
http://msdn2.microsoft.com/en-gb/library/8fkteez0(VS.80).aspx
Basically, you have the default values in your native language (I use
English although you'd never know it from my posts at times). Then, you get
the translations done and a separate .RC file created for each. Create a
DLL project (according to the way described in the link) and load that DLL
based on the locale where the user is running the software. I use something
like:
//
// Creates a resource file name (for a DLL) given the locale id and a format
string.
//
CString GetResourceFilename(UINT nLID, LPCTSTR cFormat)
{
CString csHex, cs;
nLID = MAKELANGID(nLID&0xff, SUBLANG_DEFAULT);
csHex.Format(_T("%04x"), nLID);
cs.FormatMessage(cFormat,csHex);
return cs;
}
LCID lcid = ::GetThreadLocale();
lcid = LANGIDFROMLCID(lcid);
CString csResourceDLL;
csResourceDLL = GetResourceFilename(lcid, _T("MyApp%1.dll"));
GetResourceFileName? The only reference I can find is something which is part of .NET and
takes a CultureInfo * pointer, not an LCID and an LPCTSTR.
What I provided for in several apps was asking for the three-letter LOCALE_SABBREVLANGNAME
as part of the DLL, e.g., a DLL called LocaleENU.DLL for U.S. English. Why you are
creating an lcid by throwing away a critical component of it (the sublang ID), and why you
are presuming you know that &0xff is a meaningful operation on an lcid, escapes me.
An LCID is 32 bits. Bits 9..0 are the language ID, and bits 15..10 are the sublanguage.
So you are discarding two of the language ID bits by this masking (it really helps if you
read the documentation), and for that matter, you are discarding the sort ID as well. This
seems an odd thing to do. Perhaps you meant to write
lcid = MAKELANGID(PRIMARYLANGID(lcid), SUBLANG_DEFAULT);
which still doesn't make any logical sense (discarding the sublang ID) but at least
doesn't throw away critical parts of the language ID it is extracting.)
For example, by throwing away the sublanguage, you make all 13 versions of English, 5
versions of German, 6 versions of French, 16 versions of Arabic, 2 versions of Norse, 2
versions of Portugeuse, 9 versions of Sami, 3 versions of Serbian, 20 versions of Spanish,
2 versions of Urdu and 2 versions of Uzbek lose their identities. I'm sure that the
people who uses the various dialects of these languages will find this less than ideal, to
say the least. Why do you think the various users of the local dialects of these
languages should be disenfranchised? Note that in some cases wars have been fought over
the correct dialects to use (just ask a Quebecois if those barbarians from across the
Atlantic speak French, or vice-versa). Yet you have written code that, had it been
written correctly, thinks that colour and color don't make any difference! ARGH!
****
****lcid = MAKELANGID(lcid&0xff, SUBLANG_DEFAULT);
As soon as you write the code below, you lose. There are dozens of locales and languages
supported, [Locale Explorer lists 168 locales on my version of XP] and you seem to have
homed in on six. A properly localized app would have NO such code in it; it would adapt
itself to ANY of the supported languages of Windows. Any "event logging" would be based
on retrieving the appropriate strings via the appropriate APIs and displaying those
strings in an appropriate fashion.
I wrote the entire Locale Explorer without a single line of code like you show below.
****
Joseph M. Newcomer [MVP]switch(lcid) {
case 0x0409:
LogEvent(VERSION_ENGLISH);
break;
case 0x0407:
LogEvent(VERSION_GERMAN);
break;
case 0x040a:
LogEvent(VERSION_SPANISH);
break;
case 0x040c:
LogEvent(VERSION_FRENCH);
break;
case 0x0410:
LogEvent(VERSION_ITALIAN);
break;
case 0x0411:
LogEvent(VERSION_JAPANESE);
break;
}
m_hInstResDLL = ::LoadLibrary(csResourceDLL);
if(m_hInstResDLL != NULL)
AfxSetResourceHandle(m_hInstResDLL);
else
LogEvent("Default to English");
HTH,
Tom
"flect" <flect@xxxxxxx> wrote in message
news:uSaMm%23kFHHA.1816@xxxxxxxxxxxxxxxxxxxxxxx
I have never before attempted to internationalize an application.
The current plan (which I frankly dreamed up) involves creating a unicode
xml file with a placeholder for all user interface elements, that the user
can optionally load. The idea being that a user can edit the xml file to
their tastes, regardless of language or region.
Is there a better/easier way?
That is the tradidional way, but it means I have to do every
translation. With the xml route, anybody can do it.
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Internationalizing an app
- From: Tom Serface
- Re: Internationalizing an app
- References:
- Internationalizing an app
- From: flect
- Re: Internationalizing an app
- From: Tom Serface
- Re: Internationalizing an app
- From: flect
- Internationalizing an app
- Prev by Date: Re: No border on dynamically created CListCtrl in W2K (fine on XP)
- Next by Date: Re: No border on dynamically created CListCtrl in W2K (fine on XP)
- Previous by thread: Re: Internationalizing an app
- Next by thread: Re: Internationalizing an app
- Index(es):
Relevant Pages
|