Delphi拖放編程 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://www.ahetc.gov.cn/cit/200011/20.doc Delphi拖放編程 拖放(DragDrop)是Windows提供的一種快捷的操作方式。作?基於Windows的開發工具,Delphi同樣支援拖放操作,而且開發應用系統的拖放功能十分方便。
一 控制項的拖放支援
Delphi提供的所有可視控制項都支援拖放操作,並有相應的拖放屬性、拖放事件和拖放方法。
拖放屬性主要有兩個:
DragMode : 拖動模式
DragCursor : 拖動游標
它們都是在拖放的源控制項中設置。DragMode控制用戶在運行時間內當在控制項上按下滑鼠時控制項如何反應。如果DragMode置?dmAutomatic,那?當用戶在控制項上按下滑鼠時拖動自動開始;如果DragMode置?dmManual(這是缺省值),則將通過處理滑鼠事件來判斷一個拖動是否可以開始。
DragCursor用於選擇拖動時顯示的游標,缺省值是CrDrag,一般不要去修改它,但有時候?了特定的目的,開發者也可以把自己設計的游標賦給ragCursor。
拖放事件主要有三個:
OnDragOver:拖動經過時激發
OnDragDrop:拖動放下時激發
OnEndDrop :拖動結束時激發
前兩個事件由目標控制項回應,後一個事件由源控制項回應。
OnDragOver事件最主要的功能是確定當用戶就地放下拖動時控制項是否可以接受。它的參數包括:
Source : TObject; {源控制項}
X,Y : Integer; {游標位置}
State : TDragState; {拖動狀態}
var Accept : Boolean {能否接受}
TDragState是一個枚舉類型,表示拖放專案與目標控制項的關係。
其不同取值的意義如下表:
DragState 的取值與意義
取 值 意 義
───────────────────────────
dsDragEnter 拖動物件進入一個允許拖動物件放下
的控制項中。?缺省狀態。
dsDragLeave 拖動物件離開一個允許拖動物件放下
的控制項。
dsDragMove 拖動物件在一個允許拖動物件放下的
控制項內移動。
用戶可以利用提供的參數來確定放下的拖動是否可被接受,如:
判斷源控制項類型:
Accept := Source is TLabel;
判斷源控制項物件:
Accept := (Source = TabSet1);
判斷拖動狀態:
If (Source is TLabel) and (State = dsDragMove) then
begin
source.DragIcon := ' New.Ico ';
Accept := True;
end
else
Accept := False;
當Accept=True時,目標控制項可以回應OnDragDrop事件,用於確定拖動被放下後程式如何進行處理。
OnDragDrop事件處理過程的參數包括源控制項和游標位置。這些資訊可用於處理方式的確定。
OnEndDrag事件是在拖動操作結束後由源控制項來進行回應的,用於源控制項進行相應的處理。拖動操作結束既包括拖動放下被接受,也包括用戶在一個不能接受放下的控制項上釋放了滑鼠。該事件處理過程的參數包括目標控制項(Target)和放下位置的座標。如果Target=nil, 表示拖動專案沒有被任何控制項接受。
除以上介紹的三個事件外,還有一個事件OnMouseDown 也常用於拖放操作的回應。OnMouseDown雖然不是一個專門的拖放事件,但在人工模式下拖動的開始是在這一事件的處理過程中實現的。
拖放方法有三個:
BeginDrag : 人工方式下開始一個拖動
EndDrag : 結束一個拖動
Dragging : 判斷一個控制項是否正被拖動
這三個方法都被源控制項使用。
當DragMode置?dmManual時,拖動必須調用控制項的BeginDrag方法才能開始。BeginDrag有一個布林參數Immediate。如果輸入參數?True,拖動立即開始,游標改變到DragCursor的設置。如果輸入參數?False,直到用戶將游標移動了一定的距離(5個象素點)後才改變游標,開始拖動。這就允許控制項接受一個OnClick事件而並不開始拖動操作。
EndDrag方法中止一個物件的被拖動狀態。它有一個布林參數Drop。如果Drop設置?True,被拖動的物件在當前位置放下(能否被接受由目標控制項決定);如果Drop設置?False,則拖動就地被取消。
下面一段程式表明當拖動進入一控制面板時拖動被取消。
procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := False;
if (Source is TLabel) and (State = dsDragEnter) then
(Source as TLabel).EndDrag(False);
end;
Draging方法判斷一個控制項是否正被拖動。在下面的例子中當用戶拖動不同的檢查框時窗口改變?不同的?色。
procedure TForm1.FormActivate(Sender: TObject);
begin
CheckBox1.DragMode := dmAutomatic;
CheckBox2.DragMode := dmAutomatic;
CheckBox3.DragMode := dmAutomatic;
end;
procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
if CheckBox1.Dragging then
Color := clAqua;
if CheckBox2.Dragging then
Color := clYellow;
if CheckBox3.Dragging then
Color := clLime;
end;
二 開發拖放功能的一般步驟
根據拖放操作的過程可以把開發步驟劃分?四個階段,即:
開始拖動操作
接收拖動專案
放下拖動專案
終止拖動操作
在介紹過程中我們將結合一個TabSet(標簽集)的拖放操作實例。介面設計如圖。在運行時當用戶把一個標簽拖動到另一個標簽的位置時,該標簽將移動到該位置並引起標簽集的重新佈置。
TabSet 拖放實例的介面設計
a. 開始拖動操作
當拖動模式(DragMode)設置?dmAutomatic時,用戶在源控制項上按下滑鼠時拖動自動開始;當設置?dmManual時通過處理滑鼠事件來決定拖動是否開始。如果想開始拖動調用BeginDrag方法。
在TabSet拖放中,我們用下面的MouseDown事件處理過程來開始一個標簽的拖動。首先判斷按下的是否是左鍵,而後再判斷專案是否合法。
Procedure TForm1.TabSet1MouseDown(Sender:TObject;Button:TMouseButton;Shift: ShiftState; 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);
end;
end;
b. 接收拖動專案
一個控制項能否接收拖動專案是由該控制項的OnDragOver事件決定的。在TabSet拖動中,主要是利用滑鼠的位置進行判斷。
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;
c. 放下拖動專案
當OnDragOver事件處理過程返回的Accept?True且專案被放下時,由OnDragDrop事件處理過程來完成拖動放下後的回應。在TabSet拖放實例中是改變標簽的位置。
procedure TForm1.TabSet1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
OldPos: Integer;
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;
d. 結束拖動操作
結束拖動操作的方式有兩種:或者是用戶釋放了滑鼠鍵或者是程式用EndDrag方法強行中止拖動。結束拖動操作的後果有兩種:放下被接受或放下被忽略。
拖動操作結束後源控制項都要收到一條消息回應拖動結束事件OnEndDrag。 新疆維吾爾自治區昌吉州技工學校 張濤
郵編:831100 電話:0994-2348728 EMAIL:jxzt-cj@mail.xj.cninfo.net
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
wnhoo
高階會員 發表:75 回覆:443 積分:198 註冊:2003-04-22 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |