Tutorial
Windows Drag und Drop Tutorial
von stephanbrunker | Seite 9 von 12 |
Datenaustausch mit der Zwischenablage
Es ist fast schon ein Abfallprodukt: Ist man soweit gekommen, dann kann man den Datenaustausch über die Zwischenablage quasi nebenbei implementieren, da es mit dem gleichen Dataobject funktioniert wie Drag&Drop. Wir müssen, um unnötige Fehlermeldungen zu vermeiden, weitere Funktionen neu deklarieren damit sie mit unseren Interfaces klarkommen. Spätestens jetzt wird es deutlich übersichtlicher, wenn wir vor und nach jedem neuen Typ die mit ihm zusammenhängenden Typen neu deklarieren:
Declare Function OleSetClipboard Alias "OleSetClipboard" (ByVal as IDataObject Ptr) as HRESULT
Declare Function OleIsCurrentClipboard Alias "OleIsCurrentClipboard" (ByVal As IDataObject Ptr) As HRESULT
Declare Function OleGetClipboard Alias "OleGetClipboard" (ByVal As IDataObject Ptr Ptr) As HRESULT
Kopieren zur Zwischenablage
Kopieren zur Zwischenablage ist dann denkbar einfach, wir fragen die WM_NOTIFY/LVN_KEYDOWN Message nach der Tastenkombination STRG+C ab und übergeben das an unsere DataTransfer-Funktion mit den (schon existierenden) Flags:
Case LVN_KEYDOWN
'Key pressed while focus on listview
Dim lpnmhdrkey As NMLVKEYDOWN Ptr = Cast(NMLVKEYDOWN Ptr,lParam)
Dim keystate As Short
Select Case lpnmhdrkey->wVKey
Case VK_DELETE 'Delete Key
DeleteListViewSelRows(hLSV1)
Case VK_C 'C Key
keystate = GetKeyState(VK_CONTROL)
If Bit(keystate,15) = - 1 Then 'CONTROL pressed
Print "copy to clipboard"
DataTransfer(hLSV1,C_HDROP,STRGC)
EndIf
Diese Funktion bekommt dann am Ende die Variante für die Zwischenablage:
Dim pDataObject As IDATAOBJECT Ptr = New IDATAOBJECT(fmtetc(),stgmed())
pDataSelf=pDataObject
'Drag&Drop operation
If (cAction And DRAGDROP) Then
.....
'Clipboard copy
ElseIf (cAction And STRGC) Then
OleSetClipboard(pDataObject)
EndIf
Wir sehen an unseren Print-Mitteilungen, dass in diesem Fall eine Instanz des IDataObjects erhalten bleibt nachdem die Operation beendet ist. Klar, wir können ja die Zwischenablage beliebig oft woanders hineinkopieren. Um das ganze sauber am Programmende aufzulösen, bekommt die WM_CLOSE - Abfrage noch eine Prozedur für die Zwischenablage, die unsere Referenz freigibt und Windows-Intern davon eine Kopie erstellt, mit der wir nichts mehr zu tun haben:
'release DataObject from Clipboard if it's still there
If OleIsCurrentClipboard(pDataSelf)=S_OK Then
Print "FlushClipboard"
OleFlushClipboard()
EndIf
Einfügen aus der Zwischenablage
In der Gegenrichtung machen wir im Prinzip das Gleiche, was wir vorher im IDropTarget::DragEnter und ::Drop implementiert haben: Eine Abfrage, ob das gewünschte Format im Datenobjekt enthalten ist und dieses dann an unsere DataDrop-Funktion übergeben:
Case VK_V 'V Key
keystate = GetKeyState(VK_CONTROL)
Dim index As Integer
Dim stgmed As STGMEDIUM
Dim fmtetc (0 To 0) As FORMATETC
fmtetc(0)=divfmtetc(0)
Dim pDataObject As IDATAOBJECT Ptr
If Bit(keystate,15) = - 1 Then 'CONTROL pressed
Print "Get Data from clipboard"
If OleGetClipboard(@pDataObject) = S_OK Then
'Check if clipboard dataobject support CF_HDROP
For index=0 To UBound(fmtetc)
If pDataObject->QueryGetData(@fmtetc(0)) = S_OK Then
pDataObject->GetData(@fmtetc(index),@stgmed)
DataDrop(hLSV1,@fmtetc(index), @stgmed)
Exit For
End If
Next index
EndIf
EndIf
End Select
Speziell in unserem Beispiel sollten wir uns nicht verrückt machen, wenn das jetzt nicht klappt: Der Windows-Explorer liefert bei den Clipboard-Formaten nämlich kein CF_HDROP mit. Wir können aber aus unserer eigenen Anwendung kopieren, die schließen, neu starten und einfügen - funktioniert. Aber es geht ja nur ums Prinzip .. jeder sollte das jetzt genauso für CF_TEXT oder andere Formate implementieren können. Daran denken: Die Funktionen OleSetClipboard, OleIsCurrentClipboard und OleGetClipboard müssen wieder umdefiniert werden.
DragDrop4.zip
Erweiterte Cursor-Rückmeldungen
Der nächste Punkt ist kein Tutorial, sondern ein Link - vielleicht macht ja jemand anderes einen FB-Code daraus:
Shell Drag-Drop Helper
Es geht um die seit Windows 2000 implementierte erweiterte Drag-Drop-Funktionalität, die zum Beispiel Bilder beim Verschieben unter dem Cursor zeigt. Sicherlich ein schönes Projekt, dafür die IDropTargetHelper und IDropSourceHelper - Interfaces zu programmieren.
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|