VB 将 HRESULT 值映射到 Err.Number 值。例如,如果 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“找不到文件”。
在 VB 文档中,总是鼓励我们在从 VB 组件引发错误编号时将常量 vbObjectError 添加到错误编号中。这几乎等同于将 32 位整数 0x80040000 与您的错误号进行或运算(假设它是
我们真正应该做的是忽略文档并直接提出错误编号。在幕后,VB 对自己的设施代码进行了 OR 运算 - 0xA (FACILITY_CONTROL)。但是,任何看到带有该设施代码的 HRESULT 的 VB 组件都会自动清除前两个字节,因此我们会将数字视为正数 - 而不是负数。
我建议您将 FACILITY_CONTROL 用于您自己的错误编号。其他 COM 客户端可能会感到困惑,但 VB 客户端会将您的错误编号视为肯定的。
或者,您可以忽略返回值的正常 HRESULT 机制。而是返回 HRESULT = S_OK,并在函数末尾使用 [retval, out] 参数使其看起来像一个 VB 函数。