Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Wie DragDrop-Ende signalisieren? (https://www.delphipraxis.net/209629-wie-dragdrop-ende-signalisieren.html)

Benmik 1. Jan 2022 16:43

Wie DragDrop-Ende signalisieren?
 
In meinem Programm realisiere ich DragDrop sowohl innerhalb der Delphi-Anwendung als auch nach außerhalb; Letzteres mit der The-Drag-and-Drop-Component-Suite-for-Delphi von Sven Harazim (ehemals Anders Melander). Das funktioniert auch.

Wenn ich anfange, ein Objekt zu ziehen, dann startet Delphi DragDropBegin - zu diesem Zeitpunkt ist ja noch nicht klar, wohin das Objekt geht. Wenn ich es nun in ein anderes Windows-Programm außerhalb der Delphi-Anwendung ziehe und dann wieder zurückkehre, dann hat die Delphi-Anwendung nicht mitbekommen, dass DragDrop vorbei ist. Es gibt zwar bei der Komponente das Ereignis AfterDrop, das auch ausgelöst wird, aber es gelingt mir nicht, damit das Delphi-DragDrop abzubrechen, und auch das manuelle Setzen des Mauszeiger zeigt keine Wirkung. Müsste man sowas wie DragFinish senden, und wenn ja, wie? Oder wie macht man das?

Uwe Raabe 1. Jan 2022 17:30

AW: Wie DragDrop-Ende signalisieren?
 
Kannst du mal ein minimales Codebeispiel zeigen?

Benmik 1. Jan 2022 19:48

AW: Wie DragDrop-Ende signalisieren?
 
Hallo Uwe,

Frohes Neues Jahr!

Anbei ein Minimalbeispiel, leider muss dazu die erwähnte Komponente installiert sein. Das Beispiel besteht lediglich aus der Form mit einem TPanel darauf, dazu noch ein DropFileSource. Für die Demonstration muss es die Datei "C:\Temp\Test01.jpg" noch nicht mal geben.

Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
begin
  Panel1.Caption := 'C:\Temp\Test01.jpg';
  Panel1.DragMode := dmAutomatic;
end;

procedure TForm3.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  DropFileSource1.Files.Clear;
  DropFileSource1.Files.Add(Panel1.Caption);
end;

procedure TForm3.DropFileSource1GetDragImage(Sender: TObject; const DragSourceHelper: IDragSourceHelper; var Handled: Boolean);
var
  Pt: TPoint;
begin
  GetCursorPos(Pt);
  Handled := Succeeded(DragSourceHelper.InitializeFromWindow(Panel1.Handle, Pt, TCustomDropSource(Sender) as IDataObject));
end;

procedure TForm3.Panel1StartDrag(Sender: TObject; var DragObject: TDragObject);
begin
  DropFileSource1.Execute(False);
end;

Gausi 1. Jan 2022 21:15

AW: Wie DragDrop-Ende signalisieren?
 
Wenn du das StartDrag-Event des Panels benutzt, dann sollte das Ende beim OnEndDrag-Event des Panels behandelt werden können. Oder kommt das auch nicht an?

Benmik 1. Jan 2022 21:59

AW: Wie DragDrop-Ende signalisieren?
 
Das OnEndDrag-Event des Panels findet nicht statt, wenn ich zur Anwendung zurückkehre (z.B. mit ALT-TAB), sondern erst, wenn ich wieder auf das Panel klicke. Bis dahin zeigt der Mauszeiger aber "Kein-DragDrop" und die DragDrop-Aktion ist offensichtlich noch nicht abgeschlossen, was ich gern programmatisch erreichen würde.

Uwe Raabe 1. Jan 2022 23:01

AW: Wie DragDrop-Ende signalisieren?
 
Wenn du
Delphi-Quellcode:
DragSource.Execute(False)
(oder nur Execute) aufrufst, wird das DragDrop synchron gestartet und gibt im Result das Ergebnis der Operation zurück. Damit das VCL-Dragging nicht weiter dazwischen funkt, solltest du das über einen Aufruf von
Delphi-Quellcode:
Abort
am Ende des StartDrag-Events beenden.

Das sollte insbesondere auch beim asynchronen Aufruf erfolgen.

Benmik 2. Jan 2022 00:08

AW: Wie DragDrop-Ende signalisieren?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1499943)
...Aufruf von
Delphi-Quellcode:
Abort
am Ende des StartDrag-Events...

