如何从ATL返回正错误码到VB6

How to return positive error code from ATL to VB6?

本文关键字:错误 误码 VB6 返回 ATL      更新时间:2023-10-16

我已经检查出答案:我如何从ATL activex控件返回错误字符串和错误代码到VB6 ?

我能够返回自定义负错误代码,即设置严重性位,和自定义错误消息。但是,我希望能够生成一个代码,VB6将呈现为Err的正#。用户会觉得更容易使用的数字。我很确定这是可以做到的,因为微软的DAO 3.6 DLL能够做到。例如,它返回Err。编号= 3078,带有Err。如果表不存在,则描述"The Microsoft Jet database…"。

请注意,我已经实现了ISupportErrorInfo等错误报告

给Mark的回答加一点注释。他使用FACILITY_CONTROL是对的。此外,您必须确保错误码大于512,这样它就不会干扰VB6运行时错误码。所以可以这样写:

HRESULT MakeVB6Error(UINT errCode) {
    assert(errCode > 0 && errCode < 65536 - 513);
    return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_CONTROL, errCode + 513);
}

VB做了很多HRESULT值到Err的映射。数量值。例如,如果HRESULT是0x8007002, VB使用COM标准将它们分解为如下所示:

Bit 31 - Severity (set to 1 in all errors)
Bit 30 - Reserved
Bit 29 - Customer Bit
Bit 28 - Reserved
Bit 27 
  - 16   Facility code
Bit 15 
  -  0   Error code

在实践中,最上面的小口总是8。Facility会变化,告诉你这是什么类型的错误。在本例中,设备代码是0x007 (FACILITY_WIN32),这意味着这是一个标准的Win32错误。下面的两个字节表示实际的错误。查看winerror.h,这个错误是2 - ERROR_FILE_NOT_FOUND。VB很聪明地将这个错误映射到标准的VB错误53 "File not found"。

在VB文档中,我们总是被鼓励在从VB组件中引发错误数时将常量vbObjectError添加到错误数中。这几乎相当于将32位整数0x80040000与错误号(假设它是<= 65535)匹配。在这种情况下,设施代码是0x4 (FACILITY_ITF),这表明错误是从协类的特定接口引发的。在实践中,这只会使我们的错误数又大又负,难以理解。

我们真正应该做的是忽略文档,直接抛出错误编号。在幕后,VB编写了自己的设施代码0xA (FACILITY_CONTROL)。然而,任何VB组件看到带有该工具代码的HRESULT都会自动清除顶部的两个字节,因此我们将看到的数字是正的-而不是负的。

我建议您使用FACILITY_CONTROL作为您自己的错误编号。其他COM客户端可能会感到困惑,但是VB客户端会看到您的错误数为正。

或者,您可以忽略返回值的普通HRESULT机制。相反,返回HRESULT = S_OK,并在函数末尾使用[retval, out]参数,使其看起来像是一个VB函数。