拖放操作四階段:① 開始拖動 ② 接收拖動項目 ③ 放下拖動項目 ④ 結束拖動。結合 TabSet 標簽拖放實例:運行時將標簽拖至另一位置,標簽移動並引起重新佈局。
DragMode=dmAutomatic:按下鼠標自動開始;dmManual:處理鼠標事件決定。TabSet 用 MouseDown 事件:
procedure TForm1.TabSet1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var DragItem: Integer;
begin
if Button = mbLeft then
begin
DragItem := TabSet1.ItemAtPos(Point(X, Y));
if (DragItem > -1) and (DragItem < TabSet1.Tabs.Count) then
TabSet1.BeginDrag(False); // False:移動一定距離後才改變光標開始拖動
end;
end;
OnDragOver 事件決定是否接受,利用鼠標位置判斷:
procedure TForm1.TabSet1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var DropPos: Integer;
begin
if Source = TabSet1 then
begin
DropPos := TabSet1.ItemAtPos(Point(X, Y));
Accept := (DropPos > -1) and (DropPos <> TabSet1.TabIndex) and (DropPos < TabSet1.Tabs.Count);
end
else Accept := False;
end;
OnDragOver 返回 Accept=True 且放下時,OnDragDrop 響應,改變標簽位置:
procedure TForm1.TabSet1DragDrop(Sender, Source: TObject; X, Y: Integer);
var OldPos, NewPos: Integer;
begin
if Source = TabSet1 then
begin
OldPos := TabSet1.TabIndex;
NewPos := TabSet1.ItemAtPos(Point(X, Y));
if (NewPos > -1) and (NewPos <> OldPos) then
TabSet1.Tabs.Move(OldPos, NewPos);
end;
end;
兩種結束方式:用戶釋放鼠標、程序 EndDrag 強行中止。兩種後果:放下被接受、放下被忽略。源控件均收到 OnEndDrag 事件響應。