The MFC library provides a series of classes for handling exceptions. For example, CFileException can be used for handling exceptions thrown from CFile methods, CMemoryException can be used for handling out-of-memory exceptions thrown by the new operator, and so on.

Sometimes you need to extend MFC by writing your own classes with corresponding exception classes. As long as usually you are using Windows API calls (like MFC generally does), an exception class for handling Windows API errors would be great.

First, let's take a fast look into CException.

CException class

CException is the base class for all other MFC exception classes.
It has two virtual functions:

  • GetErrorMessage - gets a string which describes the error;
  • ReportError - displays a message box showing the error message.
If derive from CException, then you can override one or both of these virtual functions to provide your own error descriptions and message boxes. Now, we can go further and implement the exception class for generic WinAPI errors.

A lite CWinAPIException class

class CWinAPIException : public CException  
   CWinAPIException(DWORD dwError) : m_dwErrorCode(dwError) {}
// Attributes
   DWORD m_dwErrorCode;    // error code given by Windows API 
// Overrides
   virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
      PUINT pnHelpContext = NULL);
   virtual int ReportError(UINT nType = MB_OK, UINT nMessageID = 0);
// ...
CWinAPIException overrides CException::GetErrorMessage and CException::ReportError (more info about implementation can be found in the attached sources). We could stop here, but no... CWinAPIException can do more.

An improved CWinAPIException class

Usually MFC exception classes only give the error description, as for example "Path not found". Sometimes is useful to have more information such as the exception source (source file name and code line number). CWinAPIException can provide this additional information at the programmer's request. Let's say, in a beta release of an application we can choose to get all the information, while later in a more stable version we can set to display only the error description. Here is the complete CWinAPIException class:

class CWinAPIException : public CException  
// Constructor
   CWinAPIException(DWORD dwError, LPCTSTR pszFile, UINT nLine, COleDateTime& odtTime);

// Attributes
   DWORD m_dwErrorCode;    // error code given by Windows API 
   CString m_strFile;      // the file from which the exception was thrown
   UINT m_nLine;           // the line from which the exception was thrown
   COleDateTime m_odtTime; // date/time when exception occurred
   // switches used for customizing displayed info 
   static bool m_bShowErrorCode, m_bShowTimestamp, m_bShowSource;
// Overrides
   virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
      PUINT pnHelpContext = NULL);
   virtual int ReportError(UINT nType = MB_OK, UINT nMessageID = 0);
// Operations
   // method for throwing exceptions
   // NOTE: Prefer below macros instead of directly CWinAPIException::Throw call!
   static void Throw(DWORD dwError, LPCTSTR pszFile, UINT nLine);
   // accessors for custom display switches
   static void ShowErrorCode(bool bShowErrorCode) {m_bShowErrorCode = bShowErrorCode;}
   static void ShowSource(bool bShowSource) {m_bShowSource = bShowSource;}
   static void ShowTimestamp(bool bShowTimestamp) {m_bShowTimestamp = bShowTimestamp;}
   static bool IsErrorCodeShown() {return m_bShowErrorCode;}
   static bool IsSourceShown() {return m_bShowSource;}
   static bool IsTimestampShown() {return m_bShowTimestamp;}
// Implementation
   void FormatMessage(CString& strText, LPCTSTR pszSep);
   void FormatMessageFromSystem(CString& strMessage);

There remains just few little things to add. When throwing an exception by calling CWinAPIException::Throw you have to pass the error code dwError, the source (full path and) file name pszFile, and the code line number nLine. The error code is usually retrieved with ::GetLastError. For source file name and line number can be passed the predefined macros __FILE__ and __LINE__, respectively. To make this task easier I have added the following macros to be used instead of CWinAPIException::Throw:

#define WINAPI_THROW_ERROR(e)          CWinAPIException::Throw(e, __FILE__, __LINE__)

// use this macro for functions which return 0 (FALSE) in case of failure
// use this macro for functions which returns NULL in case of failure 
// use this macro which return ERROR_SUCCESS in case of success and an error code otherwise


  • Using WINAPI_VERIFY_TRUE to throw an exception in case of failure (the function returns FALSE)
       BOOL bRet = ::AppendMenu(hMenu, MF_STRING, nID, pszNewItem);
  • Using WINAPI_VERIFY_NOT_NULL to throw an exception in case of failure (the function returns NULL)
       SC_HANDLE hSCManager = ::OpenSCManager(NULL, NULL, GENERIC_READ);
  • Using WINAPI_VERIFY_ERROR_SUCCESS to throw an exception in case of failure (the function returns an error code)
       UINT nRet = ::RegOpenKey(HKEY_LOCAL_MACHINE, pszPath, &hKey);
  • Catching CWinAPIException exceptions
          // some code which can throw CWinAPIException
       catch(CWinAPIException* e)
  • Prevent showing error code

Demo application

ExceptionDemo is a simple SDI application that demonstrates how to use CWinAPIException. You can choose which additional info has to be shown (error code, source, and timestamp), then push "Test exception" button and enjoy.

Related articles

About the Author

Ovidiu Cucu

Graduated at "Gh. Asachi" Technical University - Iasi, Romania. Programming in C++ using Microsoft technologies since 1995. Microsoft MVP awardee since 2006. Moderator and article reviewer at, the number one developer site. Co-founder of, a website dedicated to Romanian C++ developers.



  • Do Herb Erectile Dysfunction Pills Offer Stronger And Rock Hard Erection?

    Posted by adeeffifielm on 06/21/2013 06:48am

    Why To Use Erectile Dysfunction Herbal Cure For Treating Impotence Problems? If medical causes and medications are ruled out, many times hormonal therapy will be attempted [url= ] viagra while working out [/url] see much more Masturbation Erectile Dysfunction Cures

  • Good lookin exception class

    Posted by ahoodin on 07/27/2009 12:44pm

    Nice Ovi!

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

Top White Papers and Webcasts

  • Complex hybrid environments can make it difficult to track interdependencies, increasing the risk of disrupting critical business services. In this white paper by EMA, you'll learn how application discovery and dependency mapping can help you: Meet granular targets for availability, cost, and time-to-revenue for cloud services. Accelerate mean time to repair (MTTR) while communicating better with stakeholders. Manage even the most complex hybrid environments more efficiently and effectively Understand the …

  • Rocket Mobile® for IBM i is an enterprise mobile application development and deployment platform for customers who rely on the IBM i system. Rocket Mobile for IBM i enables customers to leave proven applications in-place and rapidly repurpose them into new managed and secure mobile applications. Fast, easy creation of mobile, web, and hybrid mobile applications that deploy to any iOS, Android, or Windows mobile phone or tablet Built-in integration for seamless repurposing of existing IBM i applications …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date