第九章-Delphi拖放编程(4)

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);

begin

if Button = mbLeft then

with Sender as TFileListBox do

begin

if ItemAtPos(Point(X, Y), True) >= 0 then

BeginDrag(False);

end;

end;

ItemAtPos用来检查当前是否有文件存在。而BeginDrag方法传递参数False, 允许FileList单独处理鼠标事件而并不开始拖动。事实上这种情况是大量存在的。 

2.DirectoryOutline、DriveTabSet决定是否能接受拖动的就地放下。  

procedure TFMForm.DirectoryOutlineDragOver(Sender, Source: TObject; X,

Y: Integer; State: TDragState; var Accept: Boolean);

begin

if Source is TFileListBox then

Accept := True;

end; 

procedure TFMForm.DriveTabSetDragOver(Sender, Source: TObject; X,

Y: Integer; State: TDragState; var Accept: Boolean);

var

PropPos: Integer;

begin

if Source is TFileListBox then

with DriveTabSet do

begin

PropPos := ItemAtPos(Point(X,Y));

Accept := (PropPos > -1) and (PropPos < Tabs.Count);

end;

end;

DirectoryOutline是无条件的接受,而DriveTabSet需检查是否是合法的标签。 

3.拖动放下的响应

DirectoryOutline的拖动放下用于实现文件移动功能。程序中调用ConfirmChange事件处理过程,目标路径由DirctoryOutline.Items[GetItem(X,Y)].FullPath来得到。  

procedure TFMForm.DirectoryOutlineDragDrop(Sender, Source: TObject; X,

Y: Integer);

begin

if Source is TFileListBox then

with DirectoryOutline do

begin

ConfirmChange('Move',FileList.FileName, Items[GetItem(X, Y)].FullPath);

end;

end;

  DriveTabSet的拖动放下用于实现文件拷贝功能。程序中把当前位置转化为相应的驱动器号,目标路径由CurrentDirList[DriveTabSet.TabIndex]获得。 

procedure TFMForm.DriveTabSetDragDrop(Sender, Source: TObject; X,Y: Integer);

var

APoint: TPoint;

begin

APoint.X := X; APoint.Y := Y;

DriveTabSet.TabIndex := DriveTabSet.ItemAtPos(APoint);

if Source is TFileListBox then

with DriveTabSet do

begin

if CurrentDirList[TabIndex] <> '' then

ConfirmChange('Copy',TheFilename,CurrentDirList[TabIndex]);

end;

end; 

4.FileList响应拖动结束,更新文件列表 

procedure TFMForm.FileListEndDrag(Sender, Target: TObject; X, Y: Integer);

begin

if Target <> nil then FileList.Update;

end; 

到目前为止,我们的文件管理器功能已足够强大。 不过还有许多问题值得读者去进

一步探讨,如:

1.文件与应用程序关联的建立;

2.在文件列表框中显示更多的文件信息;

3.文件列表框中的文件按后缀各排序等。

文件管理器是一个真正的综合例程,对它的钻研会使您更进一步模到Delphi编程的精髓。

时间: 2024-09-16 12:10:57

第九章-Delphi拖放编程(4)的相关文章

第九章-Delphi拖放编程(2)

9.1.3 拖放方法 拖放方法有三个: ●BeginDrag : 人工方式下开始一个拖动 ●EndDrag : 结束一个拖动 ●Dragging : 判断一个控件是否正被拖动 这三个方法都被源控件使用. 当DragMode置为dmManual时,拖动必须调用控件的BeginDrag方法才能开始.BeginDrag有一个布尔参数Immediate.如果输入参数为True,拖动立即开始,光标改变到DragCursor的设置.如果输入参数为False,直到用户将光标移动了一定的距离(5个象素点)后才改

第九章-Delphi拖放编程(1)

拖放(DragDrop)是Windows提供的一种快捷的操作方式.作为基于Windows的开发工具,Delphi同样支持拖放操作,而且开发应用系统的拖放功能十分方便,真正体现了Delphi的强大功能和方便性. Delphi提供的所有控件(Control,即能获得输入焦点的部件)都支持拖放操作,并有相应的拖放属性.拖放事件和拖放方法.下面我们先介绍控件的拖放支持,而后再给出开发拖放操作的一般步骤和应用实例. 9.1 控件的拖放支持 拖放操作中控件可以分为源控件和目标控件两类.绝大部分控件既可以作为

第九章-Delphi拖放编程(3)

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 Dro

《.net编程先锋C#》第九章 配置和调度(转)

编程 第九章 配置和调度在上一章,你学到如何创建一个通用语言运行时(CLR)组件,且如何在一个简单的测试应用程序中使用它.虽然CLR组件就要准备装载了,但你还是应该思考以下技术之一:.条件编译.文档注释.代码版本化 9.1 条件编译 没有代码的条件编译功能,我就不能继续工作.条件编译允许执行或包括基于某些条件的代码:例如,生成应用程序的一个查错(DEBUG)版本.演示(DEMO)版本或零售(RELEASE)版本.可能被包括或被执行的代码的例子为许可证代码. 屏幕保护或你出示的任何程序.在C#中,

第二章-Delphi面向对象的编程方法(三)(2)

2.1.9.4 字符串类型 字符串类型事实上是一个一维的字符数组.当您说明一个字符串型的变量时,您应当指明这个字符串的大小,下面是说明字符串类型的例子: type MyString: string[15]; var MyName: MyString; 则变量MyName被说明成为最多可以包含15个字符.如果您没有说明字符串的大小,Delphi会认为字符串包含最大值255个字符.给字符串赋值可以直接使用单引号括起的字串赋值: MyName := 'Frank.Smith'; 或MyName :=

新手求教 谢谢-c primer plus 编程练习第九章

问题描述 c primer plus 编程练习第九章 设计函数chline(ch, i, j),实现指定字符在i列到j列的输出,并用一个简单的驱动程序测试该函数. #include<stdio.h> void chline(char ch , int i , int j); int main(void) { int i = 0; int j = 0 ; char ch = ' '; printf("enter the char you want to print:"); c

3D编程:第九章 Normal Mapping and Displacement Mapping

第九章 Normal Mapping and Displacement Mapping 本章主要讲述两种图形学技术,支持在不增加objects的poly primitive的情况下,在场景中增加更多的细节.第一种是normal mapping,通过创建一些"fake" geometry(虚设的多边形图元)模拟光照作用.第二种是displacement mapping,根据纹理数据moving vertices actually(与"fake"相对应,这里指真实的移动

第十九章-Delphi自定义部件开发(一)(1)

Delphi除了支持使用可视化部件所见即所得地建立应用程序外,还支持为开发应用而设计自己的部件. 在本章中将阐述如何为Delphi应用程序编写部件.这一章将达到两个目的: ● 教你如何自定义部件 ● 使你的部件成为Delphi环境的有机组合部分 19.1 Delphi部件原理 19.1.1 什么是部件 部件是Delphi应用程序的程序构件.尽管大多数部件代表用户界面的可见元素,但部件也可以是程序中的不可见元素,如数据库部件.为弄清什么是部件可以从三个方面来考察它:功能定义.技术定义和经验定义.

022_《Delphi模式编程》

<Delphi模式编程> Delphi 教程 系列书籍 (022) <Delphi模式编程> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Pdf   作者: 刘艺 丛书名: Borland/Inprise核心技术丛书 出版社:机械工业出版社 ISBN:7111149491 上架时间:2004-9-11 出版日期:2004 年9月 开本:16开 页码:509 版次:1-1 内容简介 <delphi模式编程>是一本delphi程序员的模式入门和