Thread: FormatMessage to a different language

  1. #1
    A source of questions... Benji Wiebe's Avatar
    Join Date
    Mar 2011
    Location
    Durham, Kansas
    Posts
    69

    Thumbs down FormatMessage to a different language

    Why does this not work?
    Code:
    FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_AFRIKAANS, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
    I want it to use a different language.
    But it puts (null) into the lpMsgBuf.
    Ever notice how fast Windows runs?
    Neither did I.
    Which is why I switched to Linux.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    This is not a translation function... it is part of Windows error reporting mechanism that reads a messagetable resource from your executable file and formats the error message into a string.

    With the FORMAT_MESSAGE_FROM_SYSTEM flag, to format a message (short for "Windows Error Message") in afrikans you will need to have a message table resource in your executable or DLL that contains both a section for afrikaans and the numerically indexed message itself in the correct format. Also be aware that this flag causes a sequence of searching the current module (exe or dll) then a series of system resources... collision in error codes can produce some very bizarre results.

    Very few IDEs include Message Table editors and I've never found a free standing one so you will have to read up on it here then create and compile them manually using MC.EXE. (The only IDE I know that includes a Message Table editor is POIDE supplied with Pelles C )

    Other options to format message allow you to use it with source strings in memory which may or may not make things easier for you.

    Also note that if you need to print characters outside the normal 127 ASCII characters you will need to do all of this using Unicode... Which you can believe is no picnic for programmers...

    FormatMessage function (Windows)
    Quote Originally Posted by MSDN Library
    Formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.

    EDIT... If it helps here is an error reporting function I wrote as part of an SEH library using FormatMessage()...
    Code:
    #include <errorx.h>
    #include <wchar.h>
    
    ////////////////////////////////////////////////////////////////
    // Error text lookup array
    //
    #pragma pack(1)
    typedef struct MsgText
              { unsigned long code;
                wchar_t       msg[60]; }
              MessageText;
    
    const MessageText Message[] =
      { EXCEPTION_ACCESS_VIOLATION, 
        L"Access violation: protected system resources",
        EXCEPTION_DATATYPE_MISALIGNMENT, 
        L"A data type misalignment has caused system errors",
        EXCEPTION_BREAKPOINT,
        L"A breakpoint has been reached while debugging",
        EXCEPTION_SINGLE_STEP,  
        L"Single stepping  mode while debugging",
        EXCEPTION_ARRAY_BOUNDS_EXCEEDED,
        L"Array access outside of allocated memory",
        EXCEPTION_FLT_DENORMAL_OPERAND,
        L"Floating point error, bad demoromal operand",
        EXCEPTION_FLT_DIVIDE_BY_ZERO, 
        L"Floating point error, attempting to divide by zero",
        EXCEPTION_FLT_INEXACT_RESULT,
        L"Floating point error, inexact result",
        EXCEPTION_FLT_INVALID_OPERATION,
        L"Floating point error, invalid operation attempted",
        EXCEPTION_FLT_OVERFLOW, 
        L"Floating point error, operation caused an overflow",
        EXCEPTION_FLT_STACK_CHECK,
        L"Floating point error, FPU stack corrupted",
        EXCEPTION_FLT_UNDERFLOW,
        L"Floating point error, operation caused an underflow",
        EXCEPTION_INT_DIVIDE_BY_ZERO, 
        L"Integer math error, attempted to divide by zero",
        EXCEPTION_INT_OVERFLOW,
        L"Integer math error, operation caused an overflow",
        EXCEPTION_PRIV_INSTRUCTION,
        L"An attempt was made to execute priveledged instructions",
        EXCEPTION_IN_PAGE_ERROR, 
        L"Memory page protection error",
        EXCEPTION_ILLEGAL_INSTRUCTION,
        L"An attempt was made to execute unknown CPU instructions",
        EXCEPTION_NONCONTINUABLE_EXCEPTION,
        L"Too many nested exceptions have occured",
        EXCEPTION_STACK_OVERFLOW,
        L"Stack overflow",
        EXCEPTION_INVALID_DISPOSITION, 
        L"An invalid disposition error has occured",
        EXCEPTION_GUARD_PAGE, 
        L"Invalid guard page",
        EXCEPTION_INVALID_HANDLE, 
        L"Invalid system handle",
        STATUS_NO_MEMORY,
        L"Out of memory",
        CONTROL_C_EXIT,
        L"A keyboard exit has been requested", 
        0xFFFFFFFF,
        L"No text description is available for this error" };
    
    
    /////////////////////////////////////////////////////////////////////
    // Fetch Windows error string
    // 1. Searches MessageTable resources for error text matching errcode
    // 2. Result is placed at errtext which must be at least MAX_PATH bytes.
    // 2. width = right margin, 0 = no right margin 
    //
    
    void WINAPI GetErrorTextW(unsigned long errcode, wchar_t *errtext, int width) 
      { // fetch the current module's handle
        HMODULE hmod = GetModuleHandle(NULL);
        // locate the message in the local message table   
        if (FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | width,
                        hmod,errcode,0,errtext,256,NULL))
          return; 
        // try the system list                   
        if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | width,
                        NULL,errcode,0,errtext,256,NULL))
          return;
        // now the internal table
        int x = 0;
        while ((Message[x].code != errcode) & 
                (Message[x].code != 0xFFFFFFFF))
          { x++; }
        FormatMessageW(FORMAT_MESSAGE_FROM_STRING | width,
                      Message[x].msg,0,0,errtext,256,NULL); }
    Last edited by CommonTater; 09-14-2011 at 11:31 AM.

  3. #3
    A source of questions... Benji Wiebe's Avatar
    Join Date
    Mar 2011
    Location
    Durham, Kansas
    Posts
    69
    Too bad it can not spit out windows error messages in other languages.
    Ever notice how fast Windows runs?
    Neither did I.
    Which is why I switched to Linux.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Benji Wiebe View Post
    Too bad it can not spit out windows error messages in other languages.
    It can... but they have to exist someplace in your system's resources... either your own program, in a system language resource, or strings in memory.

    Think about the enormous bloat in windows (as though it's not bad enough already) to have a translator function for every language...

    FWIW... the underpinning here is sprintf()... all it does is format message text into a string.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Localization is usually done via string tables. The string table is a resource in your DLL or EXE and is put into the resources section so it can be loaded later. MSVS does have a string table resource editor but I have not used it much.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by VirtualAce View Post
    Localization is usually done via string tables. The string table is a resource in your DLL or EXE and is put into the resources section so it can be loaded later. MSVS does have a string table resource editor but I have not used it much.
    Yes, for general strings that's true... but windows error messages are all done through message tables....

    MESSAGETABLE resource (Windows)

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes, for general strings that's true... but windows error messages are all done through message tables....
    Alas, I am not the man to turn to for localization.

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by VirtualAce View Post
    Alas, I am not the man to turn to for localization.
    The "other language" error messages are generally included in the language modules you can add to Windows Professional (or better) in versions since XP...
    You access them either by specifying a language option or changing Locale settings in control panel.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is C++ or C language is a high Level language?
    By uthmankhale in forum C++ Programming
    Replies: 5
    Last Post: 08-25-2011, 06:00 PM
  2. What's the Difference Between a Programming Language and a Scripting Language?
    By Krak in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 07-15-2005, 04:46 PM
  3. C Language And A Scripting Language
    By DarkSpy in forum C Programming
    Replies: 9
    Last Post: 06-26-2003, 08:05 AM
  4. Language
    By nvoigt in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 04-29-2002, 02:28 PM
  5. Computer Language VS Spoken Language
    By Isometric in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 02-04-2002, 03:47 PM