in C++

[C++]: Drag & Drop auf eine Form

Wie schon vor einer ganzen Weile auf chris-blog.com angekündigt, zeige ich euch heute wie man in einer Windows-Anwendung Drag & Drop implementieren kann. Wie immer gilt: Ich verwende den C++ Builder von Embarcadero (in der Version XE6). Da es sich aber um Windows-Funktionen handelt sollte dies in anderen Compilern (mit kleineren Abweichungen) genauso funktionieren. Also legen wir los.

Drag & Drop auf eine Form

Als erstes habe ich eine neues VCL-Projekt erstellt. Auf der der Form muss als erstes Drag & Drop erlaubt werden und dann gleiche OLE initialisiert werden. Beim schließen muss OLE natürlich wieder deinitialisiert werden. Das ist ganz einfach und sind nur ein paar Zeilen Code. Hier der Konstruktor und Destruktor meiner Form:

Als nächstes brauchen wir eine neue Klasse (Unit). Diese wird vom Interface IDropTarget abgeleitet. Die Header mit den entsprechenden Funktionen die benötigt werden sieht folgendermaßen aus:

Die Header-Datei sieht jetzt zwar noch ziemlich wild aus, wenn ihr euch die folgenden Funktionen aber nach und nach anseht, wird aber schnell klar wozu die Funktionen und Variablen gut sind.

Als erstes der Konstruktor. Dazu brauch ich wohl nicht recht viel zu sagen. Hier werden einfach die Variablen initialisiert:

Als nächstes sehen wir uns die Funktion DragEnter an. Dabei wird mit der Funktion QueryDataObject als erstes geprüft ob das entsprechende Objekt überhaupt auf die Form „gedropt“ werden darf. Danach wird in Abhängigkeit der Shift-/Strg-Taste geprüft ob das Objekt kopiert oder verschoben werden soll.

Wie schon erwähnt wird mit der Funktion QueryDataObject geprüft ob wir die entsprechende Datei annehmen. Außerdem ist es noch wichtig zu unterscheiden ob es sich um „virtuelle“ oder normale Dateien handelt. Normale Dateien sind z. B. .txt-Dateien, .iso-Datein, usw., „virtuelle“ Dateien sind z. B. E-Mails, die man direkt aus Outlook in das eigene Programm zieht.

Und hier gleich die Funktion mit der geprüft wird ob die Datei verschoben oder kopiert werden soll:

Damit ist ein Großteil schon geschafft. Hier noch die Funktionen DragOver und DragLeave zu denen ich nicht viel sagen muss:

Die vorletzte Funktion die ich Zeige ist die Drop-Funktion. Diese bestimmt welche Aktion ausgeführt werden soll.

Wie man sieht, macht auch diese Funktion nicht sehr viel. Im Grunde ruft sie nur die Funktion DropData auf. Dies ist nun die größte und „schwierigste“ Funktion. Danach ist es aber geschafft.

Als erstes sehen wir uns an wie man normale Dateien verschieben und kopieren kann. Nachdem geprüft wurde ob überhaupt eine Datei übergeben wurde und ob dies eine normale Datei ist, muss die Datei in eine STGMEDIUM-Struktur gelegt werden. Falls das geklappt hat, wird der hGlobal-Teil von STGMEDIUM in eine HDROP-Variable gecastet.
Danach muss nur noch über DragQueryFile die Anzahl der Dateien ermittelt werden und in einer Schleife dann wieder per DragQueryFile der Dateiname. Dann einfach noch prüfen ob verschoben oder kopiert werden soll und schon kann man die Aktion starten:

Etwas schwieriger wirds da schon wenn es sich um eine „virtuelle“ Datei handelt, aber auch dass ist machbar. Dabei werden alle übergebenen „virtuellen“-Dateien durchgelaufen und geschaut ob es sich um eine Email oder um einen Anhang handelt. Je nachdem wird dann (für eine Mail) über ein IStorage-Objekt gespeichert und für Anhänge muss ein Umweg über ein Byte-Array und einen TMemoryStream gegangen werden. So sieht der Code aus:

Das wars, nun ist die Form Drag & Drop-Fähig.

Hier Kann wie üblich das Fertige Projekt heruntergeladen werden.

Du hast Fragen, Anregungen, o. ä.? Ich freue mich wenn du einen Kommentar hinterlässt!

Write a Comment

Comment

Time limit is exhausted. Please reload the CAPTCHA.

  1. Hab das mal probiert wenn ich aber das Programm in Win 8.1 über den Totalcommander starte und den Drop über den WindowsExplorer durchführe funktioniert nix mehr, das Problem habe ich übrigens bei all meinen anderen Programmen auch. Woran liegt das ?