Class for displaying system error messages

The attached zip contains a small class I use regularly. It is an interface to the win32 FormatMessage api for error-reporting.

It's use is very simple: when you detect a win32 error (could not open file for example):

FILE *f = fopen("idontexist.txt", "r");
if(!f)
{
   CErrorMessage em;  // initializes with the current ::GetLastError
   if(em.MessageBox("problem opening file, cause:", "file:idontexist.txt\nRetry?", MB_YESNO)== IDYES)
   {
	...
   }
}

Header file.
// ErrorMessage.h: interface for the CErrorMessage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ERRORMESSAGE_H__51CAC9F1_9ECE_11D1_A06C_0000832CDDC7__INCLUDED_)
#define AFX_ERRORMESSAGE_H__51CAC9F1_9ECE_11D1_A06C_0000832CDDC7__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class CErrorMessage  
{
public:
		// default ctor: calls GetLastError to get the current errorcode
	CErrorMessage();
		// specify your own errorcode
	CErrorMessage(DWORD theError);
	~CErrorMessage();

		//	setup a new error (0=call GetLastError)
	void	setError(DWORD error=0);

	CString	getMessage() const		{return themsg;}
	DWORD	getMessageCode() const	{return dwError;}
		//	AfxMessageBox with the text pfxtext + "\n" + themsg + "\n" + suftext
	int		MessageBox(const char* pfxtext=NULL, const char* suftext=NULL, UINT nType=MB_OK) const;
protected:
	DWORD	dwError;
	CString	themsg;
		//	get the messagestring from the system
	void	getCurrentMessage();

};

#endif // !defined(AFX_ERRORMESSAGE_H__51CAC9F1_9ECE_11D1_A06C_0000832CDDC7__INCLUDED_)

Implementation file.

// ErrorMessage.cpp: implementation of the CErrorMessage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ErrorMessage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
	default ctor
	gets the current system-error
*/
CErrorMessage::CErrorMessage()
{
	dwError		=	::GetLastError();
	getCurrentMessage();
}
/*
	ctor
	you specify the system-error
*/
CErrorMessage::CErrorMessage(DWORD theError)
{
	dwError		=	theError;
	getCurrentMessage();
}

CErrorMessage::~CErrorMessage()
{
}
/*
	reuse an existing CErrorMessage by setting a new system-error
*/
void	CErrorMessage::setError(DWORD error)
{
	if(dwError==0)
		dwError=::GetLastError();
	else
		dwError=error;
	getCurrentMessage();
}
/*
	show a message-box with the error-message
	you can specify a prefix- and suffix-line to the message
*/
int CErrorMessage::MessageBox(const char* pfxtext, const char* suftext, UINT nType) const
{
	CString	msg	=	"";
	if(pfxtext)	msg	=	CString(pfxtext) + "\n";
	msg	+=	themsg;
	if(suftext)	msg	=	msg + "\n" + suftext;
	return AfxMessageBox(msg, nType);
}
/*
	get the message from the current errorcode in the user's language
*/
void CErrorMessage::getCurrentMessage()
{
	LPTSTR	lpBuf;
	if(::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
						FORMAT_MESSAGE_ALLOCATE_BUFFER
					,	NULL
					,	dwError
					,	MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)
					,	(LPTSTR)&lpBuf
					,	0
					,	NULL)!=0)
	{
		themsg	=	lpBuf;
		::LocalFree(lpBuf);
	}
	else
	{
		themsg.Format("Error %i occurred (no further info)", dwError);
	}
}



Comments

  • Convert more OS error to string

    Posted by Legacy on 02/18/1999 12:00am

    Originally posted by: Remon

    Please have a look ...
    
    

    #include <lmerr.h>
    void PASCAL ConvertErrorToString( DWORD error_code, CString& error_string )
    {
    HMODULE hModule = NULL; // default to system source
    LPTSTR MessageBuffer = NULL;
    DWORD dwBufferLength;

    //
    // Always start off with an empty string
    //
    error_string.Empty();

    //
    // if error_code is in the network range, load the message source
    //
    if (error_code >= NERR_BASE && error_code <= MAX_NERR) {
    hModule = ::LoadLibraryEx( _TEXT("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE );
    }

    //
    // call FormatMessage() to allow for message text to be acquired
    // from the system or the supplied module handle
    //
    dwBufferLength = ::FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_IGNORE_INSERTS |
    FORMAT_MESSAGE_FROM_SYSTEM | // always consider system table
    ((hModule != NULL) ? FORMAT_MESSAGE_FROM_HMODULE : 0),
    hModule, // module to get message from (NULL == system)
    error_code,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
    (LPTSTR) &MessageBuffer, 0, NULL );

    if ( MessageBuffer ) {
    if ( dwBufferLength )
    error_string = (LPCTSTR)MessageBuffer;

    //
    // free the buffer allocated by the system
    //
    ::LocalFree(MessageBuffer);
    }

    //
    // if you loaded a message source, unload it
    //
    if (hModule != NULL)
    ::FreeLibrary(hModule);

    if ( error_string.GetLength() == 0 ) {
    error_string.Format( TEXT( "Unknown System Error %lu" ), error_code );
    }
    }

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds