我试图返回使用详细的错误VB6 CComCoClass ::错误 ,但似乎我只能返回错误代码/或/消息-但不能同时。
return Error(_T("Not connected"), __uuidof(IMyInterface), HRESULT_FROM_WIN32(ERROR_CONNECTION_INVALID));
在Err.Description结果在一个通用的“对象‘IMyInterface的’方法‘申请’失败”错误消息的VB6侧(但ERROR_CONNECTION_INVALID在Err.Number的),而
return Error(_T("Not connected"));
结果在适当的错误消息,但在Err.Number的一般性错误代码。 我怎样才能两全其美呢?
你不能,这似乎是由设计。 下面详细进一步,但总之,你有三种选择:
- 返回任何消息和VB友好COM错误,即,一个根据该井由VB运行时已知 KB文章 ; VB运行库将在“COM错误”翻译为VB误差加上消息。
- 返回错误消息和DISP_E_EXCEPTION; VB运行库将通过这个“服务器错误”和您的自定义错误消息。 这是什么隐含发生在你的第二个例子,详见下文。
- 返回任何消息和任何其它COM错误,即, 不通过VB运行库已知的一种; VB运行库将诉诸原始HRESULT加上通用消息“
Method '~' of object '~' failed
”。 - 请注意,这个运行时的行为确实也适用,如果你在这里提供的错误信息,即你的信息将完全忽略! 这是什么在你的第一个例子,详见下文。
对于手头的任务它归结为两种选择:
- 如果你要提供的自动化客户上下文正确的“COM错误”像VB(可能你应该),你必须省略自定义错误消息。
- 如果您想为“服务器错误”(即关于您的自动化服务器中的功能的自定义错误条件)提供自定义错误消息你唯一的选择是DISP_E_EXCEPTION。
细节
VB运行库似乎只能提供非常有限的处理关于COM的错误。 这可能是针对特定的方式VB历史和/或技术原因已经实施,而不是在这里特别感兴趣的(关键字是唯一的IDispatch VS双接口和ActiveX COM作为一个“子集”)。
虽然我已经无法浮出水面上述行为的明确说明人们可以从通过其他来源挖看着办吧:
从知识库文章 justadreamer 已指出 :
[...]呼叫到GetErrorInfo方法来检索可用错误信息作出。 然后,运行时确定bstrDescription是否具有比NULL以外的值。 如果运行时发现NULL以外的值,[...],原始HRESULT值在这种情况下使用。 如果运行时发现一个NULL值,[...]的Visual Basic然后使用HRESULT查找相应的Visual Basic错误。
这就解释了关于你的拳头例子的行为:你没有提供的错误信息,因此运行时只是诉诸于它的通用消息“ Method '~' of object '~' failed
”加上你HRESULT
。
你的第二个例子的行为也是一致的,一旦你看看(首先列出)构造函数的定义CComCoClass::Error
:它具有对非指定的参数的默认值,尤其是“HRES = 0”。 在“备注”部分中进一步指出,“如果HRES是零,则返回错误DISP_E_EXCEPTION的前四个版本。” 因此,这暗示将触发“服务器错误”通过行为。
最后,对于像自动化客户行为VB的具体的C ++实现样品见例如段落“错误处理”,并在下面的“练习5” 自动化的Microsoft Office 97和Microsoft Office 2000 。
派生实现从ISupportErrorInfoImpl您的COM暴露接口的类,调用SetErrorInfo如果发生任何设置错误的详细说明。 不要忘记,包括ISupportErrorInfo到类的COM_MAP。
我有这个权利现在挣扎过。 到目前为止,我挖表明错误代码是真正的HRESULT值。 VB6试图将智能和解释HRESULT,但它似乎有它理解的HRESULT相当有限的名单。 对于VB6的HRESULT是不熟悉的,它只是放HRESULT到Err.Number的财产,并希望开发商是足够聪明,弄清楚如何处理它。
我来返回一个错误编号,最接近的是通过使用MAKE_SCODE生成具有设置为我想要的HRESULT的代码领域的HRESULT,严重性标志设置什么,我希望是正确的设施。
这与CreateErrorInfo和SetErrorInfo一起给我拿一个错误代码和VB6的错误描述。 这把我们带回到VB6试图将智能与错误的有限清单。
结帐这篇文章http://support.microsoft.com/kb/827994 。 所以,你的对象必须实现方法ISupportsErrorInfo :: InterfaceSupportsErrorInfo()返回S_OK。 然后返回,你必须调用SetErrorInfo的指针COM对象,它实现的IErrorInfo :: GetDescription前()。 这里有一个例子: http://msdn.microsoft.com/en-us/library/ms221409.aspx 。
如果您返回之前SetErrorInfo,VB会询问你传递给SetErrorInfo对象指针的GetDescription方法。
我不是在归因代码太深您使用的 - 我宁愿用更多的原始COM这肯定是总是有很多的样板代码来测试它 - 但至少它的作品,那么你可以使用先进的封装来代替它。
文章来源: How can I return both an error string and error code to VB6 from an ATL activex control?