Насколько я понимаю (основываясь на некоторых связанных страницах MSDN), реализуя ISupportErrorInfo
, вы указываете, что один или несколько интерфейсов в вашем классе возвращают информацию об ошибке, вызывая SetErrorInfo
, а не просто возвращает ошибку HRESULT
.
С этой целью ваша реализация ISuportErrorInfo::InterfaceSupportsErrorInfo
должна возвращать S_OK
только для тех интерфейсов вашего класса, которые фактически используют SetErrorInfo
для возврата информации об ошибке вызывающей стороне, и только этих интерфейсов.
Например, скажем, у вас есть класс, который реализует интерфейс, который вы написали, с именем IFoo
, у которого есть метод DoSomething
. Если кто-то еще создает экземпляр вашего класса и вызывает IFoo::DoSomething
, он должен сделать следующее, если DoSomething
возвращает ошибку HRESULT
(перефразируя с разных страниц MSDN, но я начал с этого: http://msdn.microsoft.com/en-us/library/ms221510.aspx):
Вызовите QueryInterface
по указателю IFoo
, чтобы получить интерфейс ISupportErrorInfo
для объекта, который реализует IFoo
Если вызываемый объект не реализует ISupportErrorInfo
,
тогда звонивший будет иметь
обработать ошибку на основе
HRESULT
значение или передать его в стек вызовов.
Если вызываемый объект реализует ISupportErrorInfo
, то вызывающая сторона должна вызвать ISupportErrorInfo::InterfaceSupportsErrorInfo
, передав REFIID
для интерфейса, который вернул ошибку. В этом случае метод DoSomething
интерфейса IFoo
вернул ошибку, поэтому вы должны передать REFIID_IFoo
(при условии, что оно определено) в InterfaceSupportsErrorInfo
.
Если InterfaceSupportsErrorInfo
возвращает S_OK
, затем вызывающий
на данный момент знает, что может
получить более подробную информацию
об ошибке по телефону
GetErrorInfo
. Если InterfaceSupportsErrorInfo
возвращает S_FALSE
, вызывающий может предположить, что вызываемый интерфейс не предоставляет подробную информацию об ошибке, и ему придется полагаться на возвращенный HRESULT, чтобы выяснить, что произошло.
Причина этого несколько запутанного / запутанного API обработки ошибок, по-видимому, заключается в гибкости (насколько я могу сказать, в любом случае. Это , в конце концов, COM;). При таком дизайне класс может поддерживать несколько интерфейсов, но не каждый интерфейс должен использовать SetErrorInfo
для возврата информации об ошибках из своих методов. Вы можете быть уверены, что выбранные интерфейсы вашего класса возвращают подробную информацию об ошибках через SetErrorInfo
, тогда как другие интерфейсы могут продолжать использовать обычные HRESULT
s для индикации ошибок.
Таким образом, интерфейс ISupportErrorInfo
- это способ сообщить вызывающему коду, что хотя бы один из интерфейсов, реализованных вашим классом, может возвращать подробную информацию об ошибке, а метод InterfaceSupportsErrorInfo
сообщает вызывающей стороне, является ли данный интерфейс единым. из этих интерфейсов. Если это так, то вызывающая сторона может получить подробную информацию об ошибке, позвонив по номеру GetErrorInfo
.
.