COM的错误处理,一般是通过返回值HRESULT来确定的,这个相关描述的文章比较多了,不多说了。
今天在做一个VS插件的时候发现对于主窗口设置标题总是失败,在summer帮助下,跟汇编,发现一句话说vs主窗口不能被设置,晕。后面针对这句话发现了COM的错误信息传递的方式。
这里要说一下的就是COM是如何进行语言无关的错误信息处理,这里就涉及到一组接口,对,又是接口。
按照COM的标准,对于一个可以尽心错误处理的对象,要实现ISupportErrorInfo接口,该接口只有一个方法InterfaceSupportsErrorInfo,给这个方法传出产生错误信息的对象所实现的接口中那个刚产生错误的哪个方法所在的接口的IID(很绕口把),举个例子,
class CA : public IA,IAImpl,ISupportErrorInfo{...};//这就说明CA 的对象至此和错误处理,需要实现
按照COM的标准,对于一个可以尽心错误处理的对象,要实现ISupportErrorInfo接口,该接口只有一个方法InterfaceSupportsErrorInfo,给这个方法传出产生错误信息的对象所实现的接口中那个刚产生错误的哪个方法所在的接口的IID(很绕口把),举个例子,
方法,如果在调用IA接口的foo方法的时候产生了错误,就要给InterfaceSupportsErrorInfo方法传入IA接口的IID,如果返回S_OK,说明本对象支持对IA接口的错误处理,如果返回S_FALSE则说明不支持该接口的错误信息处理。
接下来我们首先讨论,CA对象如何实现错误信息,首先当错误产生的时候要显示生成一个Error Object,使用CreateErrorInfo方法可以产生一个ICreateErrorInfo对象,通过这个对象就可以设置错误的描述信息,产生错误的接口IID,ProgID,帮助信息等等。当产生出ICreateErrorInfo对象后,再对这个错误对象查询出IErrorInfo对象,设置给SetErrorInfo方法,该方法第一个参数始终为0.到此你就将错误信息设置好了,这时候返回一个错误的HRESULT,调用方就可以侦错到错误产生了。在调用方,如果侦测到错误,比如通过返回值的HRESULT,在检查调用对象是否实现了ISupportErrorInfo接口,并且通过InterfaceSupportsErrorInfo方法检查对与产生错误的函数调用所在的接口是否支持错误处理,如果确实是需要处理,并且对象以及对应的接口也支持,则调用GetErrorInfo方法获得IErrorInfo对象,进而查询到相关的信息。
这里需要注意的是,对于GetErrorInfo方法,如果调用方发现,当前这个错误不需要处理,那么他就应该将这个错误代码(HRESULT)传递给它自己的调用方,而不要调用GetErrorInfo获取错误信息对象,只有真正处理这个错误的地方才应该调用GetErrorInfo。