Mein eigenes Beispiel:
Der Vorgang beginn mit dem MouseDown-Ereignis, wenn die linke Taste gedrückt wird: BeginDrag. Das "false" bedeutet, dass die Maus erst über die im nächsten Parameter angegebene Distanz gezogen werden muss (Default ist 5). Das schützt vor unbeabsichtigtem Drag&Drop beim "verrutschten" Klicken. Mit Hilfe der Methode MouseToCell werden die Koordinaten der Zelle ermittelt, in der geklickt wurde - diese brauchen wir später zum Kopieren des Inhalts:
Code: Alles auswählen
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) then begin
StringGrid1.BeginDrag(false, 8);
StringGrid1.MouseToCell(X, Y, OrigCol, OrigRow);
end;
end;
Während die Maus über den Bildschirm gezogen wird, signalisieren alle Controls unterhalb der Maus, ob sie für den Drop-Vorgang in Frage kommen. Dafür ist das Ereignis OnDragAccept verantwortlich. Dabei ist Source das Control unter der Maus (Sender ist das aktuell gezogene Object). Normalerweise reicht es aus abzufragen, ob Source gleich dem StringGrid ist. Darüber hinaus könnte man aber auch z.B. prüfen, ob die Zelle unter der Maus leer ist, so dass nichts überschrieben wird. Um die aktuelle Position zu erlauben, setzt man Accept auf true - Accept ist standardmäßig auf false, so dass nicht in Frage kommende Controls keinen OnDragOver-Handler benötigen.
Code: Alles auswählen
procedure TForm1.StringGrid1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
if Source = StringGrid1 then
Accept := true;
end;
Schließlich wird die Maus losgelassen. Nun kommt das Ereignis OnDragDrop. Die Methode MouseToCell ermittelt wieder die Spalten/Zeilen-Nummer der Zelle, die aktuell unter der Maus liegt. In diese Zelle schreiben wir den Inhalt der Ausgangszelle. Die Ausgangszelle wird gelöscht (oder auch nicht - je nachdem, was man will). In dem Beispiel habe ich auch eine Bestätigungs-Abfrage eingebaut:
Code: Alles auswählen
procedure TForm1.StringGrid1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
c, r: Integer;
begin
StringGrid1.MouseToCell(X, Y, c, r);
Caption := Format('X = %d, Y = %d | Col = %d, Row = %d', [X, Y, c, r]);
if MessageDlg('Wirklich?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then
exit;
StringGrid1.Cells[c, r] := StringGrid1.Cells[OrigCol, OrigRow];
StringGrid1.Cells[OrigCol, OrigRow] := '';
end;