Motivation
In your last project, how many times did you read the following in the MSDN help files:
If the function fails, the return value is NULL
(or FALSE
, or 0, or -1, or INVALID_HANDLE_VALUE
).
To get extended error information, call GetLastError
.
Then, while debugging, how many times did you:
- copy the current value of the error code from the variables window
- launch the Error Lookup tool
- paste the contents
- and hit a button on the tool
All of this just to see what the meaning of that error number was?
Or, how many times did you separately look up the FormatMessage
documentation on MSDN (took time to swap the CDs too! :) ), just to copy and paste the code for retrieving error messages into your project?
Then, how many times did you wonder if it was worth introducing all those lines calling FormatMessage
right in the middle of the main logic of your app?
Or, how many times did you recall the discussions of exceptions vs error codes?
Or, how many times did you have to explain the meaning of your own, home-grown, error strings to your marketing folks?
Why, coming to MFC, you even have a CPoint
class, and a CSize
class, but no CWin32Error
class!!
That was so, until now! :)
CWin32Error Summary
A C++ class with a very small footprint that encapsulates both the WIN32 error-message strings and the error-code numbers returned by GetLastError()
. Employs a smart-copy mechanism for minimal overheads while passing or returning objects by value. Provides DWORD
and const char*
conversions. Objects can also be sent to the TRACE()
macro directly!
CWin32Error Sample Usage
Example 1: Exception Handling
void MyFunction( void ) throw CWin32Error
{
if(! SomeWin32API())
{
throw CWin32Error();
}
}
void ClientToMyFunction( void )
{
try
{
MyFunction();
}
catch( CWin32Error e ) {
::OutputDebugTrace( e );
}
}
Example 2: "Vanilla" Usage (No exception-handling)
The following code shows how a function can return a CWin32Error
object. Smart copy means you can return objects even during the normal course of execution, without having to take an undue performance hit.
CWin32Error MyFunction( void )
{
if( ! SomeWin32API() )
{
CWin32Error e;
TRACE( "%s\n", e );
return e;
}
return 0; }
Example 3: Simplest: As a message formatting class
The code given below shows how you can use CWin32Error
purely to make the source-code look pretty!
void MyFunction( void )
{
if( ! SomeWin32API() )
{
DWORD dwErr = ::GetLastError();
if( AlertUser( dwErr ) )
{
CWin32Error e = dwErr;
AfxMessageBox( e );
}
return;
}
}
CWin32Error Features
- Is an incredibly small but enourmously useful C++ class.
- Encapsulates the two basic Win32 APIs:
GetLastError
and
FormatMessage
.
- Employs smart copy methods to minimize the overheads of memory allocation, retrieval of system error strings, and copying strings.
- Has all member-functions inline. Just
#include
the Win32Error.h file.
- Does not depend on MFC. Use freely with any C++ library.
- Compiles under both UNICODE and MBCS.
- Is very convenient and simple to use - in fact, the objects of this class are *best* created on the stack, and can be passed by value without undue performance hit.
- Provides automatic conversion to const TCHAR* type. Pass objects, as they are, to
MessageBox()
or AfxMessageBox()
.
- Supports the MFC
TRACE
macro. Pass objects to TRACE
as they are - you don't have to call object.c_str()
method or so. e.g. TRACE( "%s\n", e );
and not TRACE( "%s\n", e.c_str() );
- Helps in taking advantage of the exception-handling features of the C++ language.
Documentation
The main source code is in only one file: Win32Error.h.
A console app demo is included in the download zip file.
Technical notes are included in the ReadMe.Win32Error.txt in the zip file.
Comments, suggestions, and bug reports are most welcome.