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

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds