Discussion:
Forcing FormatMessage to use English (us)
(too old to reply)
Vinzenz Feenstra
2006-07-21 23:26:41 UTC
Permalink
Hi,

I'm trying to force FormatMessage to use us-english. Since the PSDK says:
<quote PSDK FormatMessage Docs>
If you pass a specific LANGID in this parameter, FormatMessage will
return a message for that LANGID only. If the function cannot find a
message for that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If
you pass in zero, FormatMessage looks for a message for LANGIDs in the
following order:

1. Language neutral
2. Thread LANGID, based on the thread's locale value
3. User default LANGID, based on the user's default locale value
4. System default LANGID, based on the system default locale value
5. US English
</quote>

So what the heck is going on that I don't get US English if I use the
US-English LANGID (0x409 taken from the PSDK Docs as well)

Has anyone an idea if it is possible, at all?

If not, I would have to use only error codes for my logging stuff.
:/

(I don't want to ask a customer for logs and he sends me the logs and
the messages are chinese or something *fg* ^^)

Thanks.

Regards,

Vinzenz
William DePalo [MVP VC++]
2006-07-21 23:41:23 UTC
Permalink
Post by Vinzenz Feenstra
So what the heck is going on that I don't get US English if I use the
US-English LANGID (0x409 taken from the PSDK Docs as well)
What happens if you use this for the language identifier

MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) ?

Does it return an error? Which?

Regards.
Will
Vinzenz Feenstra
2006-07-21 23:59:51 UTC
Permalink
Post by William DePalo [MVP VC++]
Post by Vinzenz Feenstra
So what the heck is going on that I don't get US English if I use the
US-English LANGID (0x409 taken from the PSDK Docs as well)
What happens if you use this for the language identifier
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) ?
Does it return an error? Which?
Hi,

That is the strange thing.

My Windows is Microsoft Windows XP SP2 German and the results are following:

LANGID: 0x409
FormatMessage returns: 0
GetLastError returns: 0
(Message empty, as indicated by the FormatMessage return value)

LANGID: MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)
FormatMessage returns: 0
GetLastError returns: 0
(Message empty, as indicated by the FormatMessage return value)

LANGID: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
FormatMessage returns: Length of string e.g. 19
GetLastError return: 0
(German Message)

LANGID: MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
FormatMessage returns: Length of string e.g. 19
GetLastError return: 0
(German Message)

LANGID: MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)
FormatMessage returns: Length of string e.g. 19
GetLastError return: 0
(German Message)


You see that is really strange. Is it maybe a bug in Windows?

Regards,
Vinzenz
Vinzenz Feenstra
2006-07-22 00:05:02 UTC
Permalink
Btw I have tried MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) instead of
0x409 too, but it is the same result as I use 0x409
=> Empty String & No Error Code

Regards,
William DePalo [MVP VC++]
2006-07-22 01:57:04 UTC
Permalink
Post by Vinzenz Feenstra
You see that is really strange. Is it maybe a bug in Windows?
Anything is possible. I remain skeptical. Though to be perfectly honest, I
have no experience using anything but an English edition of Windows.

Why not post the code that calls FormatMessage() here?

Regards,
Will
Vinzenz Feenstra
2006-07-22 02:42:53 UTC
Permalink
Post by William DePalo [MVP VC++]
Post by Vinzenz Feenstra
You see that is really strange. Is it maybe a bug in Windows?
Anything is possible. I remain skeptical. Though to be perfectly honest, I
have no experience using anything but an English edition of Windows.
Why not post the code that calls FormatMessage() here?
Regards,
Will
That's the code:

LANGID langid = 0x409;
int errorcode = 5; // Access Denied for testing purposes
wchar_t msgbuf[1024] = {0};
int ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errcode, langid, msgbuf, 1024, 0);
wprintf(L"FormatMessage returns: %i\nGetLastError returns:
%i\n",ret,GetLastError());


Regards,
Vinzenz
William DePalo [MVP VC++]
2006-07-22 15:30:59 UTC
Permalink
Post by Vinzenz Feenstra
LANGID langid = 0x409;
int errorcode = 5; // Access Denied for testing purposes
wchar_t msgbuf[1024] = {0};
int ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errcode, langid, msgbuf, 1024, 0);
%i\n",ret,GetLastError());
I tried it here where English is the default language and it worked as
expected of course.

I'm sorry to say that I don't know what to tell you. But then I don't know
anything about "internationalization".

Regards,
Will
Eman
2006-07-22 15:53:36 UTC
Permalink
Post by William DePalo [MVP VC++]
Post by Vinzenz Feenstra
LANGID langid = 0x409;
int errorcode = 5; // Access Denied for testing purposes
wchar_t msgbuf[1024] = {0};
int ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errcode, langid, msgbuf, 1024, 0);
%i\n",ret,GetLastError());
I tried it here where English is the default language and it worked as
expected of course.
I'm sorry to say that I don't know what to tell you. But then I don't know
anything about "internationalization".
It seems FormatMessage takes error-code expansions from the
KERNEL32.DLL message resource table (mostly). If the system
is localized, there are no English messages there.
Jochen Kalmbach [MVP]
2006-07-22 17:30:18 UTC
Permalink
Hi Vinzenz!

English messages can only be retrived on a MUI OS!
Otherwise only the "localized" error messages are installed...
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Vinzenz Feenstra
2006-07-22 20:12:42 UTC
Permalink
Post by Jochen Kalmbach [MVP]
Hi Vinzenz!
English messages can only be retrived on a MUI OS!
Otherwise only the "localized" error messages are installed...
Hi Jochen ;)

That explains the behaviour. Thank you :)

Regards,
Vinzenz
Eugene Gershnik
2006-07-22 21:35:57 UTC
Permalink
Post by Vinzenz Feenstra
Post by Jochen Kalmbach [MVP]
Hi Vinzenz!
English messages can only be retrived on a MUI OS!
Otherwise only the "localized" error messages are installed...
Hi Jochen ;)
That explains the behaviour. Thank you :)
LANGID: MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)
FormatMessage returns: 0
GetLastError returns: 0
(Message empty, as indicated by the FormatMessage return value)
If this is really what happens then FormatMessage has a bug on your system.
If the relevant tables are not present it is supposed to set
ERROR_RESOURCE_LANG_NOT_FOUND, not silently fail with an empty string as a
result. See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/formatmessage.asp
for details.
--
Eugene
http://www.gershnik.com
Sam Hobbs
2006-07-22 20:08:27 UTC
Permalink
Post by Vinzenz Feenstra
int ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errcode, langid, msgbuf, 1024, 0);
%i\n",ret,GetLastError());
Don't call GetLastError in the wprintf call; call GetLastError as soon as
possible. It is useless to call GetLastError if any other function is called
before it that sets the error code. Of course, you probably know all that
already and just did not realize that wprintf can be using many Windows API
functions.

That might not make a difference, but my guess is that it will and it is
good practice to always call GetLastError as soon as possible.

Note that GetLastError is not useful unless FormatMessage returns 0. I think
the documentation does not specify what GetLastError returns if
FormatMessage returns a non-zero value. However according to the
documentation, if there are no bytes or characters stored in the output
buffer then GetLastError should return an error code. The fact that you are
getting zero from both FormatMessage and GetLastError should be an
indication that you are overlooking something.
Eugene Gershnik
2006-07-22 21:41:39 UTC
Permalink
Post by Sam Hobbs
Post by Vinzenz Feenstra
int ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errcode, langid, msgbuf, 1024, 0);
%i\n",ret,GetLastError());
Don't call GetLastError in the wprintf call; call GetLastError as
soon as possible. It is useless to call GetLastError if any other
function is called before it that sets the error code.
And what do you think is being called between FormatMessage and GetLastError
in this case?
Post by Sam Hobbs
Of course, you
probably know all that already and just did not realize that wprintf
can be using many Windows API functions.
What it can be using is irrelevant. As any introductory C text will explain
to you function arguments are evaluated before the call is made.
--
Eugene
http://www.gershnik.com
Sam Hobbs
2006-07-22 23:29:46 UTC
Permalink
Post by Eugene Gershnik
What it can be using is irrelevant. As any introductory C text will
explain to you function arguments are evaluated before the call is made.
Yes, I did not think that through.

