Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Windows Drag und Drop Tutorial

von MitgliedstephanbrunkerSeite 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.

Externer Link!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:
Externer Link!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.

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  8  9  10  11  12  
Zusätzliche Informationen und Funktionen
  Bearbeiten Bearbeiten  

  Versionen Versionen