RSS
StartseiteKnowledge LibraryTop 10Impressum

Dateien aus der Ablage

Kopierte Dateien aus der Zwischenablage ermitteln

Das VB Clipboard-Objekt beschränkt sich bei seinen Funktionen auf Grafik- und Textdaten. Für Dateien, die im Explorer kopiert/ausgeschnitten wurden, bietet es keine Funktionen an. Dieser Artikel zeigt Ihnen, wie Sie dieses Defizit ausgleichen können ...

Anders als das DataObject-Objekt, das bei OLE Drag & Drop Vorgängen zum Zuge kommt, lässt das Clipboard-Objekt eine Möglichkeit vermissen im Explorer kopierte Dateien der Zwischenablage zu entlocken.

Um an die Dateinamen zu kommen, die bei einem Kopiervorgang in der Zwischenablage abgelegt wurden, muss man direkt auf die Zwischenablage zugreifen. Dies erfolgt über die API Funktionen OpenClipboard, zum Öffnen der Zwischenablage und GetClipboardData. Letztere liefert den Handle einer DROPFILES-Struktur (HDROP), die die kopierten Dateinamen enthält. Diese werden mit der API Funktion DragQueryFile extrahiert.

Übergibt man der DragQueryFile Funktion nur den HDROP Handle und –1 als Index, liefert sie die Anzahl der enthaltenen Dateien. Übergibt man hingegen als Index einen Wert zwischen 0 und der Anzahl der insgesamt enthaltenen Dateien, erhält man die Länge des Dateinamens, die dazu genutzt wird einen passenden Puffer zu reservieren. In diesen kann dann der extrahierte Dateiname geschrieben werden.

Zur Erkennung, ob die Quelldateien vom Benutzer ausgeschnitten oder kopiert wurden, muss man den sogenannten "DropEffect" abfragen, der unter dem Format "Preferred DropEffect" in der Zwischenablage abgelegt sind. Da dies ein benutzerdefiniertes Format ist, muss die passende ID zunächst über die API Funktion RegisterClipboardFormat ermittelt werden und wird genutzt, um mit der Funktion GetClipboardData den Handle zu erhalten, der auf den Long-Wert mit dem DropEffect verweist. Dieser wird mit der API Funktion MoveMemory in eine lokale Variable kopiert. Die möglichen Werte sind in der FileDropEffectConstants- Aufzählung deklariert.

Die ClipboardGetFiles Funktion erledigt alles notwendige und gibt eine handliche Collection mit den Pfad- und Dateinamen des Clipboards zurück, die Sie in Ihrer Anwendung weiter verwenden können. Über den Parameter DropEffect, können Sie abfragen, ob die Dateien kopiert oder ausgeschnitten wurden:

Private Declare Function RegisterClipboardFormat Lib "user32" Alias _
       "RegisterClipboardFormatA" (ByVal lpString As String) As Long
Private Declare Function IsClipboardFormatAvailable Lib "user32" _
       (ByVal wFormat As Long) As Long

Private Declare Function OpenClipboard Lib "user32" _
 (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" _
 (ByVal wFormat As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function DragQueryFile Lib "shell32.dll" Alias _
       "DragQueryFileA" (ByVal hDrop As Long, _
        ByVal iFile As Long, ByVal lpszFile As String, _
 	  ByVal cch As Long) As Long

Private Declare Sub MoveMemory Lib "kernel32" Alias _
       "RtlMoveMemory" (ByRef Destination As Any, _
        ByRef Source As Any, ByVal Length As Long)

Private Const CF_HDROP As Long = 15
Private Const CFSTR_PREFERREDDROPEFFECT As String = "Preferred DropEffect"

Public Enum FileDropEffectConstants
  fdDropEffectNone = 0
  fdDropEffectCopy = 1
  fdDropEffectMove = 2
  fdDropEffectLink = 4
End Enum

Public Function ClipboardGetFiles( _
          Optional ByRef DropEffect As FileDropEffectConstants _
                                  ) As Collection
  Dim lngSize   As Long
  Dim strFile   As String
  Dim hDrop     As Long
  Dim lngFormat as Long
  Dim hGlobal   As Long
  Dim lngEffect As Long
  Dim l         As Long

  If (IsClipboardFormatAvailable(CF_HDROP) = 0) Then Exit Function
  
  If (OpenClipboard(0)) Then
    hDrop = GetClipboardData(CF_HDROP)
    
    If (hDrop) Then
      Set ClipboardGetFiles = New Collection

      With ClipboardGetFiles
        For l = 0 To DragQueryFile(hDrop, -1, vbNullString, 0) - 1
          lngSize = DragQueryFile(hDrop, l, vbNullString, 0)
          
          strFile = String$(lngSize + 1, 0)
          lngSize = DragQueryFile(hDrop, l, strFile, Len(strFile))
          
          .Add Left$(strFile, lngSize)
        Next
      End With

      lngFormat = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT))
      hGlobal = GetClipboardData(lngFormat)
      
      If (hGlobal) Then
        MoveMemory lngEffect, ByVal hGlobal, 4
        
        DropEffect = lngEffect
      End If
    End If
    CloseClipboard
  End If
End Function