Drag and Drop Dropfiles versus sonstiges Drag and Drop

Rund um die LCL und andere Komponenten
Antworten
Martin V
Beiträge: 142
Registriert: Sa 30. Jan 2010, 19:35
OS, Lazarus, FPC: Linux64, Wiindows32, MacOS, Lazarus 1.8.2
CPU-Target: xxBit

Drag and Drop Dropfiles versus sonstiges Drag and Drop

Beitrag von Martin V »

Es gibt zwei unterschiedliche Implemenationen von Drag and Drop in der lcl: zum einen das externe Drag and Drop von Datei-Icons in eine Form. Hier kann man sehr einfach mit tForm.OnDropFiles eine Procedure schreiben, in der die Aktivität beim Fallenlassen des Datei-Icons über der Form dann stattfindet. Man muß lediglich tForm.AllowDropFiles auf TRUE setzen.

Unabhängig davon gibt es eine allgemeine Drag-and-Drop Funktionalität, die für programminterne Drag and Drop Vorgänge bestimmt sind. Hierfür gibt es Methoden wie BeginDrag, OnDragOver usw.

Ich möchte nun in meinem Programm (einem Editor) an eine bestimmte Stelle meines Controls (meine Editorkomponente) eine Textdatei an einer bestimmten Stelle plazieren können, um diese in den Text einfügen zu können. Das klingt auf den ersten Blick leicht, doch steht mit OnDropFiles lediglich eine allgemeine Drag-and-Drop-Funktionalität zur Verfügung, die außer OnDragDrop keine Events produziert (kein DragOver, nicht einmal MouseMove!) und z. B. keine Mauskoordinaten abrufen läßt. Man könnte jetzt theoretisch mit einem Timer die Mauskoordinaten und das aktuelle Mousecursor-Icon abfragen und so Rückschlüsse auf den Drag and Drop file Vorgang schließen. Aber das kann es nicht wirklich sein. Hat jemand eine Idee, wie man im Prinzip das Problem lösen könnte?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Drag and Drop Dropfiles versus sonstiges Drag and Drop

Beitrag von Michl »

Ich mache das nicht über einen Timer, sondern in etwa so:

Code: Alles auswählen

procedure TForm1.FormDropFiles(Sender: TObject;
  const FileNames: array of String);
var
  aControl: TControl;
begin
  aControl := FindControlAtPosition(Mouse.CursorPos, false);
  if Assigned(aControl) then
    ShowMessage('Files könnten ' + aControl.Name + ' zugewiesen werden!');
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Martin V
Beiträge: 142
Registriert: Sa 30. Jan 2010, 19:35
OS, Lazarus, FPC: Linux64, Wiindows32, MacOS, Lazarus 1.8.2
CPU-Target: xxBit

Re: Drag and Drop Dropfiles versus sonstiges Drag and Drop

Beitrag von Martin V »

Danke für den Hinweis. Mehr ist wohl nicht drin. Es gibt nur einen Event beim Fallenlassen, und dort muß man dann alles machen. D.h. man kann den Cursor nicht mit der Maus mitziehen lassen, da nicht einmal MouseMove funktioniert. Aber im Prinzip geht es, ich konnte es vernünftig umsetzen. Dabei konnte ich sogar unterscheiden, ob sich der Mauszeiger über dem Editcontrol befindet oder nicht und dann zwischen "neue Datei laden" und "Text an Mausposition einfügen" unterscheiden.

Weiß jemand, ob man mit lcl ein Drag and Drop von einer Form in eine andere umsetzen kann? Von einem Programm zum anderen geht das wohl nicht, das ist hier beschrieben: http://wiki.freepascal.org/LCL_Drag_Drop
Das gilt vermutlich auch, wenn beide Programme lcl Programme sind, ich bin aber nicht sicher.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Drag and Drop Dropfiles versus sonstiges Drag and Drop

Beitrag von Michl »

Martin V hat geschrieben:Weiß jemand, ob man mit lcl ein Drag and Drop von einer Form in eine andere umsetzen kann?
Warum probierst du es nicht einfach aus? Habe es eben unter Windows probiert - es funktioniert hier - einfaches Testbeispiel anbei.
Martin V hat geschrieben:Von einem Programm zum anderen geht das wohl nicht, das ist hier beschrieben: http://wiki.freepascal.org/LCL_Drag_Drop
Das gilt vermutlich auch, wenn beide Programme lcl Programme sind, ich bin aber nicht sicher.
Unter Windows geht das schon (hatte ich mal irgendwann getestet - weiss nicht, ob ich den Test noch irgendwo rumliegen hab). Siehe aber auch: http://wiki.lazarus.freepascal.org/Drag ... le#Windows

Ansonsten könntest du auch mal dieses Package probieren (ungetestet): https://github.com/prof7bit/NativeDragDrop
Dateianhänge
DragDrop2Forms.zip
(4.01 KiB) 55-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Martin V
Beiträge: 142
Registriert: Sa 30. Jan 2010, 19:35
OS, Lazarus, FPC: Linux64, Wiindows32, MacOS, Lazarus 1.8.2
CPU-Target: xxBit

Re: Drag and Drop Dropfiles versus sonstiges Drag and Drop

Beitrag von Martin V »

Danke für das Beispiel. Die Umsetzung von Drag and Drop von einer Form zu einer anderen ist wirklich sehr einfach und ist mir in meinem Programm auf Anhieb gut gelungen. Bemerkenswert ist, dass das abschließende DoEndDrag Event von der Quellform verwaltet wird (deshalb auch der Parameter Target : tObject), obwohl es in der Zielform stattfindet. Quell- und Zielform sind bei mir beides dieselbe Objektklasse. Wenn target = self, dann findet der Drop innerhalb derselben Form statt, wenn nicht, dann ist es eine fremde Form, über die ich via Target... Zugriff habe. Der DragOver Event wird dagegen von der Zielform verwaltet (deshalb der Parameter Source : tObject), hier muß man mit der property Accept festlegen, ob der Drop erlaubt ist oder nicht.

Was aber wohl gar nicht geht, ist von einem Lazarus Programm zu einem anderen bzw. zwischen zwei Instanzen desselben Programms.

Antworten