MSGTEST.C

/* Microsoft Developer Support 
Copyright 1992 - 1998 Microsoft Corporation */

#include <windows.h>
#include <stdio.h>

/* messages.h is created by mc.exe when compiling messages.mc */
#include "messages.h"

#define MAX_MESSAGES 5
#define MAX_MSG_LENGTH 1024
#define SEVERITY_MASK 0xC0000000
#define FACILITY_MASK 0x0FFF0000
#define MSG_ID_MASK 0x0000FFFF


/********************************************************************
* FUNCTION: myPutMsg(HINSTANCE hLib, LPVOID lpArgs, DWORD dwMsgId, *
* DWORD dwLangId) *
* *
* PURPOSE: format and output error dwMsgId, using string defined *
* for language dwLangId, with insert strings lpArgs, from *
* the messagetable resource in the DLL referenced by *
* handle hLib *
* *
* INPUT: Library handle, insert strings, message ID number, and *
* language ID as defined in the .mc file *
* *
* RETURNS: none *
********************************************************************/

void myPutMsg(HINSTANCE hLib, LPVOID lpArgs, DWORD dwMsgId, DWORD dwLangId)
{
BOOL bSuccess;
LPTSTR msgBuf; /* hold text of the error message that we build */
int dwCode; /* hold various codes extracted from dwMsgId */

/* Here is the layout of the message ID:

3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---+-+-+-----------------------+-------------------------------+
|Sev|C|R| Facility | Code |
+---+-+-+-----------------------+-------------------------------+

where

Sev - is the severity code
C - is the Customer code flag
R - is a reserved bit
Facility - is the facility code
Code - is the facility's status code
*/

printf("Severity: ");
/* output the severity and facility code. Mask off the severity */
/* bits with SEVERITY_MASK and shift them down */
dwCode = (dwMsgId & SEVERITY_MASK) >> 30;
switch (dwCode)
{
case STATUS_SEVERITY_WARNING:
printf("STATUS_SEVERITY_WARNING"); break;
case STATUS_SEVERITY_SUCCESS:
printf("STATUS_SEVERITY_SUCCESS"); break;
case STATUS_SEVERITY_INFORMATIONAL:
printf("STATUS_SEVERITY_INFORMATIONAL"); break;
case STATUS_SEVERITY_ERROR:
printf("STATUS_SEVERITY_ERROR"); break;
default:
printf("Unknown!"); break;
}
printf ("\nFacility: ");
/* Mask off the facility bits with FACILITY_MASK and shift them down */
dwCode = (dwMsgId & FACILITY_MASK) >> 16;
switch (dwCode)
{
case FACILITY_SYSTEM:
printf("FACILITY_SYSTEM"); break;
case FACILITY_STUBS:
printf("FACILITY_STUBS"); break;
case FACILITY_RUNTIME:
printf("FACILITY_RUNTIME"); break;
case FACILITY_IO_ERROR_CODE:
printf("FACILITY_IO_ERROR_CODE"); break;
default:
printf("Unknown!"); break;
}
/* retrieve and format the message from the messagetable DLL. */
bSuccess = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | /* get the message from the DLL */
FORMAT_MESSAGE_ALLOCATE_BUFFER | /* allocate the msg buffer for us */
FORMAT_MESSAGE_ARGUMENT_ARRAY | /* lpArgs is an array of 32-bit values */
60, /* line length for the mesages */
hLib, /* the messagetable DLL handle */
dwMsgId, /* message ID */
dwLangId, /* language ID as defined in .mc file */
(LPTSTR) &msgBuf, /* address of pointer to buffer for message */
MAX_MSG_LENGTH, /* maximum size of the message buffer */
lpArgs); /* array of insert strings for the message */
if (!bSuccess)
printf("Error %d from FormatMessage\n", GetLastError());
else
{
/* mask off the actual message number with MSG_ID_MASK and show it */
printf("\nError: %d: %s", dwMsgId & MSG_ID_MASK, msgBuf);
/* Free the buffer that FormatMessage allocated for us. */
LocalFree((HLOCAL) msgBuf);
}
puts("\n__________\n");
CloseHandle(hLib);
}

/********************************************************************
* FUNCTION: main() *
* *
* PURPOSE: Load the message resource DLL, and call myPutMsg() to *
* format and output error messages to the user *
* *
* INPUT: none *
* *
* RETURNS: none *
********************************************************************/

int main()
{
HINSTANCE hLib; /* handle to the messagetable DLL */
PTCHAR aInsertStrs[8]; /* array of 32-bit insert values for FormatMessage*/
WORD wLangID;

/* Check to make sure we are running on Windows NT */
if( GetVersion() & 0x80000000 )
{
MessageBox(NULL, "Sorry, this application requires Windows NT.\n"
"This application will now terminate.",
"Error: Windows NT Required to Run", MB_OK );
return(1);
}
/* Load the resource library without calling any entry points since */
/* this is a resource-only DLL */
hLib = LoadLibraryEx("messages.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);
if (!hLib)
printf("Error %d from LoadLibrary\n", GetLastError());
/* Messages in the .mc file have been defined using standard locale ID's:
see MAKELANGID and LANG_* definitions in winnt.h */

wLangID = LANG_USER_DEFAULT;
/* to force a different language, define the language ID as one of the values
defined in the Language statement in the .mc file. Alternatively, you
can choose a different language in the International applet in the control
panel and stick with LANG_USER_DEFAULT. */
//wLangID = 0x411;

/* Output some error messages from the messagetable DLL */
/* The first three have no insert strings */
myPutMsg(hLib, NULL, MSG_BAD_COMMAND, wLangID);
myPutMsg(hLib, NULL, MSG_BAD_PARM1, wLangID);
myPutMsg(hLib, NULL, MSG_STRIKE_ANY_KEY, wLangID);
/* wait for user to hit enter as per last error message */
getchar();
/* The next two messages contain insert strings - set up our array */
/* of insert strings and pass the array to myPutMsg() */
aInsertStrs[0] = "foo.c";
aInsertStrs[1] = "BAR";
myPutMsg(hLib, aInsertStrs, MSG_CMD_DELETE, wLangID);
aInsertStrs[0] = (PTCHAR) 47;
aInsertStrs[1] = (PTCHAR) 5;
myPutMsg(hLib, aInsertStrs, MSG_RETRYS, wLangID);
return(0);
}