Sign in Join
Wiki copytemporary

Drag and Drop/de: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-\
21Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
3-\
4-\
2+
53Dieser Artikel beschäftigt sich mit der Windows- und der Linuxprogrammierung.\
64Dieser Artikel bezieht sich auf Lazarus Version 1.0.10 und höher.\
7-\
5+
86=Grundlegendes zu Drag and Drop= Drag and Drop ist eine Methode zur Bedienung grafischer Benutzeroberflächen.\
97Bei einem Drag and Drop Vorgang sind immer zwei Objekte beteiligt. Das sendende Objekt und das entgegennehmende Objekt.\
10-\
118
129# Drag and Drop innerhalb eines Formulars
1310
14-\
1511Damit ein Objekt senden kann, benötigt es genau ein Ereignis:\
1612* OnMouseDown\
1713Damit ein Objekt empfangen kann, benötigt es zwei Ereignise:\
1814* OnDragDrop
1915
2016- OnDragOver
2117
22-\
2318==Das OnMouseDown-Ereignis des sendenden Objekts== Beispiele wie ein OnMouseDown-Ereignis des sendenden Objektes aussehen kann:\
2419===Beispiel für ein Edit===
2520
2621``` pascal
2722procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
2823 Shift: TShiftState; X, Y: integer);
2924begin
3025 if Button = mbLeft then
3126 Edit1.BeginDrag(False); // False, damit Drag and Drop erst nach einer Mausbewegung beginnt
3227end;
3328```
3429
35-\
3630===Beispiel für ein Memo===
3731
3832``` pascal
3933procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton;
4034 Shift: TShiftState; X, Y: Integer);
4135begin
4236 if Button = mbLeft then
4337 Memo1.BeginDrag(False); // False, damit Drag and Drop erst nach einer Mausbewegung beginnt
4438end;
4539```
4640
47-\
4841==Die Ereignisse OnDragDrop, OnDragOver und EndDrag des empfangenden Objekts==
4942
5043### Beispiel für ein Edit, wenn ein Edit der Sender ist
5144
5245``` pascal
5346// Auswerten, ob es sich um den richtigen Sendertyp handelt
5447// und nicht, ob es sich um den richtigen Sender handelt
5548procedure TForm1.Edit2DragOver(Sender, Source: TObject; X, Y: integer;
5649 State: TDragState; var Accept: boolean);
5750begin
5851 if (Source is TEdit) then // Fragt den Objekttyp ab
5952 Accept := True; // Wenn der Objekttyp stimmt ist der Datensatz zu akzeptieren
6053end;
6154
6255// Datenübernahme
6356procedure TForm1.Edit2DragDrop(Sender, Source: TObject; X, Y: integer);
6457begin
6558 if (Source is TEdit) then // Wenn der Objekttyp stimmt werden die Daten übernommen
6659 Edit2.Text := TEdit(Source).Text;
6760end;
6861
6962// Fehlerauswertung
7063procedure TForm1.Edit2EndDrag(Sender, Target: TObject; X, Y: Integer);
7164begin
7265 if (Target = nil) then // Wenn beim Drag and Drop ein Fehlerauftritt
7366 Showmessage('Bei Drag and Drop ist ein Fehler aufgetreten.');
7467end;
7568```
7669
77-\
7870===Beispiel für eine Listbox, wenn ein Edit der Sender ist===
7971
8072``` pascal
8173// Auswerten, ob es sich um den richtigen Sendertyp handelt
8274// und nicht, ob es sich um den richtigen Sender handelt
8375procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: integer;
8476 State: TDragState; var Accept: boolean);
8577begin
8678 if (Source is TEdit) then // Fragt den Objekttyp ab
8779 Accept := True; // Wenn der Objekttyp stimmt ist der Datensatz zu akzeptieren
8880end;
8981
9082// Datenübernahme
9183procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: integer);
9284begin
9385 if (Source is TEdit) then // Wenn der Objekttyp stimmt werden die Daten übernommen
9486 Listbox1.Items.Add(TEdit(Source).Text); // Fügt den Text aus dem Edit hinzu
9587end;
9688
9789// Fehlerauswertung
9890procedure TForm1.ListBox1EndDrag(Sender, Target: TObject; X, Y: integer);
9991begin
10092 if (Target = nil) then // Wenn beim Drag and Drop ein Fehlerauftritt
10193 ShowMessage('Bei Drag and Drop ist ein Fehler aufgetreten.');
10294end;
10395```
10496
105-\
10697===Beispiel für ein Treeview, wenn ein Edit der Sender ist===
10798
10899``` pascal
109100// Auswerten, ob es sich um den richtigen Sendertyp handelt
110101// und nicht, ob es sich um den richtigen Sender handelt
111102procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: integer;
112103 State: TDragState; var Accept: boolean);
113104begin
114105 if (Source is TEdit) then // Fragt den Objekttyp ab
115106 Accept := True; // Wenn der Objekttyp stimmt ist der Datensatz zu akzeptieren
116107end;
117108
118109// Datenübernahme
119110procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: integer);
120111var
121112 tv: TTreeView;
122113 Knoten: TTreeNode;
123114
124115begin
125116
126117 tv := TTreeView(Sender); // Sender is TreeView where the data is being dropped
127118 Knoten := tv.GetNodeAt(x, y); // x,y sind die Drop Koordinaten im Baum des Treeview
128119
129120 // Wenn der Objekttyp stimmt werden die Daten übernommen
130121 if Source is TEdit then
131122 // nun werden die Daten dem Knoten hizugefügt
132123 tv.Items.AddChild(Knoten, TEdit(Source).Text);
133124
134125end;
135126
136127// Fehlerauswertung
137128procedure TForm1.TreeView1EndDrag(Sender, Target: TObject; X, Y: integer);
138129begin
139130 if (Target = nil) then // Wenn beim Drag and Drop ein Fehlerauftritt
140131 ShowMessage('Bei Drag and Drop ist ein Fehler aufgetreten.');
141132end;
142133```
143134
144-\
145-
146135# Drag and Drop vom Dateimanager auf das Formular
147136
148137Vorab:\
149138Fast jedes Betriebsystem bringt einen oder mehrere Dateimanager mit, das heisst, dass das Funktionieren von Drag and Drop nicht mit jedem Dateimanager garantiert werden kann.\
150139Dateimanager sind z. B.:\
151140Explorer (Betriebsystem Windows), Nautilus (Betriebssystem Ubuntu), Dolphin, Konqueror, usw.\
152-\
141+
153142Vorgehensweise:\
154-Zu erst muss im Objektinspektor des Formulars im Register Eigenschaft die Eigenschaft <b>AllowDropFiles</b> auf True gesetzt werden.\
155-\
143+Zu erst muss im Objektinspektor des Formulars im Register Eigenschaft die Eigenschaft AllowDropFiles auf True gesetzt werden.\
144+
156145![](/wiki-images/3/3f/DragDropEigenschaften.jpg)\
157-\
158-Dann wird im Objektinspektor des Formulars im Register Ereignisse das Ereignis <b>OnDropFiles</b> ausgewählt.\
159-\
146+
147+Dann wird im Objektinspektor des Formulars im Register Ereignisse das Ereignis OnDropFiles ausgewählt.\
148+
160149![](/wiki-images/f/f1/DragDropEreignisse.jpg)\
161-\
162-Um zum Beispiel die Dateien in einer ListBox an zuzeigen, wird für das Ereignis <b>OnDropFiles</b> folgender Code benötigt:\
150+
151+Um zum Beispiel die Dateien in einer ListBox an zuzeigen, wird für das Ereignis OnDropFiles folgender Code benötigt:\
163152===Minimalbeispiel zu OnDropFiles===
164153
165154``` pascal
166155procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of string);
167156var
168157 intI: integer = 0;
169158begin
170159
171160 for intI := 0 to high(filenames) do
172161 listbox1.Items.Add(filenames[intI]);
173162
174163end;
175164```
176165
177-\
178-
179166## Ein Beispiel dass Probleme bei OnDropFiles erläutert
180167
181-\
182168Dieses Beispiel beschäftigt sich mit Besonderheiten editierbarer Felder und der Auswertung des Drop.\
183169Dieses Beispiel beschäftigt sich auch mit Besonderheiten der Linuxprogrammierung.\
184-\
170+
185171===Probleme=== Beim Ziehen auf ein Formular entstehen folgende Effekte:
186172
1871731. Der Drop kann auf das Formular selbst oder ein Komponente auf dem Formular erfolgen, wo spielt keine Rolle, aber es wird kein Zielpunkt übergeben
1881742. Editierbare Felder fügen den erhaltenen Text automatisch ein! Alle Anderen nicht.
189-3. Zusätzlich fügen diese Felder automatisch eine Kennung hinzu z.B. <b>file:</b> oder <b>url:</b>
190-4. <b>Das Ereignis wird vom Formular in jedem Fall verarbeitet</b>, es ist nicht möglich den Drop durch das Editierfeld zu verweigern, abzubrechen oder umzuleiten
175+3. Zusätzlich fügen diese Felder automatisch eine Kennung hinzu z.B. file: oder url:
176+4. Das Ereignis wird vom Formular in jedem Fall verarbeitet, es ist nicht möglich den Drop durch das Editierfeld zu verweigern, abzubrechen oder umzuleiten
1911775. Wegen 2. wird u.U. doppelt eingefügt, wenn nicht geprüft wird, wo der Drop erfolgt
192178
193-\
194-<b>Hinweis:</b> Um 'einfach' ein <b>Drop-Ereignis auf ein editierbares Element zu verhindern</b>, kann es auf <b>Readonly</b> gesetzt werden. Der Cursor zeigt dann, dass das Feld keinen Drop annimmt. Eine bessere Lösung kann ich derzeit nicht anbieten.
179+Hinweis: Um 'einfach' ein Drop-Ereignis auf ein editierbares Element zu verhindern, kann es auf Readonly gesetzt werden. Der Cursor zeigt dann, dass das Feld keinen Drop annimmt. Eine bessere Lösung kann ich derzeit nicht anbieten.
195180
196181### Aufbau des Beispiels
197182
198183Das Beispiel besteht aus zwei ListView-Elementen, da diese auf den FileDrop nicht weiter reagieren, es könnten aber auch andere sein (sollten nur keine editierbaren sein). Diese Element haben sonst keine Aufgaben. Ein Memo-Element wird zur Ausgabe der Ergebnisse benutzt. Hier kann auch ein reiner Text-Drop<sup>*</sup>) aus einem Editierfeld überprüft werden (markieren und ziehen).\
199184<sup>*</sup>) In wie weit meine Desktopumgebung (Debian+KDE4) hier automatismen verwendet die zu einem anderem Verhalten führen als geplant, kann ich bisher nicht nachvollziehen.\
200185====Zusätzlich benötigte Units====
201186
202187- baseunix
203188- types
204189
205-\
206-====Benötigt Funktionen für Linux (basierend auf <i>baseunix</i>)==== Mit Linux wird im Prizip (fast) alles als Datei behandelt. Anhand des Pfades ist zunächst nicht erkennbar was dahinter steckt.
190+====Benötigt Funktionen für Linux (basierend auf baseunix)==== Mit Linux wird im Prizip (fast) alles als Datei behandelt. Anhand des Pfades ist zunächst nicht erkennbar was dahinter steckt.
207191
208192- Systemdateien: Hier kann ein Problem entstehen wenn ein Lesezugriff z.B. auf einen FIFO gemacht wird, als ob es eine normale Datei wäre: Die Datei hat KEIN ENDE. (In die Falle tappen viele Programme.)
209193- LINKs: Gerade SymLinks führen zu einem anderen Verzeichniss, dies kann beim Folgen eines solchen zu einer endlosen Kreisbewegung führen.\
210194
211-\
212-<b>Anmerkung:</b> Dateien und Verzeichnisse können ein LINK sein. Siehe Unit <b>Baseunix</b>, Beispiel zu <b>S_ISLNK</b> ; Siehe auch Linuxbefehl <b>stat</b>\
213-\
195+Anmerkung: Dateien und Verzeichnisse können ein LINK sein. Siehe Unit Baseunix, Beispiel zu S_ISLNK ; Siehe auch Linuxbefehl stat\
196+
214197Die genaue Auswertung was im Dateisystem hinter dem Pfad steckt, erfolgt mit folgenden Funktionen:
215198
216199``` pascal
217200//Prüfe ob StrPath ein LINK im Dateisystem ist
218201function IsLink(const StrPath: string):Boolean;
219202 var info: stat;
220203 begin
221204 fplstat(StrPath, @info);
222205 Result := (fpS_ISLNK(info.st_mode));
223206 end;
224207
225208//Prüfe ob StrPath eine reguläre Datei ist
226209function IsRegular(const StrPath: string):Boolean;
227210 var info: stat;
228211 begin
229212 fplstat(StrPath, @info);
230213 Result := (fpS_ISREG(info.st_mode));
231214 end;
232215```
233216
234-\
235217===Beispiel mit Auswertung des Drop=== Es erfolgt folgende Auswertung:
236218
237219- Gehört der übergebene Pfad zum lokalen Dateisystem
238-- Ist es etwa eine URL z.B. WebLink <b><http://></b> oder eine Freigabe <b><smb://></b>
220+- Ist es etwa eine URL z.B. WebLink <http://> oder eine Freigabe <smb://>
239221- Auf welchem Element ist der Drop erfolgt
240-
241-\
242222
243223``` pascal
244224procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of String );
245225 var i,j: integer;
246226 s: String;
247227 p: TPoint;
248228begin
249229
250230// Auswertung des übergebenen Pfades
251231for i:=0 to High(FileNames) do
252232 begin
253233 s:= FileNames[i];
254234 // Reihenfolge ist für linux wichtig !
255235 if DirectoryExists(s) then begin
256236 if IsLink(s) then Memo1.Lines.Add('VERZEICHNIS LINK:'+s)
257237 else Memo1.Lines.Add('VERZEICHNIS:'+s);
258238 end
259239 else if FileExists(s) then begin
260240 if IsLink(s) then Memo1.Lines.Add('DATEI LINK:'+s)
261241 else if IsRegular(s) then Memo1.Lines.Add('DATEI:'+s)
262242 else Memo1.Lines.Add('Systemdatei NICHT Lesen:'+s); // fifo, socket, usw.
263243 end
264244 else begin
265245 j:= pos('://',s);
266246 if ((j > 0)and(j < 6)) then begin // limit j< 6 hängt von zu erwartetenden Dienst ab
267247 Memo1.Lines.Add('Eine Art von URL:'+s); // 'smb://' , 'http://' , usw.
268248 Memo1.Lines.Add('Dienst:'+copy(s, 1, j));
269249 Memo1.Lines.Add('PFAD:' +copy(s, j+3, Length(s)));
270250 end
271251 // Ein Drop mit Text erfolgt nur auf editierbare Felder
272252 else Memo1.Lines.Add('TEXT:'+s); //Man kann hier also auch Text übergeben
273253 end;
274254
275255 //Auf welchem Element war der Drop: Prüfe ob die Maus über einem ListView war
276256 p:= Mouse.CursorPos;
277257 if PtInRect(ListView1.BoundsRect,Form1.ScreenToClient(p)) then Memo1.Lines.Add('Drop in ListView1');
278258 if PtInRect(ListView2.BoundsRect,Form1.ScreenToClient(p)) then Memo1.Lines.Add('Drop in ListView2');
279259end;
280260```
281261
282262Anmerkung: Die Auswertung der Mausposition erfolgt im Formularkoordinatensystem.
283263
284264---
285265*From the Free Pascal wiki, page "Drag and Drop/de", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history