Tipps und Tricks zur API

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Autor: Christoph Spielmann, Düsseldorf

Bei der Windows-API (Application Programmers Interface) handelt es sich um eine mächtige Bibliothek von Funktionen, die Ihnen den Zugang zu Windows-internen Ressourcen ermöglichen. Unser Autor Christoph Spielmann hat für den vorliegenden Beitrag in seinen umfangreichen Erfahrungsschatz gegriffen, um Ihnen anhand einiger Beispiele die Möglichkeiten der API zu eröffnen.

Temporäre Dateien werden von Anwendungen vorübergehend angelegt, um verschiedene Daten, Zustände oder gerade in Bearbeitung befindliche Dokumente zwischenzuspeichern.

Es ist zwar kein Muss, aber als allgemeine übereinkunft gilt, einen im System als speziell für diesen Zweck deklarierten Ordner zur Ablage von temporären Dateien zu verwenden – den TEMP-Ordner.

Windows stellt dazu sogar eine eigene API-Funktion bereit, über die Sie den Pfad dieses Ordners ermitteln können (Gesucht – Systemordner). Und wie der Name es sagt: Temporäre Dateien sind ihrer Natur nach vergänglich – Ihre Anwendungen sollten daher auch dafür sorgen, dass sie von Ihnen angelegte temporäre Dateien spätestens beim Beenden wieder löschen.

Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal _    pszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, _
    ByVal lpTempFileName As String) As Long

Quellcode 1

Wenn Sie für Ihr Programm eine temporäre Datei erzeugen wollen, brauchen Sie einen eindeutigen Dateinamen. Denn schließlich legen ja auch andere Anwendungen im TEMP-Ordner ihre Dateien ab, sodass es leicht zu Namenskonflikten kommen könnte.

Sie könnten natürlich einfach einen beliebigen Dateinamen wählen und für den Fall, dass eine Datei dieses Namens bereits existieren sollte, in einer Schleife einen neuen Dateinamen kreieren, bis Sie einen freien gefunden haben.

Doch besser ist wie immer der Weg, die speziell dafür bereitgestellte API-Funktion GetTempFileName (s. Quellcode 1) zu verwenden. Der Funktion werden vier Parameter übergeben.

Im ersten Parameter, lpszPath übergeben Sie den Pfad, in dem der temporäre Dateiname angelegt werden soll, vorzugsweise den des TEMP-Ordners.

In lpPrefixString übergeben Sie einen aus bis zu drei Zeichen bestehenden Präfix, den Sie dem Dateinamen voranstellen möchten. Damit können Sie gewissermaßen eine Anwendung individuell hervorheben. Sie können natürlich auch ganz normal ein „tmp“ übergeben.

Private Declare Function GetTempFileName _    Lib "kernel32" Alias "GetTempFileNameA" _    (ByVal lpszPath As String, ByVal lpPrefixString As _    String, ByVal wUnique As Long, _    ByVal lpTempFileName As String) As Long 
Private Declare Function GetTempPath Lib "kernel32" _    Alias "GetTempPathA" (ByVal BufferLength As Long, _    ByVal lpBuffer As String) As Long
Private Const kLength = 255
Public Function CreateTempFile(Optional Prefix As _    String = "tmp", Optional TempPath As String) _    As String
    Dim nBuffer, nTempPath As String
    Dim nReturn, nPosEnd As Long
    If Len(TempPath) = 0 Then
        nBuffer = Space(kLength)
        nReturn = GetTempPath(kLength, nBuffer)
        If nReturn > 0 Then
            nTempPath = Left(nBuffer, nReturn)
        Else
            nTempPath = CurDir$
            If Right$(nTempPath, 1) <> "\" Then
                nTempPath = nTempPath & "\"
            End If
        End If
    Else
        nTempPath = TempPath
    End If
    nBuffer = Space(kLength)
    nReturn = GetTempFileName(nTempPath, Left$(Prefix, _        3), 0&, nBuffer)
    If nReturn <> 0 Then
        nPosEnd = InStr(nBuffer, Chr$(0))
        If nPosEnd = 0 Then
            CreateTempFile = nBuffer
        Else
            CreateTempFile = Left(nBuffer, nPosEnd - 1)
        End If
    End If
End Function

Quellcode 2

Um den Parameter wUnique brauchen Sie sich nicht unbedingt zu kümmern. Hier könnten Sie Ihrer temporären Datei eine von Ihrer Anwendung selbst generierte und verwaltete Nummer geben. übergeben Sie 0, erzeugt Windows selbst eine eindeutige Zahl anhand der Systemzeit.

Im Puffer lpTempFileName liefert Ihnen die Funktion den erzeugten Dateinamen zurück.

Die Funktion CreateTempFile (s. Quellcode 3) verpackt den Aufruf auf VBA-gerechte und einfach zu handhabende Weise.

Beide Parameter sind optional. Verzichten Sie auf den individuellen Präfix, wird „tmp“ als Präfix verwendet. Lassen Sie die Pfadangabe weg, wird die Datei automatisch im TEMP-Ordner des Systems angelegt. Dazu wird hier die API-Funktion GetTempPath (s. Quellcode 2) direkt aufgerufen (Gesucht Systemordner). Konnte aus irgendeinem Grund keine temporäre Datei angelegt werden, wird ein leerer String zurückgegeben.

Beachten Sie, dass der Aufruf der API-Funktion GetTempFileName (s. Quellcode 2) auf jeden Fall eine Datei anlegt, die Sie nach Gebrauch oder Nichtgebrauch wieder ordnungsgemäß löschen sollten. Dieses Funktionalität der API-Funktion ist sinnvoll, da nach der Ermittlung eines unverwendeten Dateinamens dieser unter Umständen doch schon nicht mehr frei sein könnte, wenn Sie selbst nur Sekunden später eine Datei dieses Namens anzulegen versuchten.

Function CreatePathDeep(NewPath As String) As Boolean
    Dim nNewPath As String
    Dim nStart As Integer
    nNewPath = Trim$(NewPath)
    If Left$(nNewPath, 2) = "\\" Then
        If Len(nNewPath) > 6 Then
            nStart = 7
        Else
            Exit Function
        End If
    ElseIf Mid$(nNewPath, 2, 2) = ":\" Then
        nStart = 4
    Else
        Exit Function
    End If
    If nStart Then
        Do
            nPos = Instr(nStart, nNewPath, "\")
            If nPos Then
                On Error Resume Next
                MkDir Left$(nNewPath, nPos - 1)
                On Error GoTo 0
            Else
                On Error Resume Next
                MkDir nNewPath
                If Err.Number = 0 Then
                    CreatePathDeep = True '' Erfolg
                End If
                On Error GoTo 0
            End If
        Loop While nPos
    End If
End Function

Quellcode 3

Ein neuer Ordner in einem tief verschachtelten Pfad kann mit der VBA-Funktion MkDir nur dann angelegt werden, wenn der Pfad selbst bereits vorhanden ist. Anderenfalls ist es in VBA eine recht mühselige Angelegenheit.

Wollten Sie beispielsweise den Pfad c:\abc\def\ghi anlegen, wenn selbst c:\abc noch nicht existiert, sähe das etwa so aus:

On Error Resume Next
MkDir "c:\abc"
MkDir "c:\abc\def"
MkDir "c:\abc\def\ghi"
On Error GoTo 0

Direkt an Ort und Stelle im Code platziert ist das schon recht aufwändig. Es würde allerdings noch aufwendiger, wenn Sie diese Codezeilen als allgemein verwendbare Funktion implementieren wollten (s. Quellcode 3).

Für Windows-Versionen vor Windows 98 werden Sie nicht darum herum kommen, eine solche oder ähnliche Funktion auf diese Weise zu implementieren. Ab Windows 98 und unter Windows NT können Sie jedoch eine API-Funktion aus einer der System-DLLs (imagehlp.dll) verwenden.

Die Funktion MakeSureDirectoryPathExists (s. Quellcode 4) hält, was ihr Name verspricht. Sie stellt sicher, dass der als Parameter übergebene Pfad nach ihrem Aufruf tatsächlich existiert – selbst wenn sie ihn erst anlegen muss. Das heißt – sie versucht zumindest, das Versprechen zu halten.

Natürlich kann auch sie nichts gegen nicht bereite Laufwerke oder Netzwerkpfade ausrichten. Und ohne die entsprechenden Berechtigungen wird auch sie keine Pfade anlegen können. Den Erfolg meldet sie mit dem Rückgabewert 1 – bei Misserfolg ist dieser 0.

Private Declare Function MakeSureDirectoryPathExists _
    Lib "imagehlp.dll" (ByVal lpPath As String) As Long

Quellcode 5

Public Function CreatePath(NewPath As String) As Boolean
    Dim nNewPath As String
        nNewPath = Trim$(NewPath)
    If Right$(nNewPath, 1) <> "\" Then
        nNewPath = nNewPath & "\"
    Else
        nNewPath = nNewPath
    End If
    CreatePath = _        CBool(MakeSureDirectoryPathExists(nNewPath))
End Function

Quellcode 6

Sie erwartet allerdings einen abschließenden „\“ bei der übergabe des anzulegenden Pfades. Anderenfalls nimmt die Funktion an, dass der letzte Teil ein Dateiname sein könnte und legt diesen Teil daher nicht als Pfadbestandteil an.

Und so rufen Sie diese Funktion beispielsweise auf und prüfen den Erfolg:

Private Declare Function _  MakeSureDirectoryPathExists _
  Lib "imagehlp.dll" (ByVal lpPath As _  String) As Long
  '' ...
  If Not (Cbool _    (MakeSureDirectoryPathExists _    ("c:\abc\def\ghi\") Then
      MsgBox "Pfad konnte nicht " _      & "angelegt werden."
  End If

Wenn Sie die Funktion benötigen, um beispielsweise eine Datei, deren Zielpfad und Name in einem String zusammen vorliegen, in genau diesen Zielpfad zu kopieren, können Sie sich die Sicherheitsmaßnahmen dieser Funktion zunutze machen: Sie können den Pfadstring (eben einschließlich des Dateinamens) an sie übergeben, ohne ihn zuvor erst in Pfad und Dateinamen zerlegen zu müssen.

Wenn Sie sich jedoch nicht bei jedem Aufruf um den abschließenden „\“ kümmern wollen, verpacken Sie die API-Funktion in eine eigene Funktion, CreatePath, die automatisch den abschließenden „\“ hinzufügt, falls er fehlen sollte (s. Quellcode 6).

Es ist kaum verwunderlich, dass eine Funktion zum Ein- und Ausfahren eines CD-Laufwerks im Multimedia-API zu finden ist – immerhin wird ein CD-Laufwerk gelegentlich zu den Multimedia-Geräten gezählt.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar