Eigenschaft: DragMode (TLabel-TList)

Verweis: DragKind DragCursor
Uses: StdCtrls
Eingabe: Modus für die Drag- und Drop-Operation.
Ausgabe: Funktion der Drag- und Drop-Operation.
Funktion: dmAutomatic setzt die automatische Drag- und Drop-Operation in Gang.

Das verschieben von einzelnen Komponenten oder deren Inhalten ist Ihnen bestimmt schon einmal begegnet. Das bekannteste Beispiel ist wohl der Dateiexplorer bei der Sie mit gehaltener linker Maustaste Dateien verschieben können. Die ist also eine Drag/Drop Operation. Der DragMode:=dmAutomatic lässt auf eine bequeme Programmierung von einer Drag und Drop Operation schließen. Dem ist leider nicht ganz so. Sie müssen da schon etwas mehr machen.

Beispiel 1

Vorbereitung: Erstellen sie eine IDE Anwendung und ziehen Sie drei TLabel und eine TListBox auf die Form. Wenn sie nicht wissen wie man mehrere Komponenten des gleichen Typs auf die Form bringt, dann schauen sie bitte hier. Erstellen Sie zusätzlich ein OnActivate-Ereignis für die Form. Erstellen Sie zusätzlich ein DragDrop und ein DragOver Ereignis für die ListBox1.

procedure TForm1.ListBox1DragOver(Sender, Source: TObject;
  X, Y: integer; State: TDragState; var Accept: boolean);
begin
  //Bestimme wer was ablegen darf
  Accept := (Source = Label1) or (Source = Label2);
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: integer);
begin
  //Entscheide was mit dem Abgelgten geschieht
  if (Source = Label1) then
    //Hier erweitere die Liste um Label Caption
    ListBox1.Items.Append(Label1.Caption);
  if (Source = Label2) then
    ListBox1.Items.Append(Label2.Caption);
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  //Alle sendenden Komponenten auf Automatik
  Label1.DragMode := dmAutomatic;
  Label2.DragMode := dmAutomatic;
  Label3.DragMode := dmAutomatic;
  //Beschriftung
  Label1.Caption := 'Ich darf.';
  Label2.Caption := 'Ich auch.';
  Label3.Caption := 'Ich nicht.';
end;

Im OnActivate der Form stellen Wir Dinge ein, die wir auch im Objektexplorer einstellen hätten können. Hier gehe ich nur sicher, dass alle Einstellungen auch sind wie sein sollen. Alle an der Drag und Drop Operation sendenden Komponenten müssen auf dmAutomatic stehen. Dies bedeutet, das die ListBox1 nicht auf dmAutomatic stehen muss. Danach folgt die Beschriftung der Label für ein besseres Verständnis.

Label in die Liste ziehen.
Drag und Drop in Aktion.

Wie Sie sehen können Sie die Beschriftung von Label1 und Label2 in die Listbox1 ablegen. Bei Label3 sehen Sie das Verbotszeichen. Das liegt daran, das Label3 nicht akzeptiert ( Accept ) wird. Wir hätten auch bei Label3 auf DragMode:=dmManual stehen Lassen können. Aber vielleicht schreiben Sie ja ein Programm mit einer 2. Listbox in der dann Label3.Caption abgelegt werden kann. Wie Sie bereits bemerkt haben steht in Source der Name der gezogenen Komponente. Dieser wird dann mit der Wunsch-Komponente verglichen. In der Animation sehen sie die unterschiedlichen Cursor dies hängt mit der mangelhaften Unterstützung des Betriebssystems zusammen. Siehe Cursor.

Drag und Drop in Linux Mint.
In Linux ist das Design etwas anders, aber die Funktion gleich.

Warum also überhaupt die Funktion dmManual ?

Es gibt vielleicht Momente da möchten Sie die Drag und Drop Operation anpassen. Dies geht im Automatik-Modus nicht. Hier sollten Sie die Funktion auf dmManual lassen. Manual bedeutet das Sie den Start der Drag Funktion selber bestimmen können. Dies geschieht im Quelltext. Hierzu müssen sie weitere Ereignisse für Ihre Wunsch-Funktion abfangen und in Ihre gewünschten Bahnen lenken.

Beispiel 2

Vorbereitung: Erstellen sie eine IDE Anwendung und ziehen Sie drei TLabel und eine TListBox auf die Form. Wenn sie nicht wissen wie man mehrere Komponenten des gleichen Typs auf die Form bringt, dann schauen sie bitte hier. Erstellen Sie zusätzlich ein OnActivate-Ereignis für die Form. Erstellen Sie zusätzlich ein DragDrop und ein DragOver Ereignis für die ListBox1.Erstellen Sie zusätzlich ein MouseDown Ereignis für die Label1 und Label2.

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: integer;
  State: TDragState; var Accept: boolean);
begin
  //Bestimme wer was ablegen darf
  Accept := (Source = Label1) or (Source = Label2);
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: integer);
begin
  //Entscheide was mit dem Abgelgten geschieht
  if (Source = Label1) then
    //Hier erweitere die Liste um Label Caption
    ListBox1.Items.Append(Label1.Caption);
  if (Source = Label2) then
    ListBox1.Items.Append(Label2.Caption);
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  //Alle Beteiligten Komponenten auf Manual
  Label1.DragMode := dmManual;
  Label2.DragMode := dmManual;
  //Beschriftung
  Label1.Caption := 'Ich darf.';
  Label2.Caption := 'Ich auch.';
  Label3.Caption := 'Ich nicht.';
end;

procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: integer);
begin
  //Wie Automatik
  Label1.BeginDrag(True);
end;

procedure TForm1.Label2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: integer);
begin
  //Reagiere nur bei der rechten Maustaste
  if Button = mbRight then Label2.BeginDrag(True);
end;

Wenn Sie alles richtig gemacht haben, was bei so vielen Ereignissen nicht so einfach ist, dann hat das Programm folgende Funktionen.

Label1 ‚Ich darf.‘

Label1 lässt sich wie gewohnt bei dmAutomatic in die ListBox schieben.Doch etwas ist anders. Denn Sie können mit allen Maustasten das Label verschieben. Wenn Sie die gleiche Funktion wie bei dmAutomatic haben wollen dann müssen Sie diese Zeile:

Label1.BeginDrag(True); 

gegen diese Zeile tauschen.

if Button = mbLeft then Label2.BeginDrag(True);

Nun wird nur die linke Maustaste abgefragt.

Label2 ‚Ich auch.‘

Nun sehen Sie den Vorteil, den Sie bei einer manuellen Abfrage haben. Hier können wir beispielsweise das Verschieben der Schrift nur mit einer rechts gehaltenen Maustaste benutzen.

Label3 ‚Ich nicht.‘

Das Label habe ich für Sie zum experimentieren gelassen. 🙂 Es hat jetzt noch keine Funktion. Hierzu müssten Sie bei dmManual noch ein MouseDown-Ereignis mit beginDrag hinzufügen. Oder Sie stellen Label3 auf dmAutomatic. Aber selbst dann müssten Sie noch, das DragOver und das DragDrop-Ereignis der Listbox erweitern.