API Fehlermeldungen im Klartext

Veröffentlicht: 16. Aug 2001 | Aktualisiert: 13. Jun 2004

Von Mathias Schiffer

Zu Fehlernummern unter Visual Basic gehört für gewöhnlich eine Beschreibung des Fehlers im Klartext. Fangen Sie mittels einer Fehlerbehandlungsroutine einen auftretenden Fehler ab, können Sie dessen Beschreibung der Eigenschaft Description des Err-Objekts entnehmen. Auch wenn Sie nur die Klartextbeschreibung für eine Fehlernummer erhalten möchten, ohne diesen Fehler zu provozieren, steht Visual Basic Ihnen mit der Funktion Error$ hilfreich zur Seite.

Für die Entwicklung mithilfe des Windows API ("Application Programming Interface") jedoch steht Ihnen diese Möglichkeit so direkt nicht zur Verfügung. Viele API Funktionen liefern einen in ihrer Dokumentation definierten Fehlerstatus als Rückgabewert zurück, andere wiederum returnieren als Information lediglich, ob der Aufruf erfolgreich oder erfolglos war. Die API Funktionen der zweiten Kategorie erkennen Sie im "Platform SDK" Ihrer MSDN Library daran, dass die zugehörige Fehlernummer bei Misserfolg über die API Funktion GetLastError zu ermitteln sei.

Um dieser unter Visual Basic oft fälschlich verwendeten Vorgehensweise gleich einen Riegel vorzuschieben: GetLastError liefert Ihnen unter Visual Basic vielleicht, vielleicht aber auch nicht die korrekte Fehlernummer zurück - diese Funktion ist für Visual Basic Programmierer absolut tabu!

Der Grund für dieses Tabu: Die Visual Basic Laufzeitumgebung macht selbst massiven Gebrauch vom Windows API, GetLastError jedoch liefert immer nur den Fehlerstatus des letzten Aufrufs einer API Funktion zurück. Ob GetLastError Ihnen als Visual Basic Programmierer die korrekte Fehlernummer liefert oder nicht, ist also davon abhängig, ob der letzte Aufruf einer API Funktion aus Ihrer Anwendung selbst oder aus der Visual Basic Laufzeitumgebung heraus auftrat - ein Kriterium, auf das Sie keinerlei Einfluss haben. Aus diesem Grund haben die Entwickler von Visual Basic die Aufgabe von GetLastError in Visual Basic selbst implementiert: Die Eigenschaft LastDllError des Err-Objekts liefert Ihnen den Fehlerstatus zurück, der vom letzten API Aufruf stammt, den Sie selbst in Ihrem Code eingesetzt haben.

Verwenden Sie unter Visual Basic immer Err.LastDllError, nie die API Funktion GetLastError!

Haben Sie mithilfe von Err.LastDllError herausgefunden, durch welche Fehlernummer ein aufgetretener Fehler in einer API Funktion beschrieben wird, fehlt Ihnen noch die Klartextbeschreibung zur Fehlernummer. Hierfür können Sie jedoch nicht wirksam auf die Funktion Error$ zurückgreifen, da sich die Fehlernummern von Visual Basic von denen des API unterscheiden. Notwendig für eine solche Interpretation einer API Fehlernummer ist der Einsatz der API Funktion FormatMessage, den die folgende Funktion APIErrorDescription für diesen Zweck kapselt:

' --- Notwendige Deklarationen 
Private Const FORMAT_MESSAGE_FROM_SYSTEM    As Long = &H1000& 
Private Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200& 
Private Const FORMAT_MESSAGE_MAX_WIDTH_MASK As Long = &HFF& 
Private Const LANG_USER_DEFAULT             As Long = &H400& 
Private Declare Function FormatMessage _ 
  Lib "kernel32" Alias "FormatMessageA" ( _ 
  ByVal dwFlags As Long, _ 
  ByRef lpSource As Any, _ 
  ByVal dwMessageId As Long, _ 
  ByVal dwLanguageId As Long, _ 
  ByVal lpBuffer As String, _ 
  ByVal nSize As Long, _ 
  ByRef Arguments As Long _ 
  ) As Long 
' --- Code 
Public Function APIErrorDescription(ByVal ErrLastDllError As Long) As String 
' Liefert die Klartextbeschreibung zu einer API Fehlernummer, die 
' unter Visual Basic über Err.LastDllError ermittelt wurde. 
' HINWEIS: Die API-Funktion GetLastError ist für Visual Basic tabu! 
Dim sBuffer    As String  ' String für die Rückgabe des Fehlertexts 
Dim lBufferLen As Long    ' Länge des reservierten Strings 
  ' Stringbuffer für die Rückgabe reservieren 
  sBuffer = Space$(1024) 
  ' Fehlernummer in einen Fehlertext wandeln 
  lBufferLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM _ 
                             Or FORMAT_MESSAGE_MAX_WIDTH_MASK, _ 
                             Or FORMAT_MESSAGE_IGNORE_INSERTS _ 
                             ByVal 0&, ErrLastDllError, _ 
                             LANG_USER_DEFAULT, _ 
                             sBuffer, Len(sBuffer), 0) 
  If lBufferLen > 0 Then 
    ' Fehler wurde identifiziert, der Fehlertext liegt vor 
    APIErrorDescription = Left$(sBuffer, lBufferLen) 
  Else 
    ' Der Fehlertext konnte nicht ermittelt werden 
    APIErrorDescription = "Unbekannter Fehler: &H" & Hex$(ErrLastDllError) 
  End If 
End Function

Ich empfehle, diesen Sourcecode in ein Standardmodul zu kopieren und dieses in Ihrem Vorlagenverzeichnis für Standardmodule abzuspeichern. So haben Sie über den entsprechenden Dialog beim Hinzufügen eines neuen Moduls jederzeit schnellen Zugriff auf ein wichtiges Debugging-Werkzeug bei der Arbeit mit dem Windows API.