How to correctly translate an error code into an error message
2011-06-30 20:09
330 查看
When you need to get the message corresponding to a system (Win32) error code, use the following:
//get the error code from the last function call
LONG err = ::GetLastError ();
//translate the error code into a message
void* p_text;
DWORD count = ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
err,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &p_text,
0,
NULL);
//...display / log the message in p_text buffer here
//free buffer
::LocalFree (p_text);
When you need to get the message corresponding to one of your own functions, replace the flag FORMAT_MESSAGE_FROM_SYSTEM in the first parameter with the flag FORMAT_MESSAGE_FROM_HMODULE and the second parameter from NULL to an actual handle (HMODULE) of the module that contains the message table with the error messages. This handle may be kept NULL if the error messages are contained within the calling process application file.
Note that the message table with your own error message is not the same with a string table resource. The message table is a special type of resource that must be added to the resources of a module using the Microsoft Message Compiler (mc.exe). Use the following steps to create a MESSAGETABLE resource:
1. Create a text file (e.g. MyMessages.mc) with the actual messages corresponding to error codes in your code. For example:
; // MyMessages.mc
; // Header defining the Severities, Facilities and Languages
MessageIdTypedef=LONG
SeverityNames=
(
Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)
FacilityNames=
(
Application=0x0:FACILITY_APPLICATION
Libraries=0x1:FACILITY_LIBRARIES
Network=0x2:FACILITY_NETWORK
)
LanguageNames=(English=0x409:MSG00409)
; //Add other language definitions here
; //Actual message definitions (add Language=...,
; //then the text on next line, then . on the next line for
; //translations in other languages
MessageId=0x1
Severity=Error
Facility=Application
SymbolicName=GM_APP_MSG_OPERATION_FAILED
Language=English
The operation you have chosen failed.
.
2. Compile this file through the message compiler:
mc.exe -U MyMessages.mc
If your .mc file is Unicode, also add the –u switch to the mc.exe command line. The –U switch forces the output to be Unicode (even is the .mc file used as input is not).
This produces the files: MyMessages.h, MyMessages.rc, MSG00409.bin (there may be more .bin files, one for each language defined in the header of the .mc text file).
The header file (MyMessages.h) defines the symbolic constants for the error codes (so that you can include this header in you code and refer to the error codes as symbolic constants – unfortunately they are defined as macros so you may run into collisions, so use symbolic names that reduce that chance in the .mc file, e.g.: SymbolicName=GM_APP_MSG_OPERATION_FAILED.
The .bin files are binaries containing the compiled text messages in a particular language (there is one .bin file per each language defined in the header of the .mc file).
The .rc file is a standard resource file that must be included in the .rc file of the module you want to contain the error messages. It simply forces the .rc file to include the .bin file(s) with the compiled messages.
3. Include the .rc file resulted from above into the module’s .rc file:
#include "MyMessages.rc"
4. Use code similar to the one below to retrieve your message:
//user-defined error code
LONG err = GM_APP_MSG_OPERATION_FAILED;
void* p_text;
DWORD count = ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
err,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &p_text,
0,
NULL);
//...display / log the message in p_text buffer here
//free buffer
::LocalFree (p_text);
//get the error code from the last function call
LONG err = ::GetLastError ();
//translate the error code into a message
void* p_text;
DWORD count = ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
err,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &p_text,
0,
NULL);
//...display / log the message in p_text buffer here
//free buffer
::LocalFree (p_text);
When you need to get the message corresponding to one of your own functions, replace the flag FORMAT_MESSAGE_FROM_SYSTEM in the first parameter with the flag FORMAT_MESSAGE_FROM_HMODULE and the second parameter from NULL to an actual handle (HMODULE) of the module that contains the message table with the error messages. This handle may be kept NULL if the error messages are contained within the calling process application file.
Note that the message table with your own error message is not the same with a string table resource. The message table is a special type of resource that must be added to the resources of a module using the Microsoft Message Compiler (mc.exe). Use the following steps to create a MESSAGETABLE resource:
1. Create a text file (e.g. MyMessages.mc) with the actual messages corresponding to error codes in your code. For example:
; // MyMessages.mc
; // Header defining the Severities, Facilities and Languages
MessageIdTypedef=LONG
SeverityNames=
(
Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)
FacilityNames=
(
Application=0x0:FACILITY_APPLICATION
Libraries=0x1:FACILITY_LIBRARIES
Network=0x2:FACILITY_NETWORK
)
LanguageNames=(English=0x409:MSG00409)
; //Add other language definitions here
; //Actual message definitions (add Language=...,
; //then the text on next line, then . on the next line for
; //translations in other languages
MessageId=0x1
Severity=Error
Facility=Application
SymbolicName=GM_APP_MSG_OPERATION_FAILED
Language=English
The operation you have chosen failed.
.
2. Compile this file through the message compiler:
mc.exe -U MyMessages.mc
If your .mc file is Unicode, also add the –u switch to the mc.exe command line. The –U switch forces the output to be Unicode (even is the .mc file used as input is not).
This produces the files: MyMessages.h, MyMessages.rc, MSG00409.bin (there may be more .bin files, one for each language defined in the header of the .mc text file).
The header file (MyMessages.h) defines the symbolic constants for the error codes (so that you can include this header in you code and refer to the error codes as symbolic constants – unfortunately they are defined as macros so you may run into collisions, so use symbolic names that reduce that chance in the .mc file, e.g.: SymbolicName=GM_APP_MSG_OPERATION_FAILED.
The .bin files are binaries containing the compiled text messages in a particular language (there is one .bin file per each language defined in the header of the .mc file).
The .rc file is a standard resource file that must be included in the .rc file of the module you want to contain the error messages. It simply forces the .rc file to include the .bin file(s) with the compiled messages.
3. Include the .rc file resulted from above into the module’s .rc file:
#include "MyMessages.rc"
4. Use code similar to the one below to retrieve your message:
//user-defined error code
LONG err = GM_APP_MSG_OPERATION_FAILED;
void* p_text;
DWORD count = ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
err,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &p_text,
0,
NULL);
//...display / log the message in p_text buffer here
//free buffer
::LocalFree (p_text);
相关文章推荐
- How to release an unmanaged library loaded into managed .NET code
- 1. Introduce how to import the Spring Framework sourcecode into an eclipse project 【analyze spring framework source 】
- Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
- How to throw an error in MySql procedure?
- How to import the Spring Framework sourcecode into Eclipse
- Translating SQLException with SQL state '42000', error code '1064', message [You have an error in yo
- Question 29: The C++ code below generates a compiler error. Which of the following solutions can be used to correctly access the
- LR:接口性能测试时提示:Code-29723 Error: Failed to deliver a p2p message from parent to child process, reason
- How to export Gobla Address List (GAL) into an Excel file for Outlook 2010
- How to freeze a dynamic aspx page into a static html page (on the server).(转:http://codebetter.com/blogs/peter.van.ooijen/archiv
- How to sort an array of hashes into hashes with multiple values for a key?
- All-In-One Code Framework(AIO): 如何使用C#编写进程外的COM组件 (How to write an out-of-proc COM server in C#)
- [转]How to solve SSIS error code 0xC020801C/0xC004700C/0xC0047017
- HOWTO: How to Use PeekMessage() Correctly in Windows
- how to resolve the error message "Error reading Win32 manfest file"
- How to find error message from OMS repository
- How to compile a TCL script into an EXE program
- .SQLErrorCodeSQLExceptionTranslator - Unable to translate SQLException with Error code '0', will no
- 转:How to troubleshoot Enterprise Portal error ”Unable to render content due to an error. Please contact your system administrator."
- There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance