2013-05-08 14 views
6

Ich habe die Antwort ausgecheckt: How can I return both an error string and error code to VB6 from an ATL activex control?Wie man positiven Fehlercode von ATL zu VB6 zurückgibt?

Ich bin in der Lage, benutzerdefinierte negative Fehlercodes, dh mit dem Schweregrad Bit, und eine benutzerdefinierte Fehlermeldung zurückgeben. Aber ich möchte in der Lage sein, einen Code zu generieren, den VB6 als eine positive # für Err.Number präsentiert, die der Benutzer einfacher finden wird. Ich bin mir ziemlich sicher, dass es getan werden kann, da Microsoft's DAO 3.6 DLL dazu in der Lage ist. Zum Beispiel gibt es Err.Number = 3078 mit Err.Description "Die Microsoft Jet-Datenbank ..." zurück, wenn eine Tabelle nicht existiert.

Beachten Sie, dass ich ISupportErrorInfo usw. für die Fehlerberichterstattung implementiert habe.

Antwort

5

Marks Antwort ein wenig annotieren. Er hat Recht mit FACILITY_CONTROL. Außerdem müssen Sie sicherstellen, dass der Fehlercode größer als 512 ist, so dass VB6-Laufzeitfehlercodes nicht beeinträchtigt werden. Verwenden Sie also so etwas:

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

Danke, FACILITY_CONTROL hat es geschafft! – veneff

+0

Hier ist eine ähnliche Antwort, wie man das Gleiche von C# macht (für diejenigen, die über Google hierher kommen): [Positive VB-Fehlercodes über COM-Interop von C#] (http://Stackoverflow.com/a/32868308/ 588306) – Deanna

4

VB führt eine große Zuordnung von HRESULT-Werten zu Err.Number-Werten durch. wenn die HRESULT 0x8007002 Zum Beispiel ist, bricht VB hinunter sie den COM-Standard wie folgt:

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 

In der Praxis die obere Nibble ist immer 8. Die Einrichtung variiert, und sagt Ihnen, welche Art von Fehlern, dass dies . In diesem Fall lautet der Anlagencode 0x007 (FACILITY_WIN32), was bedeutet, dass dies ein Win32-Standardfehler ist. Die unteren zwei Bytes repräsentieren den tatsächlichen Fehler. In winerror.h ist dieser Fehler 2 - ERROR_FILE_NOT_FOUND. VB ist clever genug, um diesen Fehler dem Standard-VB-Fehler 53 "Datei nicht gefunden" zuzuordnen.

In der VB-Dokumentation wurden wir immer dazu ermutigt, unseren Fehlernummern die Konstante vbObjectError hinzuzufügen, wenn sie von einer VB-Komponente ausgelöst werden. Dies entspricht fast der ODER-Verknüpfung der 32-Bit-Ganzzahl 0x80040000 mit Ihrer Fehlernummer (unter der Annahme, dass es < = 65535 war). In diesem Fall war der Einrichtungscode 0x4 (FACILITY_ITF), was darauf hinwies, dass der Fehler von der spezifischen Schnittstelle einer Co-Klasse ausgelöst wurde. In der Praxis hat dies unsere Fehlerzahlen groß und negativ und schwer verständlich gemacht.

Was wir wirklich hätten tun sollen, wäre, die Dokumentation zu ignorieren und nur die geraden Fehlernummern zu erhöhen. Hinter den Kulissen hat VB OR einen eigenen Einrichtungscode - 0xA (FACILITY_CONTROL). Jedoch würde jede VB-Komponente, die ein HRESULT mit diesem Einrichtungscode sieht, automatisch die oberen zwei Bytes löschen, so dass wir die Nummer als positiv sehen - nicht als negativ.

Ich empfehle Ihnen, FACILITY_CONTROL für Ihre eigenen Fehlernummern zu verwenden. Andere COM-Clients können möglicherweise verwirrt werden, aber VB-Clients sehen Ihre Fehlernummer als positiv.

Alternativ können Sie den normalen HRESULT-Mechanismus für Rückgabewerte ignorieren. Stattdessen geben Sie HRESULT = S_OK zurück und verwenden Sie einen [retval, out] -Parameter am Ende der Funktion, damit es so aussieht, als wäre es eine VB-Funktion.

+0

Danke, mit FACILITY_CONTROL hat den Trick! – veneff