Das funktioniert prima - aber leider legt es natürlich auch das DragDrop innerhalb der Delphi-Anwendung lahm. Ich hatte schon überlegt, ob ich die beiden Drag-Modi differenzieren sollte (durch die ALT-Taste, z.B.), aber ich fände es schon nett, wenn das bequemer ginge. Es funktioniert ja auch, man muss am Ende nur kurz nochmal klicken, aber das Ganze stört und ist unelegant.
Man müsste das Abort irgendwie nur dann einklemmen, wenn es ein OnAfterDrop des DropFileSource gegeben hat. Geht das per Message oder so?

Gausi 2. Jan 2022 07:57

AW: Wie DragDrop-Ende signalisieren?
 
Heißt das, deine Anwendung reagiert selbst nicht auf das Droppen von DragSource? Das solltest du aber tun - nur im Drop rufst du dann nicht die Dateien aus dem D&D-Object ab, sondern rufst den "VCL-Drag&Drop"-Code aus.

Falls du in deiner Anwendung auch den Drop von Dateien (z.B. vom Explorer aus) erlauben willst, dann könntest du die beiden Drop-Varianten z.B. dadurch unterscheiden, dass du beim Beginn eines Drag-Vorgangs ein Flag setzt "Drop von Intern", und dieses bei jedem Drop (inkl. bei OnAfterDrop der Komponente, wenn nach draußen gezogen wurde) zurücksetzt auf "Extern".

Aber generell ist eine Kombination aus OLE-D&D und VCL-D&D keine sonderlich gute Idee. Das merke ich grade selbst auch (vgl. https://www.delphipraxis.net/209613-...-explorer.html). Mein Fall ist da etwas anders, weil mein Problem beim Erlauben bzw. Verbieten der "Move"-Operation liegt. Bzw. kommt bei mir unter Umständen ein doppeltes OnDrop-Event an. Aber das Grundproblem ist gleich: VCL und Windows sind beim Thema Drag&Drop nicht wirklich kompatibel. :(

Benmik 2. Jan 2022 11:00

AW: Wie DragDrop-Ende signalisieren?
 
Zitat:

Zitat von Gausi (Beitrag 1499945)
...VCL und Windows sind beim Thema Drag&Drop nicht wirklich kompatibel. :(

Da hast du offenbar Recht. Sowohl von der VCL als auch von der Komponente wird DragDrop gestartet, aber beendet wird es nur von dem, der zum Zuge kommt.

Zum Verständnis: Es geht um Bilddateien, deren Vorschaubilder auf ein Panel gezeichnet sind. Bisher wurde DragDrop innerhalb der Anwendung genutzt (z.B. um Bilder zu verschieben o.ä.). Nun möchte ich aber gern auch Bilder aus dem Panel auf andere Programme ziehen. Das ging bisher auch über ein Kontextmenü, aber mit Nachteilen (u.a. funktioniert das bei einigen Programmen nicht). Konkret geht es hier um die Desktopversion von Signal, wo man durch Ziehen die Bilder direkt an einen bestimmmten Kontakt senden kann. Wenn also BeginDrag startet, dann weiß das Programm noch nicht, was der Anwender vorhat (er selbst vielleicht auch noch nicht).

Ich brauche also VCL und OLE. Es funktioniert ja auch, aber beide werden gestartet und einer "hängt" dann, bis man noch einmal klickt. Wenn ich bei DragBegin durch eine Tastenkombination festlegen würde, um welche Aktion es geht, dann wäre das Problem gelöst (und da ist Abort sehr hilfreich), aber ich hätte es natürlich gern "automatisch".

(Muss jetzt arbeiten, kann also erst wieder heute Abend weitermachen).

Uwe Raabe 2. Jan 2022 11:14

AW: Wie DragDrop-Ende signalisieren?
 
Du musst dich für eins entscheiden: OLE oder VCL. Wenn du OLE brauchst und gleichzeitig die eigene Anwendung auch als Drop-Target herhalten soll, dann kannst du das mit der TDragTarget Komponente derselben Library realisieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:32 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz