Delphi拖放编程(2)
2008-04-09 04:17:53来源:互联网 阅读 ()
拖放作为Windows提供的一种方便操作对象的功能,在Delphi中可以很容易地开发出来。根据拖放操作的过程可以把开发步骤划分为四个阶段,即:
●开始拖动操作
●接收拖动项目
●放下拖动项目
●终止拖动操作
在介绍过程中我们将结合一个TabSet(标签集)的拖放操作实例。界面设计如图。在运行时当用户把一个标签拖动到另一个标签的位置时,该标签将移动到该位置并引起标签集的重新布置。
9.2.1开始拖动操作
当拖动模式(DragMode)设置为dmAutomatic时,用户在源控件上按下鼠标时拖动自动开始;当设置为dmManual时通过处理鼠标事件来决定拖动是否开始。如果想开始拖动调用BeginDrag方法。
在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 $#@62; -1) and (DragItem $#@60; TabSet1.Tabs.Count) then
TabSet1.BeginDrag(False);
end;
end;
9.2.2接收拖动项目
一个控件能否接收拖动项目是由该控件的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 $#@62; -1) and (DropPos $#@60;$#@62; TabSet1.TabIndex) and
(DropPos $#@60; TabSet1.Tabs.Count);
end;
else
Accept := False;
end;
9.2.3放下拖动项目
当OnD Over事件处理过程返回的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 $#@62; -1) and (NewPos $#@60;$#@62; OldPos) then
TabSet1.Tabs.Move(OldPos, NewPos);
end;
end;
9.2.4结束拖动操作
结束拖动操作的方式有两种:或者是用户释放了鼠标键或者是程序用EndDrag方法强行中止拖动。结束拖动操作的后果有两种:放下被接受或放下被忽略。
拖动操作结束后源控件都要收到一条消息响应拖动结束事件OnEndDrag。
9.3 拖放应用实例:文件管理器的拖放支持
在第六章最后开发的文件管理器应用实例,虽然功能上已初具规模,但在操作上与Windows的文件管理器相比还有很大不足。其中最大的缺陷是它不支持文件的拖放移动和拖放拷贝。在这一章结束的时候,我们可以来弥补这一缺陷了。
文件拖放移动指的是当用户把一个文件拖动到目录树下的某一目录并放下时,文件将自动移动到该目录中;文件拖放拷贝指的是当用户把一个文件拖动到某个驱动器标签上并放下时,文件将自动拷贝到该驱动器的当前目录下。作为源控件的文件列表框和作为目标控件的目录树、驱动器标签可以位于不同的子窗口。驱动器的当前目录是任一子窗口的最新操作结果,而不论这一子窗口与拖动源、拖动目标是否有关系。
为了实现上述功能,有两个问题必须首先解决:
1.如何记录每一驱动器的当前目录?
为此我们定义了一个全局变量:
var CurentDirList: Array[0...25] of string[70];
在DirectoryOutline的OnChange事件中:
procedure TFMForm.DirectoryOutlineChange(Sender: TObject);
begin
CreateCaption;
FileList.clear;
FileList.Directory := DirectoryOutline.Directory;
FileList.Update;
CurrentDirList[DriveTabSet.TabIndex] := DirectoryOutline.Directory;
FileManager.DirectoryPanel.Caption := DirectoryOutline.Directory;
end;
由于DriveTabSet在响应OnDragDrop事件前先响应OnClick事件,并由该事件激发DirectoryOutline的Onchange事件,因而可保证在任何时候OnDragDrop事件中用到的CurrentDirList数组项不为空字符串。
2.如何保证移动、拷贝与子窗口的无关性?
在这里一个关键问题是我们判断源控件时是用is操作符进行类型检查:
If Source is TFileList then …
如果我们用下面的语句:
If Source = FileList then
…
则移动、拷贝操作将限制在本子窗口范围内。
当解决了上述问我们的工作就只是遵循拖放的一般开发步骤,按步就班来完成了。
1.FileList开始拖动操作
procedure TFMForm.FileListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:制作固定大小的Form
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash