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

Объекты, которые сбрасывают исключения СОМ, должны использовать интерфейс ISupportErrorInfo , чтобы показывать, какие интерфейсы поддерживают исключения. Этот интерфейс используется клиентами, чтобы установить, верный ли результат дает GetErrorInfo[2]. Этот интерфейс предельно прост:

[ object, uuid(DFOB3060-548F-101B-8E65-08002B2BD119) ]

interface ISupportErrorInfo: IUnknown

{

HRESULT InterfaceSupportsErrorInfo([in] REFIID riid);

}

Предположим, что класс PugCat, рассмотренный в этой главе, сбрасывает исключения из каждого поддерживаемого им интерфейса. Тогда его реализация будет выглядеть так:

STDMETHODIMP PugCat::InterfaceSupportsErrorInfo(REFIID riid)

{

if (riid == IIDIAnimal || riid == IIDICat || 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));

assert(SUCCEEDED(hr));

if (pszHelpFile) hr=pcei->SetHelpFile(constcast(pszHelpFile));

assert(SUCCEEDED(hr));

hr = pcei->SetHelpContext(dwHelpContext);

assert(SUCCEEDED(hr));

// hold the HRESULT and IErrorInfo ptr as data members

// сохраняем HRESULT и указатель IErrorInfo как элементы данных

mhresult = hresult;

hr=pcei->QueryInterface(IIDIErrorInfo, (void**)&mpei);

assert(SUCCEEDED(hr));

pcei->Release();

}

};

С использованием только что приведенного С++-класса COMException показанный выше метод Snore может быть модифицирован так, чтобы он преобразовывал любые исключения C++ в исключения СОМ:

STDMETHODIMP PugCat::Snore(void)

{

HRESULT hrex = SOK;

try

{

if (this->IsAsleep()) return this->DoSnore();

else throw COMException(PUGEPUGNOTASLEEP, IIDIPug, OLESTR(«PugCat»), OLESTR(«I am not asleep!»));

}

catch (COMException& ce)

{

// a C++ COMException was thrown

// было сброшено исключение COMException C++

HRESULT hr = SetErrorInfo(0, ce.mpei);

assert(SUCCEEDED(hr));

ce.mpei->Release();

hrex = ce.mhresult;

}

catch (…)

{

// some unidentified C++ exception was thrown

// было выброшено какое-то неидентифицированное исключение C++

COMException ex(EFAIL, IIDIPug, OLESTR(«PugCat»), OLESTR(«A C++ exception was thrown»));

HRESULT hr = SetErrorInfo(0, ex.mpei);

assert(SUCCEEDED(hr));

ex.mpei->Release();

hrex = ex.mhresult;

}

return hrex;

}

Заметим, что реализация метода заботится о том, чтобы не позволить чисто С++-исключениям переходить через границы метода. Таково безусловное требование СОМ.

<p>Где мы находимся?</p>
Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных