Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Easy handling number of HRESULTs

0.00/5 (No votes)
14 Jun 2002 1  
Handling HRESULT return values with TRY_HRESULT/CATCH_HRESULT macros

Introduction

Handling HRESULT return values is always hard job for creative programmers. I found a solution which uses exceptions mechanism and all HRESULTs can be handled at once. It's simple - override the operator = for function calls and use it for error handling.

TRY/CATCH HRESULT macros

void OutputHresult(HRESULT hr, UINT nTextID);
#define TRY_HRESULT(hr) HRESULT_EX hr; try {
#define CATCH_HRESULT(hr, nTextID) } catch(HRESULT hr) 
    { if(hr != S_OK) OutputHresult(hr, nTextID); }

struct HRESULT_EX
{
    void operator = (const HRESULT& hr)
    { 
        if(FAILED(hr))
            throw hr;
    }
};

void OutputHresult(HRESULT hr, UINT nTextID)
{
    CString sText = (LPCSTR)nTextID;
    LPTSTR szError;
    if(HRESULT_FACILITY(hr) == FACILITY_WINDOWS)
        hr = HRESULT_CODE(hr);
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
        (LPTSTR)&szError, 0, NULL);
    CHAR s[MAX_PATH];
    sprintf(s, "%s\n\nError number 0x%x\n%s", 
        sText, hr, szError);
    MessageBox(NULL, s, "Error", 
        MB_ICONWARNING);
    LocalFree(szError);
}

Standard HRESULT return values handling

#include <afxoledb.h>


HRESULT OpenDatabase()
{
    HRESULT hr;

    CDataSource db;
    CSession session;

    CDBPropSet dbinit(DBPROPSET_DBINIT);
    dbinit.AddProperty(
        DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, false);
    dbinit.AddProperty(DBPROP_INIT_DATASOURCE,
        "MyDatabase");
    dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
    dbinit.AddProperty(DBPROP_INIT_LCID, (long)1029);

    hr = db.OpenWithServiceComponents("MSDASQL.1",
        &dbinit);
    if(FAILED(hr)) // check for errors

        return hr;

    hr = session.Open(db);
    if(FAILED(hr)) // check for errors

        return hr;

    return hr;
}

HRESULT handling with TRY_HRESULT/CATCH_HRESULT macros

bool OpenDatabase2()
{
    bool bRetVal = false;

    // --- begin of HRESULT checking ---


    TRY_HRESULT(hr)                          
        // try statement, HRESULT_EX definition


        CDataSource db;
    CSession session;

    CDBPropSet dbinit(DBPROPSET_DBINIT);
    dbinit.AddProperty(
        DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, false);
    dbinit.AddProperty(DBPROP_INIT_DATASOURCE, 
        "MyDatabase");
    dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
    dbinit.AddProperty(DBPROP_INIT_LCID, (long)1029);

    hr = db.OpenWithServiceComponents(
        "MSDASQL.1", &dbinit);
    // do not need to check for errors

    hr = session.Open(db);
    // do not need to check for errors


    bRetVal = true; // all HRESULTs succeeded


    CATCH_HRESULT(hr, IDS_ERROR_HR_OLEDB) // catch statement


        // --- end of HRESULT checking ---


        return bRetVal;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here