Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ БОМ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 23

Автор Π”ΠΎΠ½Π°Π»ΡŒΠ΄ Бокс

Sub UseCollie(fido as ICollie)

fido.HairCount = fido.HairCount – (fido.Age * 1000)

fido.CurrentThought = Β«I wish I had a boneΒ»

End Sub


Π‘++-ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ этого интСрфСйса просто прибавляСт ΠΊ ΠΈΠΌΠ΅Π½Π°ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² конструкции put ΠΈΠ»ΠΈ get, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ программисту, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ относится ΠΊ свойству:


void UseCollie(ICollie *pFido)

{

long n1, n2;

HRESULT hr = pFido->getHairCount(&n1);

assert(SUCCEEDED(hr));

hr = pFido->getAge(&n2);

assert(SUCCEEDED(hr));

hr = pFido->putHairCount(n1 – (n2 * 1000)): assert(SUCCEEDED(hr));

BSTR bstr = SysAllocString(OLESTR(Β«I wish I had a boneΒ»));

hr = pFido->putCurrentThought(bstr);

assert(SUCCEEDED(hr));

SysFreeString(bstr);


Π₯отя свойства Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π½Π΅ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ развития, ΠΎΠ½ΠΈ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ для выполнСния Ρ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ Π½Π° Ρ‚Π΅ языки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡ… ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚[1].


Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

БОМ ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ выбрасывания (throwing) ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ситуаций ΠΈΠ· Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ². ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² языкС C++ Π½Π΅ сущСствуСт Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ стандарта для ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, БОМ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ явныС API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для выбрасывания ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² БОМ-ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ:


// throw an exception

// Π²ΠΎΠ·Π±ΡƒΠΆΠ΄Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

HRESULT SetErrorInfo([in] ULONG reserved, //

m.b.z. [in] IErrorlnfo *pei);

// catch an exception

// ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

HRESULT GetErrorInfo([in] ULONG reserved, // m.b.z.

[out] IErrorInfo **ppei);


ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° SetErrorInfo вызываСтся ΠΈΠ· Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ логичСским ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ (logical thread)[1]. GetErrorInfo Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ логичСского ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΈ сбрасываСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ GetErrorInfo возвратят SFALSE, показывая Ρ‚Π΅ΠΌ самым, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π½Π΅Ρ‚. Как слСдуСт ΠΈΠ· ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Π½ΠΈΠΆΠ΅ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ интСрфСйс IErrorInfo:


[ object, uuid(1CF2B120-547D-101B-8E65-08002B2BD119) ]

interface IErrorInfo: IUnknown

{

// get IID of interface that threw exception

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ IID Ρ‚ΠΎΠ³ΠΎ интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π±ΡƒΠ΄ΠΈΠ» ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

HRESULT GetGUID([out] GUID * pGUID);

// get class name of object that threw exception

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя класса Ρ‚ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π±ΡƒΠ΄ΠΈΠ» ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

HRESULT GetSource([out] BSTR * pBstrSource);

// get human-readable description of exception

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΠ΅ описаниС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

HRESULT GetDescription([out] BSTR * pBstrDescription);

// get WinHelp filename of documentation of error

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя Ρ„Π°ΠΉΠ»Π° WinHelp, содСрТащСго Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΎΠ± ошибкС

HRESULT GetHelpFile([out] BSTR * pBstrHelpFile);

// get WinHelp context ID for documentation of error

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ контСкстный ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ WinHelp для Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ошибки

HRESULT GetHelpContext([out] DWORD * pdwHelpContext);

}


Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ спСцифичСскиС для ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ интСрфСйсы Π² Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ IErrorInfo.

БОМ прСдусматриваСт ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ IErrorInfo, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ с использованиСм API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ БОМ CreateErrorInfo:


HRESULT CreateErrorInfo([out] ICreateErrorInfo **ppcei);


Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ IErrorInfo ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ интСрфСйс ICreateErrorInfo, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ состояниС Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ:


[ object, uuid(22F03340-547D-101B-8E65-08002B2BD119) ]

interface ICreateErrorInfo: IUnknown

{

// set IID of interface that threw exception

// устанавливаСм IID интСрфСйс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π±ΡƒΠ΄ΠΈΠ» ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

HRESULT SetGUID([in] REFGUID rGUID);

// set class name of object that threw exception

// устанавливаСм классовоС имя ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π±ΡƒΠ΄ΠΈΠ» ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

HRESULT SetSource([in, string] OLECHAR* pwszSource);

// set human-readable description of exception

// устанавливаСм Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΠ΅ описаниС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

HRESULT SetDescription([in, string] OLECHAR* pwszDesc);

// set WinHelp filename of documentation of error

// устанавливаСм имя Ρ„Π°ΠΉΠ»Π° WinHelp, содСрТащСго Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΎΠ± ошибкС

HRESULT SetHelpFile([in, string] OLECHAR* pwszHelpFile);

// set WinHelp context ID for documentation of error

// устанавливаСм ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ контСкста WinHelp для Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ошибки

HRESULT SetHelpContext([in] DWORD dwHelpContext);

}


Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ этот интСрфСйс просто позволяСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΡΡ‚ΡŒΡŽ основными Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ, доступными ΠΈΠ· интСрфСйса IErrorInfo.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ рСализация ΠΌΠ΅Ρ‚ΠΎΠ΄Π° выбрасываСт БОМ-ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ своСму Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ:


STDMETHODIMP PugCat::Snore(void)

{

if (this->IsAsleep())

// ok to perform operation?

// ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ?

return this->DoSnore();

//do operation and return

// выполняСм ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΈ возвращаСмся

//otherwise create an exception object

// Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС создаСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

ICreateErrorInfo *рсСi = 0; HRESULT hr = CreateErrorInfo(&pcei);

assert(SUCCEEDED(hr));

// initialize the exception object

// ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

hr = pcei->SetGUID(IIDIPug);

assert(SUCCEEDED(hr));

hr = pcei->SetSource(OLESTR(Β«PugCatΒ»));

assert(SUCCEEDED(hr));

hr = pcei->SetDescription(OLESTR("I am not asleep!"));

assert(SUCCEEDED(hr));

hr = pcei->SetHelpFile(OLESTR(Β«C:\\PugCat.hlpΒ»));

assert(SUCCEEDED(hr));

hr = pcei->SetHelpContext(5221);

assert(SUCCEEDED(hr));

// Β«throwΒ» exception

// «выбрасываСм» ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

IErrorInfo *pei = 0;

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

assert(SUCCEEDED(hr));

hr = SetErrorInfo(0, pei);

// release resources and return a SEVERITYERROR result

// высвобоТдаСм рСсурсы ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚

// SEVERITYERROR (ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎΡΡ‚ΡŒ ошибки)

pei->Release();

pcei->Release();

return PUGEPUGNOTASLEEP;

}


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ пСрСдаСтся Π² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ SetErrorInfo, БОМ сохраняСт ссылку Π½Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Β«ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‡Π΅Π½ΠΎΒ» Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΌ GetErrorInfo.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ±Ρ€Π°ΡΡ‹Π²Π°ΡŽΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ БОМ, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс 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<OLECHAR*>(pszSource));

assert(SUCCEEDED(hr));

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

assert(SUCCEEDED(hr));

if (pszHelpFile) hr=pcei->SetHelpFile(constcast<OLECHAR*>(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++