轻松处理 HRESULT 数量






4.82/5 (6投票s)
2002 年 6 月 15 日

61338
使用 TRY_HRESULT/CATCH_HRESULT 宏处理 HRESULT 返回值
引言
处理 HRESULT
返回值对富有创造力的程序员来说始终是一项艰巨的任务。我找到了一种解决方案,它使用异常机制,可以一次性处理所有 HRESULTs
。方法很简单 - 重载函数调用的赋值运算符 (=) 并将其用于错误处理。
TRY/CATCH HRESULT 宏
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); }
标准的 HRESULT 返回值处理
#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; }
使用 TRY_HRESULT/CATCH_HRESULT 宏处理 HRESULT
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; }