很多时候,系统自带的COM异常不能够完全满足我们的需求,例如:
STDMETHODIMP CUserDefineError::TestReport3(BSTR startTime, BSTR stopTime)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
if (CDatetimeConvert::GetFiletimeSpan(ftBegin, ftEnd) < 0)
{
return E_FAILED;
}
...
return S_OK;
}
在此函数中,如果希望当startTime小于stopTime时,能够向外界抛出对应异常明确告诉外面时间参数错误时,自带异常信息已不能够满足需求,这就需要我们自定义COM异常。
我们有两种方法来自定义COM异常。
(1)通过使用系统宏MAKE_HRESULT(sev,fac,code)来自定义异常信息,具体说明如下
// Values are 32 bit values laid out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
其中CODE为16位的可自定义错误信息号。调用者拿到返回的HRESULT值之后,可通过宏
HRESULT_SEVERITY(hr), HRESULT_FACILITY(hr) , HRESULT_CODE(hr)分别获取对应值。进而
得到具体的错误信息。
(2)利用COM自带的错误信息接口,获取自定义错误信息。
COM包含了错误信息接口ISupportErrorInfo,通过实现此接口,可以使得此COM对象支持自定义错误信息。具体实现如下:
1、添加ATL Single Object时勾上ISupportErrorInfo。
2、使用CComCoClass类的6个Error方法中任意一个,输出对应错误信息。
STDMETHODIMP CUserDefineError::TestReportError(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your implementation code here
return Error(_T("自定义错误信息"));
}
3、客户端调用函数后,获取对应错误信息
...
HRESULT hr = spError->TestReportError()
if( FAILED( hr ))
{
CComQIPtr < ISupportErrorInfo > spErrorInfo = spError;
if( spErrorInfo )
{
//判断对象是否支持ISupportError
hr = spErrorInfo->InterfaceSupportsErrorInfo( IID_IUserDefineError);
if( SUCCEEDED( hr ) )
{
//获取具体的错误信息
CComQIPtr < IErrorInfo > spErrInfo;
hr = ::GetErrorInfo( 0, &spErrInfo );
if( SUCCEEDED( hr ) )
{
CComBSTR bstrDes;
spErrInfo->GetDescription( &bstrDes );
}
}
}
...