However the symptoms can be explained if there is something else being
called after FormatMessage and before GetLastError. Isn't that much more
likely than a bug in the system?
Eugene Gershnik
2006-07-24 05:57:27 UTC
Permalink
Post by Sam Hobbs
However the symptoms can be explained if there is something else being
called after FormatMessage and before GetLastError. Isn't that much
more likely than a bug in the system?
Could be. OTOH the OP was asked to provide his code and assuming he posted
the real version it does apper to indicate a bug in the API.
--
Eugene
http://www.gershnik.com
Mihai N.
2006-07-22 04:15:35 UTC
Permalink
Post by Vinzenz Feenstra
<quote PSDK FormatMessage Docs>
If you pass a specific LANGID in this parameter, FormatMessage will
return a message for that LANGID only. If the function cannot find a
message for that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If
you pass in zero, FormatMessage looks for a message for LANGIDs in the
1. Language neutral
2. Thread LANGID, based on the thread's locale value
3. User default LANGID, based on the user's default locale value
4. System default LANGID, based on the system default locale value
5. US English
</quote>
So what the heck is going on that I don't get US English if I use the
US-English LANGID (0x409 taken from the PSDK Docs as well)
Has anyone an idea if it is possible, at all?
If the OS is not English, probably normal.
I suspect step 5 shuld not say "US English" but "UI language of the system"
Localized systems do not "carry" with them English messages, just the
localized ones.
Post by Vinzenz Feenstra
If not, I would have to use only error codes for my logging stuff.
:/
(I don't want to ask a customer for logs and he sends me the logs and
the messages are chinese or something *fg* ^^)
Part of the log is also the message number. You can extract it and use it to
retrieve the English message.
One think I allways recomend is something like "Error 234234: corupted
tagadum in tagadom". Looks geeky but is useful.
--
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
Vinzenz Feenstra
2006-07-22 09:01:09 UTC
Permalink
Post by Mihai N.
Post by Vinzenz Feenstra
<quote PSDK FormatMessage Docs>
If you pass a specific LANGID in this parameter, FormatMessage will
return a message for that LANGID only. If the function cannot find a
message for that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If
you pass in zero, FormatMessage looks for a message for LANGIDs in the
1. Language neutral
2. Thread LANGID, based on the thread's locale value
3. User default LANGID, based on the user's default locale value
4. System default LANGID, based on the system default locale value
5. US English
</quote>
So what the heck is going on that I don't get US English if I use the
US-English LANGID (0x409 taken from the PSDK Docs as well)
Has anyone an idea if it is possible, at all?
If the OS is not English, probably normal.
I suspect step 5 shuld not say "US English" but "UI language of the system"
Localized systems do not "carry" with them English messages, just the
localized ones.
Post by Vinzenz Feenstra
If not, I would have to use only error codes for my logging stuff.
:/
(I don't want to ask a customer for logs and he sends me the logs and
the messages are chinese or something *fg* ^^)
Part of the log is also the message number. You can extract it and use it to
retrieve the English message.
One think I allways recomend is something like "Error 234234: corupted
tagadum in tagadom". Looks geeky but is useful.
Hi Mihai,
In my log/error file there is the Sourcefile name, the line number, a
private comment (of course in english), the Errorcode and I wanted to
add the FormatMessage, because I am lazy and won't look up all the codes ;)

However thanks for your reply :)
Regards,
Vinzenz
--
Regards,
Vinzenz Feenstra

And now visit my WeBlog < http://blog.evilissimo.net > ;)
Mihai N.
2006-07-23 04:11:39 UTC
Permalink
Post by Vinzenz Feenstra
Hi Mihai,
In my log/error file there is the Sourcefile name, the line number, a
private comment (of course in english), the Errorcode and I wanted to
add the FormatMessage, because I am lazy and won't look up all the codes ;)
It was not clear who produces the log, thought is about something part of the
system.

Sure, if it it produced by your application and you application is English
only, all log errors will be English.
But from your answer here:
-----------
LANGID: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
FormatMessage returns: Length of string e.g. 19
GetLastError return: 0
(German Message)
-----------
my understanding was that German messages are available.

So, if you are looking to retrieve English messages of system components on
German system, it is not possible (unless it is in fact English system with
German MUI).
If you are looking to retrieve English messages of YOUR components on German
system, then you will get what your component has (English, German, Thai,
your decision :-)
--
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
Loading...