第九章-Delphi拖放编程_第1页
第九章-Delphi拖放编程_第2页
第九章-Delphi拖放编程_第3页
第九章-Delphi拖放编程_第4页
第九章-Delphi拖放编程_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

拖放(DragDrop)是Windows提供的一种快捷的操作方式。作为基于Windows的开发工具,Delphi同样支持拖放操作,而且开发应用系统的拖放功能十分方便,真正体现了Delphi的强大功能和方便性。Delphi提供的所有控件(Control,即能获得输入焦点的部件)都支持拖放操作,并有相应的拖放属性、拖放事件和拖放方法。下面我们先介绍控件的拖放支持,而后再给出开发拖放操作的一般步骤和应用实例。9.1控件的拖放支持拖放操作中控件可以分为源控件和目标控件两类。绝大部分控件既可以作为源控件也可以作为目标控件。但也有一部分控件只能支持其中的一种。9.1.1拖放属性拖放属性主要有两个:●DragMode:拖动模式●DragCursor:拖动光标它们都是在拖放的源控件中设置。DragMode控制用户在运行时间内当在控件上按下鼠标时控件如何反应。如果DragMode置为dmAutomatic,那么当用户在控件上按下鼠标时拖动自动开始;如果DragMode置为dmManual(这是缺省值),则将通过处理鼠标事件来判断一个拖动是否可以开始。DragCursor用于选择拖动时显示的光标,缺省值是CrDrag,一般不要去修改它。在程序设计过程中通用的界面规范应该得到开发者的尊重。但有时候为了特定的目的,开发者也可以把自己设计的光标赋给DragCursor。9.1.2拖放事件拖放事件主要有三个:●OnDragOver:拖动经过时激发●OnDragDrop:拖动放下时激发●OnEndDrop:拖动结束时激发前两个事件由目标控件响应,后一个事件由源控件响应。OnDragOver事件最主要的功能是确定当用户就地放下拖动时控件是否可以接受。它的参数包括:Source:TObject;{源控件}X,Y:Integer;{光标位置}State:TDragState;{拖动状态}varAccept:Boolean{能否接受}TDragState是一个枚举类型,表示拖放项目与目标控件的关系。typeTDragState=(dsDragEnter,dsDragLeave,dsDragMove);不同取值的意义如下表:表9.1DragState的取值与意义━━━━━━━━━━━━━━━━━━━━━━━━━━━取值意义───────────────────────────dsDragEnter拖动对象进入一个允许拖动对象放下的控件中。为缺省状态。dsDragLeave拖动对象离开一个允许拖动对象放下的控件。dsDragMove拖动对象在一个允许拖动对象放下的控件内移动。━━━━━━━━━━━━━━━━━━━━━━━━━━━用户可以利用提供的参数来确定放下的if(SourceisTLabel)and(State=dsDragEnter)then(SourceasTLabel).EndDrag(False);end;Draging方法判断一个控件是否正被拖动。在下面的例子中当用户拖动不同的检查框时窗口改变为不同的颜色。procedureTForm1.FormActivate(Sender:TObject);beginCheckBox1.DragMode:=dmAutomatic;CheckBox2.DragMode:=dmAutomatic;CheckBox3.DragMode:=dmAutomatic;end;procedureTForm1.FormDragOver(Sender,Source:TObject;X,Y:Integer;State:TDragState;varAccept:Boolean);beginifCheckBox1.DraggingthenColor:=clAqua;ifCheckBox2.DraggingthenColor:=clYellow;ifCheckBox3.DraggingthenColor:=clLime;end;9.2开发拖放功能的一般步骤拖放作为Windows提供的一种方便操作对象的功能,在Delphi中可以很容易地开发出来。根据拖放操作的过程可以把开发步骤划分为四个阶段,即:●开始拖动操作●接收拖动项目●放下拖动项目●终止拖动操作在介绍过程中我们将结合一个TabSet(标签集)的拖放操作实例。界面设计如图。在运行时当用户把一个标签拖动到另一个标签的位置时,该标签将移动到该位置并引起标签集的重新布置。9.2.1开始拖动操作当拖动模式(DragMode)设置为dmAutomatic时,用户在源控件上按下鼠标时拖动自动开始;当设置为dmManual时通过处理鼠标事件来决定拖动是否开始。如果想开始拖动调用BeginDrag方法。在TabSet拖放中,我们用下面的MouseDown事件处理过程来开始一个标签的拖动。首先判断按下的是否是左键,而后再判断项目是否合法。procedureTForm1.TabSet1MouseDown(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y:Integer);varDragItem:Integer;beginifButton=mbLeftthenbeginDragItem:=TabSet1.ItemAtPos(Point(X,Y));if(DragItem>-1)and(DragItem<TabSet1.Tabs.Count)thenTabSet1.BeginDrag(False);end;end;9.2.2接收拖动项目一个控件能否接收拖动项目是由该控件的OnDragOver事件决定的。在TabSet拖动中,主要是利用鼠标的位置进行判断。procedureTForm1.TabSet1DragOver(Sender,Source:TObject;X,Y:Integer;State:TDragState;varAccept:Boolean);varDropPos:Integer;beginifSource=TabSet1thenbeginDropPos:=TabSet1.ItemAtPos(Point(X,Y));Accept:=(DropPos>-1)and(DropPos<>TabSet1.TabIndex)and(DropPos<TabSet1.Tabs.Count);end;elseAccept:=False;end;9.2.3放下拖动项目当OnDragOver事件处理过程返回的Accept为True且项目被放下时,由OnDragDrop事件处理过程来完成拖动放下后的响应。在TabSet拖放实例中是改变标签的位置。procedureTForm1.TabSet1DragDrop(Sender,Source:TObject;X,Y:Integer);varOldPos:Integer;NewPos:Integer;beginifSource=TabSet1thenbeginOldPos:=TabSet1.TabIndex;NewPos:=TabSet1.ItemAtPos(Point(X,Y));if(NewPos>-1)and(NewPos<>OldPos)thenTabSet1.Tabs.Move(OldPos,NewPos);end;end;9.2.4结束拖动操作结束拖动操作的方式有两种:或者是用户释放了鼠标键或者是程序用EndDrag方法强行中止拖动。结束拖动操作的后果有两种:放下被接受或放下被忽略。拖动操作结束后源控件都要收到一条消息响应拖动结束事件OnEndDrag。9.3拖放应用实例:文件管理器的拖放支持在第六章最后开发的文件管理器应用实例,虽然功能上已初具规模,但在操作上与Windows的文件管理器相比还有很大不足。其中最大的缺陷是它不支持文件的拖放移动和拖放拷贝。在这一章结束的时候,我们可以来弥补这一缺陷了。文件拖放移动指的是当用户把一个文件拖动到目录树下的某一目录并放下时,文件将自动移动到该目录中;文件拖放拷贝指的是当用户把一个文件拖动到某个驱动器标签上并放下时,文件将自动拷贝到该驱动器的当前目录下。作为源控件的文件列表框和作为目标控件的目录树、驱动器标签可以位于不同的子窗口。驱动器的当前目录是任一子窗口的最新操作结果,而不论这一子窗口与拖动源、拖动目标是否有关系。为了实现上述功能,有两个问题必须首先解决:1.如何记录每一驱动器的当前目录?为此我们定义了一个全局变量:varCurentDirList:Array[0...25]ofstring[70];在DirectoryOutline的OnChange事件中:procedureTFMForm.DirectoryOutlineChange(Sender:TObject);beginCreateCaption;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操作符进行类型检查:IfSourceisTFileListthen...如果我们用下面的语句:IfSource=FileListthen...则移动、拷贝操作将限制在本子窗口范围内。当解决了上述问题后我们的工作就只是遵循拖放的一般开发步骤,按步就班来完成了。1.FileList开始拖动操作procedureTFMForm.FileListMouseDown(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y:Integer);beginifButton=mbLeftthenwithSenderasTFileListBoxdobeginifItemAtPos(Point(X,Y),True)>=0thenBeginDrag(False);end;end;ItemAtPos用来检查当前是否有文件存在。而BeginDrag方法传递参数False,允许FileList单独处理鼠标事件而并不开始拖动。事实上这种情况是大量存在的。2.DirectoryOutline、DriveTabSet决定是否能接受拖动的就地放下。procedureTFMForm.DirectoryOutlineDragOver(Sender,Source:TObject;X,Y:Integer;State:TDragState;varAccept:Boolean);beginifSourceisTFileListBoxthenAccept:=True;end;procedureTFMForm.DriveTabSetDragOver(Sender,Source:TObject;X,Y:Integer;State:TDragState;varAccept:Boolean);varPropPos:Integer;beginifSourceisTFileListBoxthenwithDriveTabSetdobeginPropPos:=ItemAtPos(Point(X,Y));Accept:=(PropPos>-1)and(PropPos<Tabs.Count);end;end;DirectoryOutline是无条件的接受,而DriveTabSet需检查是否是合法的标签。3.拖动放下的响应DirectoryOutline的拖动放下用于实现文件移动功能。程序中调用ConfirmChange事件处理过程,目标路径由DirctoryOutline.Items[GetItem(X,Y)].FullPath来得到。procedureTFMForm.DirectoryOutlineDragDrop(Sender,Source:TObject;X,Y:Integer);beginifSourceisTFileListBoxthenwithDirectoryOutlinedobeginConfirmChange('Move',FileList.FileName,Items[GetItem(X,Y)].FullPath);end;end;DriveTabSet的拖动放下用于实现文件拷贝功能。程序中把当前位置转化为相应的驱动器号,目标路径由CurrentDirList[DriveTabSet.TabIndex]获得。procedure

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论