Platform SDK: Debugging and Error Handling

Event Identifiers

Event identifiers uniquely identify a particular event. Each event source can define its own numbered events and the description strings to which they are mapped. Event viewers can present these strings to the user. They should help the user understand what went wrong and suggest what actions to take. Direct the description at users solving their own problems, not at administrators or support technicians. Make the description clear and concise and avoid culture-specific phrases.

The following sections discuss these description strings, and the insertion strings that serve as placeholders in the description strings.

Description Strings

The description strings in the event message file are indexed by event identifier, enabling Event Viewer to display event-specific text for any event based on the event identifier. All descriptions are localized and language dependent. The description strings may contain insertion string placeholders, of the form %n, where %1 indicates the first insertion string, and so on. For example, the following is a sample entry in the .MC file:

MessageId=0x4
Severity=Error
Facility=System
SymbolicName=MSG_CMD_DELETE
Language=English
File %1 contains %2, which is in error.

In this case, the buffer returned by ReadEventLog contains insertion strings. The NumStrings member of the EVENTLOGRECORD structure indicates the number of insertion strings. The StringOffset member of the EVENTLOGRECORD structure indicates the location of the first insertion string in the buffer.

The description string can also contain placeholders for parameter strings from the parameter message file. The placeholders are of the form %%n, where %%1 is replaced by the parameter string with the identifier of 1, and so on. In this case, the event viewer uses LoadLibraryEx and FormatMessage to retrieve the insertion string from the file indicated by the source's ParameterMessageFile registry value.

Insertion Strings

Insertion strings are optional language-independent strings used to fill in values for placeholders in description strings. Because the strings are not localized, it is critical that these placeholders be used only to represent language-independent strings such as numeric values, file names, user names, and so on. The string length must not exceed 32 kilobytes – 1 characters.

It is not acceptable to use several strings to create a larger description. The insertion string should be treated as data, not text. For example, the following example is not recommended:

LPSTR pszString1 = "successfully"; 
LPSTR pszString2 = "not"; 
LPSTR pszDescription = "The user was %1 added to the database."; 

It is not acceptable to use pszString1 and pszString2 to form the strings "The user was successfully added to the database." and "The user was not added to the database." There are three reasons this substitution is not effective:

In the following example, it is appropriate to use either pszString1 or pszString2 for the insertion string in pszDescription.

LPSTR pszString1 = "c:\\testapp1.c"; 
LPSTR pszString2 = "c:\\testapp2.c"; 
LPSTR pszDescription = "Access denied. Attempted to open the file %1."