您的位置:首页 > 其它

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