Rubrik: Verschiedenes | VB-Versionen: VB5, VB6 | 02.01.02 |
Die Zwischenablage im Griff Die Zwischnablage ist ein beliebter Ort für das Zwischenspeichern von Daten, die öfters benötigt werden. Nahezu jedes Programm nutzt diese Funktion. Meist sogar unbeabsichtet durch das Kontextmeü einer Textbox. Aber auch Drag & Drop Operationen, die Windows Shell oder diverse Grafik-, Audio- oder Textanwendungen nutzen diese Technologie, um Daten für die Verwendung in anderen Programmen zwischenzuspeichern. | ||
Autor: Dieter Otter / Matthias Volk | Bewertung: | Views: 46.308 |
Die Zwischnablage ist ein beliebter Ort für das Zwischenspeichern von Daten, die öfters benötigt werden. Nahezu jedes Programm nutzt diese Funktion. Meist sogar unbeabsichtet durch das Kontextmeü einer Textbox. Aber auch Drag & Drop Operationen, die Windows Shell oder diverse Grafik-, Audio- oder Textanwendungen nutzen diese Technologie, um Daten für die Verwendung in anderen Programmen zwischenzuspeichern.
Die Inhalte der Zwischenablage
In der Zwischenablage befindet sich nicht, wie man vielleicht vermuten würde, nur ein Format. Das heißt, wenn eine Anwendung z.B. Text in die Zwischenablage kopiert, werden diese Daten vom Windows-System in verschiedene Formate umgewandelt. Nach dem Kopieren vonnormalem Text findet man in der Zwischenablage z.B. Unicode-Text (ein auf Bytes basierender Textfluss, der schnellere Programmabläufe ermöglicht), normalen Text und OEM-Text, der Sonderzeichen so wie ein MS-DOS Programm anzeigt, um Anzeigefehler zu verhindern. Dasselbe gilt auch für Bitmaps. Wird ein Bitmap in die Zwischenablage kopiert, so wird von Windows automatisch ein zweites Format in der Zwischenablage angelegt. Dieses zweite Bitmap ist dann vom Typ "Enhanced Metafile". Diese Methode (das Speichern von Daten in unterschiedlichen Formaten) ermöglicht, dass einige Programme, die z.B. nur Unicode-Text oder Metadateien unterstützen, diese Daten auch vorfinden - selbst wenn diese nicht direkt in die Zwischenablage abgelegt wurden.
Daten im Detail
Greift man mit der GetClipboardData-Funktion auf die Zwischenablage zu, so bekommt man immer einen Handle zu den eigentlichen Daten. Das heißt also, die Daten werden nicht direkt in der Zwischenablage abgelegt. Programme, die Daten in die Zwischenablage kopieren, legen hierzu einen Speicherblock fest, kopieren das Bitmap oder den Text in diesen Speicherblock und übergeben der Zwischenablage das Handle zu diesem Speicherblock. Dies macht die Sache für uns VisualBasic Programmierer etwas komplizierter. Andere Sprachen wie C++ sind es gewohnt mit Handles zu Speicherobjekten zu arbeiten, wir dagegen kennen nur unsere Variablen und Strukturen. Um an die Daten zu kommen, müssen wir in den meisten Fällen den Speicherblock anhand des Handles "einfrieren" und danach anhand des Pointers die Daten in die entsprechende Struktur oderVariable kopieren. Handles von Bitmaps oder Metadateien dagegen können direkt mit den dafür vorgesehenen API-Funktionen genutzt werden.
Die verschiedenen Formate kurz erklärt
Wie Eingangs erwähnt, erstellt Windows automatisch Kopien unserer Daten in andere zusätzliche Formate. Viele Programme stellen die Daten selbst ebenfalls in zusätzlichen Formaten bereit. Als Beispiel seien hier HTML- oder RTF-Text genannt. Diese Typen gehören leider nicht zu den Standard-Formaten der Zwischenablage und werden somit von Windows nicht erkannt. Das hat zur Folge, dass Windows diese Daten auch nicht in andere Formate konvertiert. Darum übernehmen Anwendungen wie Microsoft Word oder der Internet Explorer diese Aufgaben und legen selbst die Daten (Texte) in für die Anwendungen verarbeitbare Datentypen in der Zwischenablage ab. Um einen kleinen Überblick zu bekommen finden Sie nachfolgend eine Liste der Standardformate der Zwischenablage:
CF_BITMAP (Standard Bitmap)
Die Zwischenablage enthält unter diesem Format ein Handle auf ein Bitmap (hBitmap). Dieses Format wird von Windows automatisch angelegt, wenn eine Enhanced-Metadatei in die Zwischenablage kopiert wird.
CF_DIB (BITMAPINFO-Struktur)
Die Zwischenablage enthält unter diesem Format ein Handle zu einer BITMAPINFO-Struktur. Dieses Format wird von Windows automatisch angelegt, wenn ein Bitmap in die Zwischenablage kopiert wird.
CF_DIBV5 (BITMAPV5HEADER-Struktur)
Die Zwischenablage enthält unter diesem Format ein Handle zu einer BITMAPV5HEADER-Struktur. Dieses Format wird von Windows XP / 2000 automatisch angelegt, wenn ein Bitmap in die Zwischenablage kopiert wird.
CF_DIF (Software Arts' Data Interchange Format)
??
CF_DSPBITMAP (Standard Bitmap)
Die Zwischenablage enthält ein Handle zu einem Bitmap (hBitmap) in einem privaten Format.
CF_DSPENHMETAFILE (Standard Metadatei)
Die Zwischenablage enthält ein Handle zu einer Metadatei (hEnhMetaFile) in einem privaten Format.
CF_DSPMETAFILEPICT (METAFILEPICT-Struktur)
Die Zwischenablage enthält ein Handle zu einer METAFILEPICT-Struktur in einem privaten Format.
CF_DSPTEXT (Standard String)
Die Zwischenablage enthält ein Handle zu einem String in einem privaten Format.
CF_ENHMETAFILE (Enhanced Metadatei)
Die Zwischenablage enthält ein Handle zu einer Enhanced Metadatei (hEnhMetaFile). Dieses Format wird von Windows automatisch angelegt, wenn ein Bitmap in die Zwischenablage kopiert wird.
CF_GDIOBJFIRST bis CF_GDIOBJLAST (GDI Objekte)
Die Zwischenablage enthält ein Handle zu einem GDI-Objekt.
CF_HDROP (Dateiliste)
Die Zwischenablage enthält ein Handle zu einer Dateiliste, welche mit der DragQueryFile-Funktion ausgelesen werden kann.
CF_LOCALE (Sprach-ID)
Die Zwischenablage enthält ein Handle zu einer Long-Variablen, die eine Sprach-Konstante enthält, um die Sprache zu beschreiben, in der ein Text-String vorliegt. Dieses Format wird von Windows automatisch angelegt, wenn ein String in einem der Standardformate in die Zwischenablage kopiert wird.
CF_METAFILEPICT (METAFILEPICT-Struktur)
Die Zwischenablage enthält ein Handle zu einer METAFILEPICT-Struktur. Dieses Format wird automatisch angelegt, wenn eine Metadatei in die Zwischenanlage kopiert wird.
CF_OEMTEXT (Text String in OEM Format)
Die Zwischenablage enthält ein Handle zu einem String, der in einen OEM-Zeichensatz konvertiert worden ist. Dieses Format wird automatisch angelegt, wenn eines der Standard Text-Formate in die Zwischenablage kopiert wird.
CF_OWNERDISPLAY (Benutzerdefinierte Anzeige)
Über die GetClipboardOwner-Funktion erhält man das Fenster, welches den Inhalt der benutzerdefinierten Anzeige auf ein Gerät zeichnet, das in einer PAINTSTRUC-Struktur beschrieben ist. Zu diesem Zweck muss man mittels der SendMessage-Funktion dem Fenster die Nachricht "WM_PAINTCLIPBOARD" senden. Dabei muss der lParam-Wert der SendMessage-Funktion der Handle zu einer gefüllten PAINTSTRUC-Struktur sein.
CF_PALETTE (Farbpalette)
Die Zwischenablage enthält ein Handle zu einer Farbpalette (hPalette).
CF_PRIVATEFIRST bis CF_PRIVATELAST (Privates Format)
Die Zwischenablage enthält ein Handle zu einem privaten Format.
CF_PENDATA (Daten für Pen Extensions)
Die Zwischenablage enthält ein Handle zu Daten für Microsoft Pen Computing.
CF_RIFF (Audiodaten)
Die Zwischenablage enthält ein Handle zu Audiodaten, die komplexer als Wavedateien sind.
CF_SYLK (Symbolischer Link)
Die Zwischenablage enthält ein Handle zu einem symbolischen Link.
CF_TEXT (Standard Text String)
Die Zwischenablage enthält ein Handle zu einem Standard-Text-String. Dieses Format wird automatisch angelegt, wenn ein anderes Standard-Textformat der Zwischenablage hinzugefügt wird.
CF_WAVE (Wave Datei)
Die Zwischenablage enthält ein Handle zu einer Wave Datei.
CF_TIFF (Tiff Datei)
Die Zwischenablage enthält ein Handle zu einer Tiff-Datei.
CF_UNICODETEXT (Unicode Text)
Die Zwischenablage enthält ein Handle zu einem Unicode Text-String. Dieses Format wird automatisch angelegt, wenn eines der anderen Standard-Textformate der Zwischenablage hinzugefügt wird.
Wie lässt sich der Inhalt der Zwischenablage auslesen?
Über das Clipboard-Objekt in VB selbst lässt sich ja nur der Text bzw. das Bitmap (Bild) im Standard-Format auslesen. Um nun aber alle in der Zwischenablage vorhandenen Daten und Datenformate auslesen zu können, müssen wir wieder einmal auf das Windows-API zurückgreifen.
Öffnen der Zwischenablage
Das Öffnen der Zwischenablage erfolgt über die API-Funktion OpenClipboard. Die Funktion selbst erwartet lediglich das Handle des aufrufenden Fensters:
' Deklaration Declare Function OpenClipboard Lib "user32" ( _ ByVal hwnd As Long) As Long ' Aufruf Call OpenClipboard(Me.hwnd)
Schliessen der Zwischenablage
Immer, wenn die Zwischenablage per Code geöffnet wurde, muss diese nach Beenden der jeweiligen Aktion wieder geschlossen werden. Dies erfolgt über die API-Funktion CloseClipboard.
Declare Function CloseClipboard Lib "user32" () As Long
Alle in der Zwischenablage vorhandenen Datenformate ermitteln
Das Ermitteln aller in der Zwischenablage befindlichen Daten erfolgt über eine Schleife. Man prüft einfach alle möglichen Formate mit Hilfe der API-Funktion EnumClipboardFormats. Die Funktion gibt einen Wert ungleich 0 zurück, wenn Daten imParameter wFormat angegebenen Format vorhanden sind.
' benötigte Deklarationen Declare Function CountClipboardFormats Lib "user32" () As Long Declare Function EnumClipboardFormats Lib "user32" ( _ ByVal wFormat As Long) As Long ' Prüfen, welche Datenformate sich in der ' Zwischenablage befinden For i = 0 To CountClipboardFormats - 1 lngFormat = EnumClipboardFormats(lngFormat) If lngFormat = 0 Then Exit For ' Format auswerten Select Case lngFormat Case CF.CF_TEXT Case CF.CF_BITMAP Case CF.CF_WAVE Case CF.CF_DIB ... Case Else ' Benutzerdefinierter Typ End Select Next i
Auslesen der Daten der Zwischenablage
Für das Auslesen von Daten bestimmter Datenformate werden folgende API-Funktionen benötigt:
' Deklarationen Declare Function GetClipboardData Lib "user32" ( _ ByVal wFormat As Long) As Long Declare Function GlobalLock Lib "kernel32" ( _ ByVal hMem As Long) As Long Declare Function GlobalUnlock Lib "kernel32" ( _ ByVal hMem As Long) As Long Declare Function lstrlen Lib "kernel32" _ Alias "lstrlenA" ( _ ByVal lpString As Any) As Long
Text auslesen (Text, OEM Text, HTML-Format, RTF)
Das Auslesen von Textdaten erfolgt über die GetClipboardData-Funktion. Die Funktion selbst erwartet den Datentyp des Textes und gibt ein Handle auf den "Speicherblock" der Daten zurück.
Dim Tmpstr As String Dim pTmpStr As Long Dim hTmpStr As Long ' Zwischenablage öffnen OpenClipboard Me.hwnd ' Pointer zu dem String ermitteln hTmpStr = GetClipboardData(wFormat) pTmpStr = GlobalLock(hTmpStr) If pTmpStr <> 0 Then Tmpstr = Space(lstrlen(ByVal pTmpStr)) Call lstrcpy(ByVal Tmpstr, ByVal pTmpStr) ... ' Pointer wieder freigeben GlobalUnlock hTmpStr End If ' Clipboard schließen CloseClipboard
Bitmap auslesen
Das Auslesen eines Bitmaps erfolgt zunächst ebenfalls über die GetClipboardData-Funktion. Als Rückgabewert erhält man das Handle des Bitmaps. Über die SelectObject-API lässt sich das Bild dann z.B. in einer PictureBox anzeigen:
' Deklaration Declare Function SelectObject Lib "gdi32" ( _ ByVal hdc As Long, _ ByVal hObject As Long) As Long ' Bitmap auslesen und anzeigen ' Clipboard öffnen OpenClipboard Me.hwnd ' Handle des Bitmaps ermitteln hBitmap = GetClipboardData(CLng(Item.Text)) If hBitmap <> 0 Then ' Bitmap anzeigen Picture1.Cls Picture1.Refresh SelectObject Picture1.hdc, hBitmap Picture1.Refresh End If ' Clipboard schließen CloseClipboard
Weitere Datenformate
Wie man die Daten der anderen Formate ermittelt (z.B. Metafile-Dateien), das zeigt Ihnen unserBeispielprojekt.
Das Beispielprojekt
Passend zum Workshop haben wir natürlich ein entsprechendes Beispiel erstellt. Hierbei handelt es sich um einen Clipboard-Viewer, d.h. die Zwischenablage wird ständig geprüft und alle vorhandenen Daten in den verschiedensten Formaten in einer Liste angezeigt. Sofern sich der Inhalt eines Datentyps (Text/Bitmap usw.) anzeigen lässt, kann dieser durch Anklicken innerhalb der Liste gelesen und angezeigt werden.
Zusätzlich wird zu jedem Eintrag die ID, der Datentyp selbst, sowie das Handle ermittelt und aufgelistet.