2013-05-08 48 views
6

我已經檢查出答案在:How can I return both an error string and error code to VB6 from an ATL activex control?如何將積極的錯誤代碼從ATL返回給VB6?

我能夠返回自定義的負面錯誤代碼,即設置嚴重性位和自定義錯誤消息。但是,我希望能夠生成一個VB6代碼作爲Err.Number的正面代碼,以便用戶更容易使用。我非常肯定它可以完成,因爲微軟的DAO 3.6 DLL能夠做到。例如,如果表不存在,它將返回Err.Number = 3078與Err.Description「Microsoft Jet數據庫...」。

請注意,我已經實現了ISupportErrorInfo等錯誤報告。

回答

5

註釋馬克的答案了一下。他對使用FACILITY_CONTROL是正確的。另外,您必須確保錯誤代碼大於512,以免干擾VB6運行時錯誤代碼。所以使用這樣的東西:

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

謝謝,使用FACILITY_CONTROL做到了! – veneff 2013-05-09 12:37:43

+0

下面是關於如何從C#執行相同的事情(對於那些通過Google獲得)的類似答案:[通過C#的COM互操作提高正VB樣式錯誤代碼](http://stackoverflow.com/a/32868308/ 588306) – Deanna 2015-10-05 11:16:14

4

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.基金不同,並告訴你,這是什麼類型的錯誤。在這種情況下,設施代碼是0x007(FACILITY_WIN32),這意味着這是一個標準的Win32錯誤。較低的兩個字節表示實際的錯誤。查看winerror.h,這個錯誤是2 - ERROR_FILE_NOT_FOUND。 VB非常聰明,可以將此錯誤映射到標準的VB錯誤53「文件未找到」。

在VB文檔中,我們始終鼓勵在從VB組件中提取常量vbObjectError時將它們添加到我們的錯誤編號中。這幾乎等於將32位整數0x80040000與您的錯誤號進行或運算(假設它是< = 65535)。在這種情況下,設施代碼是0x4(FACILITY_ITF),表示錯誤是由coclass的特定界面引發的。在實踐中,這只是讓我們的錯誤數字大而消極,並且很難理解。

我們應該真正做的是忽略文檔,並提高直接的錯誤數字。在幕後,VB OR'd自己的設施代碼 - 0xA(FACILITY_CONTROL)。但是,任何使用該設施代碼查看HRESULT的VB組件都會自動清除前兩個字節,因此我們會看到該數字爲正值 - 不是負值。

我建議您使用FACILITY_CONTROL作爲您自己的錯誤編號。其他COM客戶端可能會感到困惑,但VB客戶端會將您的錯誤編號視爲肯定。

或者,您可以忽略返回值的正常HRESULT機制。相反,返回HRESULT = S_OK,並在函數結尾使用[retval,out]參數使其看起來好像它是VB函數。

+0

謝謝,使用FACILITY_CONTROL做到了! – veneff 2013-05-09 12:38:20