Сущность технологии СОМ. Библиотека программиста | страница 76



ICat || riid == IIDIDog || riid == IIDIPug) return SOK;

else return SFALSE;

}


Ниже приведен пример клиента, который надежно обрабатывает исключения, используя ISupportErrorInfo и GetErrorInfo:


void TellPugToSnore(/*[in]*/ IPug *pPug)

{

// call a method

// вызываем метод

HRESULT hr = pPug->Snore();

if (FAILED(hr))

{

// check to see if object supports СОМ exceptions

// проверяем, поддерживает ли объект исключения СОМ

ISupportErrorInfo *psei = 0;

HRESULT hr2 =pPug->QueryInterface( IIDISupportErrorInfo, (void**)&psei);

if (SUCCEEDED(hr2))

{

// check if object supports СОМ exceptions via IPug methods

// проверяем, поддерживает ли объект исключения СОМ через методы

IPug hr2 = psei->InterfaceSupportsErrorInfo(IIDIPug);

if (hr2 == SOK)

{

// read exception object for this logical thread

// читаем объект исключений для этого логического потока

IErrorInfo *реi = 0;

hr2 = GetErrorInfo(0, &pei);

if (hr2 == SOK)

{

// scrape out source and description strings

// извлекаем строки кода и описания

BSTR bstrSource = 0, bstrDesc = 0;

hr2 = pei->GetDescription(&bstrDesc);

assert(SUCCEEDED(hr2));

hr2 = pei->GetSource(&bstrSource);

assert(SUCCEEDED(hr2));

// display error information to end-user

// показываем информацию об ошибке конечному пользователю

MessageBoxW(0, bstrDesc ? bstrDesc : L"«, bstrSource ? bstrSource : L»", MBOK);

// free resources

// высвобождаем ресурсы

SysFreeString(bstrSource);

SysFreeString(bstrDesc);

pei->Release();

}

}

psei->Release();

}

}

if (hr2!= SOK)

// something went wrong with exception

// что-то неладно с исключением

MessageBox(0, «Snore Failed», «IPug», MBOK);

}


Довольно просто отобразить исключения СОМ в исключения C++, причем в любом месте. Определим следующий класс, который упаковывает объект исключений СОМ и HRESULT в один класс C++:


struct COMException

{

HRESULT mhresult;

// hresult to return

// hresult для возврата IErrorInfo *mpei;

// exception to throw

// исключение для выбрасывания

COMException(HRESULT hresult, REFIID riid, const OLECHAR *pszSource, const OLECHAR *pszDesc, const OLECHAR *pszHelpFile = 0, DWORD dwHelpContext = 0)

{

// create and init an error info object

// создаем и инициализируем объект информации об ошибке

ICreateErrorInfo *рсеi = 0;

HRESULT hr = CreateErrorInfo(&pcei);

assert(SUCCEEDED(hr));

hr = pcei->SetGUID(riid);

assert(SUCCEEDED(hr));

if (pszSource) hr=pcei->SetSource(constcast(pszSource));

assert(SUCCEEDED(hr));

if (pszDesc) hr=pcei->SetDescription(constcast(pszDesc));