/* Capture Windows messages and log them to a file */

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


// Possible exit status values
#define EXIT_SUCCESS			0	
#define EXIT_FAILURE_ON_OPEN		1
#define EXIT_FAILURE_ON_WRITE		2
#define EXIT_FAILURE_ON_REGISTER	3
#define EXIT_FAILURE_ON_WINDOW		4

const char APP_NAME [ ] = "MsgLog";	/* name of window class */
const char APP_TITLE [ ] = "Windows Message Logger";	/* caption */
const char LOG_FILE [ ] = "messages.out";	/* name of log file */

void
initLogFile( const char * filename )
{
	FILE * fplog;

	fplog = fopen( filename, "wt" );
	if ( fplog == NULL )
	{
		MessageBox( HWND_DESKTOP, 
			    "Cannot create file", 
			    filename, 
			    MB_OK );

		PostQuitMessage( EXIT_FAILURE_ON_OPEN );
	}
}

void
logMessage( const char * filename, 
	    const char * messageName,
	    UINT message, 
	    WPARAM wParam, 
	    LPARAM lParam )
{
	static unsigned long messageCounter;

	FILE * fplog;

	fplog = fopen( filename, "at" );
	if ( fplog == NULL )
	{
		MessageBox( HWND_DESKTOP, 
			    "Cannot append to file",
			    filename, 
			    MB_OK );

		PostQuitMessage( EXIT_FAILURE_ON_WRITE );
	}

  	fprintf( fplog, 
		 "[%lu] ", 
		 ++messageCounter );

  	fprintf( fplog, 
		 "%-30s (%04x) %08x (%6d|%6d) %08x (%6d|%6d)\n",
		 messageName, 
		 message,
		 wParam, 
		 LOWORD(wParam), 
		 HIWORD(wParam),
		 lParam, 
		 LOWORD(lParam), 
		 HIWORD(lParam) );

	fclose( fplog );
}

LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );

/*
 *	WinMain:  startup function for program
 *
 *	This is the program entry point.
 *	1.  Register the window class.
 *	2.  Create the window.
 *	3.  Enter the message loop.
 */
INT WINAPI
WinMain( HINSTANCE hThisInst, 
	 HINSTANCE hPrevInst,
	 LPSTR lpszArgs, 
	 INT nWinMode )
{
	HWND hWnd;
	MSG msg;
	WNDCLASSEX wcl;

	/* Define a window class. */
	wcl.cbSize = sizeof(WNDCLASSEX); 

	wcl.hInstance = hThisInst;	/* handle to this instance */
	wcl.lpszClassName = APP_NAME;	/* window class name */
	wcl.lpfnWndProc = WndProc;	/* window function */
	wcl.style = 0;			/* default style */

	wcl.hIcon = LoadIcon( NULL, IDI_APPLICATION );	/* large icon */
	wcl.hIconSm = LoadIcon( NULL, IDI_WINLOGO );	/* small icon */
	wcl.hCursor = LoadCursor( NULL, IDC_ARROW );	/* cursor style */

	wcl.lpszMenuName = NULL;	/* no menu */
	wcl.cbClsExtra = 0;		/* no extra */
	wcl.cbWndExtra = 0;		/* information needed */

	/* Make the window background white. */
	wcl.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ); 

	/* Register the window class. */
	if ( ! RegisterClassEx( & wcl ) )
	{
		MessageBox( HWND_DESKTOP, 
			    "RegisterClassEx", 
			    "WinMain", 
			    MB_OK );

		return ( EXIT_FAILURE_ON_REGISTER );
	}

	/* Now that a window class has been registered, a window
	     can be created. */
	hWnd = CreateWindow(
		APP_NAME,		/* name of window class */
		APP_TITLE,		/* title */
		WS_OVERLAPPEDWINDOW,	/* window style - normal */
		CW_USEDEFAULT,		/* X coordinate */
		CW_USEDEFAULT,		/* Y coordinate */
		CW_USEDEFAULT,		/* width */
		CW_USEDEFAULT,		/* height */
		HWND_DESKTOP,		/* no parent window */
		NULL, 			/* menu already specified */
		hThisInst,		/* handle of this program instance */
		NULL			/* no additional arguments */
	);
	if ( hWnd == NULL )
	{
		MessageBox( HWND_DESKTOP, 
			    "CreateWindow", 
			    "WinMain", 
			    MB_OK );

		return ( EXIT_FAILURE_ON_WINDOW );
	}

	/* Display the window. */
	ShowWindow( hWnd, nWinMode );
	UpdateWindow( hWnd );

	/* Create the message loop. */
	while ( GetMessage( & msg, NULL, 0, 0 ) )
	{
		TranslateMessage( & msg ); /* allow use of keyboard */
		DispatchMessage( & msg );  /* return control to Windows */
	}
	return msg.wParam;
}

/*
 *	This function is called by Windows NT and is passed 
 *	 messages from the message queue.
 */
LRESULT CALLBACK
WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
  switch ( message )
  {
  case WM_CREATE:
    logMessage(LOG_FILE, "WM_CREATE", message, wParam, lParam);
    break;

  case WM_DESTROY:
    logMessage(LOG_FILE, "WM_DESTROY", message, wParam, lParam);

    /* we must handle this one, otherwise we can't close the window! */
    PostQuitMessage(0);	
    break;

  case WM_MOVE:
    logMessage(LOG_FILE, "WM_MOVE", message, wParam, lParam);
    break;

  case WM_SIZE:
    logMessage(LOG_FILE, "WM_SIZE", message, wParam, lParam);
    break;

  case WM_ACTIVATE:
    logMessage(LOG_FILE, "WM_ACTIVATE", message, wParam, lParam);
    break;

  case WM_SETFOCUS:
    logMessage(LOG_FILE, "WM_SETFOCUS", message, wParam, lParam);
    break;

  case WM_KILLFOCUS:
    logMessage(LOG_FILE, "WM_KILLFOCUS", message, wParam, lParam);
    break;

  case WM_ENABLE:
    logMessage(LOG_FILE, "WM_ENABLE", message, wParam, lParam);
    break;

  case WM_SETREDRAW:
    logMessage(LOG_FILE, "WM_SETREDRAW", message, wParam, lParam);
    break;

  case WM_SETTEXT:
    logMessage(LOG_FILE, "WM_SETTEXT", message, wParam, lParam);
    break;

  case WM_GETTEXT:
    logMessage(LOG_FILE, "WM_GETTEXT", message, wParam, lParam);
    break;

  case WM_GETTEXTLENGTH:
    logMessage(LOG_FILE, "WM_GETTEXTLENGTH", message, wParam, lParam);
    break;

  case WM_PAINT:
    logMessage(LOG_FILE, "WM_PAINT", message, wParam, lParam);
    break;

  case WM_CLOSE:
    logMessage(LOG_FILE, "WM_CLOSE", message, wParam, lParam);
    break;

  case WM_QUERYENDSESSION:
    logMessage(LOG_FILE, "WM_QUERYENDSESSION", message, wParam, lParam);
    break;

  case WM_QUIT:
    logMessage(LOG_FILE, "WM_QUIT", message, wParam, lParam);
    break;

  case WM_QUERYOPEN:
    logMessage(LOG_FILE, "WM_QUERYOPEN", message, wParam, lParam);
    break;

  case WM_ERASEBKGND:
    logMessage(LOG_FILE, "WM_ERASEBKGND", message, wParam, lParam);
    break;

  case WM_SYSCOLORCHANGE:
    logMessage(LOG_FILE, "WM_SYSCOLORCHANGE", message, wParam, lParam);
    break;

  case WM_ENDSESSION:
    logMessage(LOG_FILE, "WM_ENDSESSION", message, wParam, lParam);
    break;

  case WM_SHOWWINDOW:
    logMessage(LOG_FILE, "WM_SHOWWINDOW", message, wParam, lParam);
    break;

  case WM_WININICHANGE:
    logMessage(LOG_FILE, "WM_WININICHANGE", message, wParam, lParam);
    break;

  case WM_DEVMODECHANGE:
    logMessage(LOG_FILE, "WM_DEVMODECHANGE", message, wParam, lParam);
    break;

  case WM_ACTIVATEAPP:
    logMessage(LOG_FILE, "WM_ACTIVATEAPP", message, wParam, lParam);
    break;

  case WM_FONTCHANGE:
    logMessage(LOG_FILE, "WM_FONTCHANGE", message, wParam, lParam);
    break;

  case WM_TIMECHANGE:
    logMessage(LOG_FILE, "WM_TIMECHANGE", message, wParam, lParam);
    break;

  case WM_CANCELMODE:
    logMessage(LOG_FILE, "WM_CANCELMODE", message, wParam, lParam);
    break;

  case WM_SETCURSOR:
    logMessage(LOG_FILE, "WM_SETCURSOR", message, wParam, lParam);
    break;

  case WM_MOUSEACTIVATE:
    logMessage(LOG_FILE, "WM_MOUSEACTIVATE", message, wParam, lParam);
    break;

  case WM_CHILDACTIVATE:
    logMessage(LOG_FILE, "WM_CHILDACTIVATE", message, wParam, lParam);
    break;

  case WM_QUEUESYNC:
    logMessage(LOG_FILE, "WM_QUEUESYNC", message, wParam, lParam);
    break;

  case WM_GETMINMAXINFO:
    logMessage(LOG_FILE, "WM_GETMINMAXINFO", message, wParam, lParam);
    break;

  case WM_PAINTICON:
    logMessage(LOG_FILE, "WM_PAINTICON", message, wParam, lParam);
    break;

  case WM_ICONERASEBKGND:
    logMessage(LOG_FILE, "WM_ICONERASEBKGND", message, wParam, lParam);
    break;

  case WM_NEXTDLGCTL:
    logMessage(LOG_FILE, "WM_NEXTDLGCTL", message, wParam, lParam);
    break;

  case WM_SPOOLERSTATUS:
    logMessage(LOG_FILE, "WM_SPOOLERSTATUS", message, wParam, lParam);
    break;

  case WM_DRAWITEM:
    logMessage(LOG_FILE, "WM_DRAWITEM", message, wParam, lParam);
    break;

  case WM_MEASUREITEM:
    logMessage(LOG_FILE, "WM_MEASUREITEM", message, wParam, lParam);
    break;

  case WM_DELETEITEM:
    logMessage(LOG_FILE, "WM_DELETEITEM", message, wParam, lParam);
    break;

  case WM_VKEYTOITEM:
    logMessage(LOG_FILE, "WM_VKEYTOITEM", message, wParam, lParam);
    break;

  case WM_CHARTOITEM:
    logMessage(LOG_FILE, "WM_CHARTOITEM", message, wParam, lParam);
    break;

  case WM_SETFONT:
    logMessage(LOG_FILE, "WM_SETFONT", message, wParam, lParam);
    break;

  case WM_GETFONT:
    logMessage(LOG_FILE, "WM_GETFONT", message, wParam, lParam);
    break;

  case WM_SETHOTKEY:
    logMessage(LOG_FILE, "WM_SETHOTKEY", message, wParam, lParam);
    break;

  case WM_GETHOTKEY:
    logMessage(LOG_FILE, "WM_GETHOTKEY", message, wParam, lParam);
    break;

  case WM_QUERYDRAGICON:
    logMessage(LOG_FILE, "WM_QUERYDRAGICON", message, wParam, lParam);
    break;

  case WM_COMPAREITEM:
    logMessage(LOG_FILE, "WM_COMPAREITEM", message, wParam, lParam);
    break;

  case WM_COMPACTING:
    logMessage(LOG_FILE, "WM_COMPACTING", message, wParam, lParam);
    break;

  case WM_COMMNOTIFY:
    logMessage(LOG_FILE, "WM_COMMNOTIFY", message, wParam, lParam);
    break;

  case WM_WINDOWPOSCHANGING:
    logMessage(LOG_FILE, "WM_WINDOWPOSCHANGING", message, wParam, lParam);
    break;

  case WM_WINDOWPOSCHANGED:
    logMessage(LOG_FILE, "WM_WINDOWPOSCHANGED", message, wParam, lParam);
    break;

  case WM_POWER:
    logMessage(LOG_FILE, "WM_POWER", message, wParam, lParam);
    break;

  case WM_COPYDATA:
    logMessage(LOG_FILE, "WM_COPYDATA", message, wParam, lParam);
    break;

  case WM_CANCELJOURNAL:
    logMessage(LOG_FILE, "WM_CANCELJOURNAL", message, wParam, lParam);
    break;

  case WM_NOTIFY:
    logMessage(LOG_FILE, "WM_NOTIFY", message, wParam, lParam);
    break;

  case WM_INPUTLANGCHANGEREQUEST:
    logMessage(LOG_FILE, "WM_INPUTLANGCHANGEREQUEST", message, wParam, lParam);
    break;

  case WM_INPUTLANGCHANGE:
    logMessage(LOG_FILE, "WM_INPUTLANGCHANGE", message, wParam, lParam);
    break;

  case WM_TCARD:
    logMessage(LOG_FILE, "WM_TCARD", message, wParam, lParam);
    break;

  case WM_HELP:
    logMessage(LOG_FILE, "WM_HELP", message, wParam, lParam);
    break;

  case WM_USERCHANGED:
    logMessage(LOG_FILE, "WM_USERCHANGED", message, wParam, lParam);
    break;

  case WM_NOTIFYFORMAT:
    logMessage(LOG_FILE, "WM_NOTIFYFORMAT", message, wParam, lParam);
    break;

  case WM_CONTEXTMENU:
    logMessage(LOG_FILE, "WM_CONTEXTMENU", message, wParam, lParam);
    break;

  case WM_STYLECHANGING:
    logMessage(LOG_FILE, "WM_STYLECHANGING", message, wParam, lParam);
    break;

  case WM_STYLECHANGED:
    logMessage(LOG_FILE, "WM_STYLECHANGED", message, wParam, lParam);
    break;

  case WM_DISPLAYCHANGE:
    logMessage(LOG_FILE, "WM_DISPLAYCHANGE", message, wParam, lParam);
    break;

  case WM_GETICON:
    logMessage(LOG_FILE, "WM_GETICON", message, wParam, lParam);
    break;

  case WM_SETICON:
    logMessage(LOG_FILE, "WM_SETICON", message, wParam, lParam);
    break;

  case WM_NCCREATE:
    logMessage(LOG_FILE, "WM_NCCREATE", message, wParam, lParam);
    break;

  case WM_NCDESTROY:
    logMessage(LOG_FILE, "WM_NCDESTROY", message, wParam, lParam);
    break;

  case WM_NCCALCSIZE:
    logMessage(LOG_FILE, "WM_NCCALCSIZE", message, wParam, lParam);
    break;

  case WM_NCHITTEST:
    logMessage(LOG_FILE, "WM_NCHITTEST", message, wParam, lParam);
    break;

  case WM_NCPAINT:
    logMessage(LOG_FILE, "WM_NCPAINT", message, wParam, lParam);
    break;

  case WM_NCACTIVATE:
    logMessage(LOG_FILE, "WM_NCACTIVATE", message, wParam, lParam);
    break;

  case WM_GETDLGCODE:
    logMessage(LOG_FILE, "WM_GETDLGCODE", message, wParam, lParam);
    break;

  case WM_NCMOUSEMOVE:
    logMessage(LOG_FILE, "WM_NCMOUSEMOVE", message, wParam, lParam);
    break;

  case WM_NCLBUTTONDOWN:
    logMessage(LOG_FILE, "WM_NCLBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_NCLBUTTONUP:
    logMessage(LOG_FILE, "WM_NCLBUTTONUP", message, wParam, lParam);
    break;

  case WM_NCLBUTTONDBLCLK:
    logMessage(LOG_FILE, "WM_NCLBUTTONDBLCLK", message, wParam, lParam);
    break;

  case WM_NCRBUTTONDOWN:
    logMessage(LOG_FILE, "WM_NCRBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_NCRBUTTONUP:
    logMessage(LOG_FILE, "WM_NCRBUTTONUP", message, wParam, lParam);
    break;

  case WM_NCRBUTTONDBLCLK:
    logMessage(LOG_FILE, "WM_NCRBUTTONDBLCLK", message, wParam, lParam);
    break;

  case WM_NCMBUTTONDOWN:
    logMessage(LOG_FILE, "WM_NCMBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_NCMBUTTONUP:
    logMessage(LOG_FILE, "WM_NCMBUTTONUP", message, wParam, lParam);
    break;

  case WM_NCMBUTTONDBLCLK:
    logMessage(LOG_FILE, "WM_NCMBUTTONDBLCLK", message, wParam, lParam);
    break;

  case WM_KEYDOWN:
  /* case WM_KEYFIRST:	duplicates */
    logMessage(LOG_FILE, "WM_KEYDOWN", message, wParam, lParam);
    break;

  case WM_KEYUP:
    logMessage(LOG_FILE, "WM_KEYUP", message, wParam, lParam);
    break;

  case WM_CHAR:
    logMessage(LOG_FILE, "WM_CHAR", message, wParam, lParam);
    break;

  case WM_DEADCHAR:
    logMessage(LOG_FILE, "WM_DEADCHAR", message, wParam, lParam);
    break;

  case WM_SYSKEYDOWN:
    logMessage(LOG_FILE, "WM_SYSKEYDOWN", message, wParam, lParam);
    break;

  case WM_SYSKEYUP:
    logMessage(LOG_FILE, "WM_SYSKEYUP", message, wParam, lParam);
    break;

  case WM_SYSCHAR:
    logMessage(LOG_FILE, "WM_SYSCHAR", message, wParam, lParam);
    break;

  case WM_SYSDEADCHAR:
    logMessage(LOG_FILE, "WM_SYSDEADCHAR", message, wParam, lParam);
    break;

  case WM_KEYLAST:
    logMessage(LOG_FILE, "WM_KEYLAST", message, wParam, lParam);
    break;

  case WM_IME_STARTCOMPOSITION:
    logMessage(LOG_FILE, "WM_IME_STARTCOMPOSITION", message, wParam, lParam);
    break;

  case WM_IME_ENDCOMPOSITION:
    logMessage(LOG_FILE, "WM_IME_ENDCOMPOSITION", message, wParam, lParam);
    break;

  case WM_IME_COMPOSITION:
  /* case WM_IME_KEYLAST:	duplicates */
    logMessage(LOG_FILE, "WM_IME_COMPOSITION", message, wParam, lParam);
    break;

  case WM_INITDIALOG:
    logMessage(LOG_FILE, "WM_INITDIALOG", message, wParam, lParam);
    break;

  case WM_COMMAND:
    logMessage(LOG_FILE, "WM_COMMAND", message, wParam, lParam);
    break;

  case WM_SYSCOMMAND:
    logMessage(LOG_FILE, "WM_SYSCOMMAND", message, wParam, lParam);
    break;

  case WM_TIMER:
    logMessage(LOG_FILE, "WM_TIMER", message, wParam, lParam);
    break;

  case WM_HSCROLL:
    logMessage(LOG_FILE, "WM_HSCROLL", message, wParam, lParam);
    break;

  case WM_VSCROLL:
    logMessage(LOG_FILE, "WM_VSCROLL", message, wParam, lParam);
    break;

  case WM_INITMENU:
    logMessage(LOG_FILE, "WM_INITMENU", message, wParam, lParam);
    break;

  case WM_INITMENUPOPUP:
    logMessage(LOG_FILE, "WM_INITMENUPOPUP", message, wParam, lParam);
    break;

  case WM_MENUSELECT:
    logMessage(LOG_FILE, "WM_MENUSELECT", message, wParam, lParam);
    break;

  case WM_MENUCHAR:
    logMessage(LOG_FILE, "WM_MENUCHAR", message, wParam, lParam);
    break;

  case WM_ENTERIDLE:
    logMessage(LOG_FILE, "WM_ENTERIDLE", message, wParam, lParam);
    break;

  case WM_CTLCOLORMSGBOX:
    logMessage(LOG_FILE, "WM_CTLCOLORMSGBOX", message, wParam, lParam);
    break;

  case WM_CTLCOLOREDIT:
    logMessage(LOG_FILE, "WM_CTLCOLOREDIT", message, wParam, lParam);
    break;

  case WM_CTLCOLORLISTBOX:
    logMessage(LOG_FILE, "WM_CTLCOLORLISTBOX", message, wParam, lParam);
    break;

  case WM_CTLCOLORBTN:
    logMessage(LOG_FILE, "WM_CTLCOLORBTN", message, wParam, lParam);
    break;

  case WM_CTLCOLORDLG:
    logMessage(LOG_FILE, "WM_CTLCOLORDLG", message, wParam, lParam);
    break;

  case WM_CTLCOLORSCROLLBAR:
    logMessage(LOG_FILE, "WM_CTLCOLORSCROLLBAR", message, wParam, lParam);
    break;

  case WM_CTLCOLORSTATIC:
    logMessage(LOG_FILE, "WM_CTLCOLORSTATIC", message, wParam, lParam);
    break;

  case WM_MOUSEMOVE:
  /* case WM_MOUSEFIRST:	duplicates */
    logMessage(LOG_FILE, "WM_MOUSEMOVE", message, wParam, lParam);
    break;

  case WM_LBUTTONDOWN:
    logMessage(LOG_FILE, "WM_LBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_LBUTTONUP:
    logMessage(LOG_FILE, "WM_LBUTTONUP", message, wParam, lParam);
    break;

  case WM_LBUTTONDBLCLK:
    logMessage(LOG_FILE, "WM_LBUTTONDBLCLK", message, wParam, lParam);
    break;

  case WM_RBUTTONDOWN:
    logMessage(LOG_FILE, "WM_RBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_RBUTTONUP:
    logMessage(LOG_FILE, "WM_RBUTTONUP", message, wParam, lParam);
    break;

  case WM_RBUTTONDBLCLK:
    logMessage(LOG_FILE, "WM_RBUTTONDBLCLK", message, wParam, lParam);
    break;

  case WM_MBUTTONDOWN:
    logMessage(LOG_FILE, "WM_MBUTTONDOWN", message, wParam, lParam);
    break;

  case WM_MBUTTONUP:
    logMessage(LOG_FILE, "WM_MBUTTONUP", message, wParam, lParam);
    break;

  case WM_MBUTTONDBLCLK:
  /* case WM_MOUSELAST:	duplicates */
    logMessage(LOG_FILE, "WM_MBUTTONDBLCLK", message, wParam, lParam);
    break;

#ifdef WM_MOUSEWHEEL	/* not normally defined */
  case WM_MOUSEWHEEL:
    logMessage(LOG_FILE, "WM_MOUSEWHEEL", message, wParam, lParam);
    break;
#endif /*WM_MOUSEWHEEL*/

  case WM_PARENTNOTIFY:
    logMessage(LOG_FILE, "WM_PARENTNOTIFY", message, wParam, lParam);
    break;

  case WM_ENTERMENULOOP:
    logMessage(LOG_FILE, "WM_ENTERMENULOOP", message, wParam, lParam);
    break;

  case WM_EXITMENULOOP:
    logMessage(LOG_FILE, "WM_EXITMENULOOP", message, wParam, lParam);
    break;

  case WM_NEXTMENU:
    logMessage(LOG_FILE, "WM_NEXTMENU", message, wParam, lParam);
    break;

  case WM_SIZING:
    logMessage(LOG_FILE, "WM_SIZING", message, wParam, lParam);
    break;

  case WM_CAPTURECHANGED:
    logMessage(LOG_FILE, "WM_CAPTURECHANGED", message, wParam, lParam);
    break;

  case WM_MOVING:
    logMessage(LOG_FILE, "WM_MOVING", message, wParam, lParam);
    break;

  case WM_POWERBROADCAST:
    logMessage(LOG_FILE, "WM_POWERBROADCAST", message, wParam, lParam);
    break;

  case WM_DEVICECHANGE:
    logMessage(LOG_FILE, "WM_DEVICECHANGE", message, wParam, lParam);
    break;

  case WM_IME_SETCONTEXT:
    logMessage(LOG_FILE, "WM_IME_SETCONTEXT", message, wParam, lParam);
    break;

  case WM_IME_NOTIFY:
    logMessage(LOG_FILE, "WM_IME_NOTIFY", message, wParam, lParam);
    break;

  case WM_IME_CONTROL:
    logMessage(LOG_FILE, "WM_IME_CONTROL", message, wParam, lParam);
    break;

  case WM_IME_COMPOSITIONFULL:
    logMessage(LOG_FILE, "WM_IME_COMPOSITIONFULL", message, wParam, lParam);
    break;

  case WM_IME_SELECT:
    logMessage(LOG_FILE, "WM_IME_SELECT", message, wParam, lParam);
    break;

  case WM_IME_CHAR:
    logMessage(LOG_FILE, "WM_IME_CHAR", message, wParam, lParam);
    break;

  case WM_IME_KEYDOWN:
    logMessage(LOG_FILE, "WM_IME_KEYDOWN", message, wParam, lParam);
    break;

  case WM_IME_KEYUP:
    logMessage(LOG_FILE, "WM_IME_KEYUP", message, wParam, lParam);
    break;

  case WM_MDICREATE:
    logMessage(LOG_FILE, "WM_MDICREATE", message, wParam, lParam);
    break;

  case WM_MDIDESTROY:
    logMessage(LOG_FILE, "WM_MDIDESTROY", message, wParam, lParam);
    break;

  case WM_MDIACTIVATE:
    logMessage(LOG_FILE, "WM_MDIACTIVATE", message, wParam, lParam);
    break;

  case WM_MDIRESTORE:
    logMessage(LOG_FILE, "WM_MDIRESTORE", message, wParam, lParam);
    break;

  case WM_MDINEXT:
    logMessage(LOG_FILE, "WM_MDINEXT", message, wParam, lParam);
    break;

  case WM_MDIMAXIMIZE:
    logMessage(LOG_FILE, "WM_MDIMAXIMIZE", message, wParam, lParam);
    break;

  case WM_MDITILE:
    logMessage(LOG_FILE, "WM_MDITILE", message, wParam, lParam);
    break;

  case WM_MDICASCADE:
    logMessage(LOG_FILE, "WM_MDICASCADE", message, wParam, lParam);
    break;

  case WM_MDIICONARRANGE:
    logMessage(LOG_FILE, "WM_MDIICONARRANGE", message, wParam, lParam);
    break;

  case WM_MDIGETACTIVE:
    logMessage(LOG_FILE, "WM_MDIGETACTIVE", message, wParam, lParam);
    break;

  case WM_MDISETMENU:
    logMessage(LOG_FILE, "WM_MDISETMENU", message, wParam, lParam);
    break;

  case WM_ENTERSIZEMOVE:
    logMessage(LOG_FILE, "WM_ENTERSIZEMOVE", message, wParam, lParam);
    break;

  case WM_EXITSIZEMOVE:
    logMessage(LOG_FILE, "WM_EXITSIZEMOVE", message, wParam, lParam);
    break;

  case WM_DROPFILES:
    logMessage(LOG_FILE, "WM_DROPFILES", message, wParam, lParam);
    break;

  case WM_MDIREFRESHMENU:
    logMessage(LOG_FILE, "WM_MDIREFRESHMENU", message, wParam, lParam);
    break;

#ifdef WM_MOUSEHOVER	/* not normally defined */
  case WM_MOUSEHOVER:
    logMessage(LOG_FILE, "WM_MOUSEHOVER", message, wParam, lParam);
    break;
#endif /*WM_MOUSEHOVER*/

#ifdef WM_MOUSELEAVE	/* not normally defined */
  case WM_MOUSELEAVE:
    logMessage(LOG_FILE, "WM_MOUSELEAVE", message, wParam, lParam);
    break;
#endif /*WM_MOUSELEAVE*/

  case WM_CUT:
    logMessage(LOG_FILE, "WM_CUT", message, wParam, lParam);
    break;

  case WM_COPY:
    logMessage(LOG_FILE, "WM_COPY", message, wParam, lParam);
    break;

  case WM_PASTE:
    logMessage(LOG_FILE, "WM_PASTE", message, wParam, lParam);
    break;

  case WM_CLEAR:
    logMessage(LOG_FILE, "WM_CLEAR", message, wParam, lParam);
    break;

  case WM_UNDO:
    logMessage(LOG_FILE, "WM_UNDO", message, wParam, lParam);
    break;

  case WM_RENDERFORMAT:
    logMessage(LOG_FILE, "WM_RENDERFORMAT", message, wParam, lParam);
    break;

  case WM_RENDERALLFORMATS:
    logMessage(LOG_FILE, "WM_RENDERALLFORMATS", message, wParam, lParam);
    break;

  case WM_DESTROYCLIPBOARD:
    logMessage(LOG_FILE, "WM_DESTROYCLIPBOARD", message, wParam, lParam);
    break;

  case WM_DRAWCLIPBOARD:
    logMessage(LOG_FILE, "WM_DRAWCLIPBOARD", message, wParam, lParam);
    break;

  case WM_PAINTCLIPBOARD:
    logMessage(LOG_FILE, "WM_PAINTCLIPBOARD", message, wParam, lParam);
    break;

  case WM_VSCROLLCLIPBOARD:
    logMessage(LOG_FILE, "WM_VSCROLLCLIPBOARD", message, wParam, lParam);
    break;

  case WM_SIZECLIPBOARD:
    logMessage(LOG_FILE, "WM_SIZECLIPBOARD", message, wParam, lParam);
    break;

  case WM_ASKCBFORMATNAME:
    logMessage(LOG_FILE, "WM_ASKCBFORMATNAME", message, wParam, lParam);
    break;

  case WM_CHANGECBCHAIN:
    logMessage(LOG_FILE, "WM_CHANGECBCHAIN", message, wParam, lParam);
    break;

  case WM_HSCROLLCLIPBOARD:
    logMessage(LOG_FILE, "WM_HSCROLLCLIPBOARD", message, wParam, lParam);
    break;

  case WM_QUERYNEWPALETTE:
    logMessage(LOG_FILE, "WM_QUERYNEWPALETTE", message, wParam, lParam);
    break;

  case WM_PALETTEISCHANGING:
    logMessage(LOG_FILE, "WM_PALETTEISCHANGING", message, wParam, lParam);
    break;

  case WM_PALETTECHANGED:
    logMessage(LOG_FILE, "WM_PALETTECHANGED", message, wParam, lParam);
    break;

  case WM_HOTKEY:
    logMessage(LOG_FILE, "WM_HOTKEY", message, wParam, lParam);
    break;

  case WM_PRINT:
    logMessage(LOG_FILE, "WM_PRINT", message, wParam, lParam);
    break;

  case WM_PRINTCLIENT:
    logMessage(LOG_FILE, "WM_PRINTCLIENT", message, wParam, lParam);
    break;

  case WM_HANDHELDFIRST:
    logMessage(LOG_FILE, "WM_HANDHELDFIRST", message, wParam, lParam);
    break;

  case WM_HANDHELDLAST:
    logMessage(LOG_FILE, "WM_HANDHELDLAST", message, wParam, lParam);
    break;

  case WM_AFXFIRST:
    logMessage(LOG_FILE, "WM_AFXFIRST", message, wParam, lParam);
    break;

  case WM_AFXLAST:
    logMessage(LOG_FILE, "WM_AFXLAST", message, wParam, lParam);
    break;

  case WM_PENWINFIRST:
    logMessage(LOG_FILE, "WM_PENWINFIRST", message, wParam, lParam);
    break;

  case WM_PENWINLAST:
    logMessage(LOG_FILE, "WM_PENWINLAST", message, wParam, lParam);
    break;

  default:
    logMessage(LOG_FILE, "Unrecognized Message!!!", message, wParam, lParam);
  }

  /* Let Windows NT process all messages */
  return DefWindowProc(hWnd, message, wParam, lParam);
}

