第六章-文件管理(三)(6)

6.4.7.2 删除目录 

在实现目录删除过程中,远不如创建目录那么顺利。碰到的问题是:

1.RmDir不允许删除当前目录。但为了操作方便,我们要求删除的恰恰是当前目录;

2.目录删除后调用Refresh方法或Update方法并不能使该目录从屏幕显示中去除。因而当用户试图进入该目录时会导致系统崩溃。

对第一个问题,我们的解决办法是把当前目录转换到其父目录。假如读者记得目录也被操作系统作为一种特殊的文件对待的话,那么就不会对下面的语句感到奇怪了: 

path := DirectoryOutline.Directory;

Directoryoutlin.Directory := ExpandFilePath(Path);

而后调用RmDir过程: 

RmDir(Path);

第二个问题的解决却颇为费神。因为DirectoryOutline是Delphi提供的示例部件,没有Help文件支持。通过试验发现:只有当DirectoryOutline的Drive属性改变时,才重新从相应驱动器读取目录。而且它基本上是只读的,除非清除( Clear) 它,象Add、Delete这些方法对它都是无效的。

我曾经考虑过一个笨拙的方法,那就是先改变当前驱动器而后再改回来。但这种方法一方面速度无法忍受,另一方面当只存在一个驱动器可用时会导致系统崩溃。

正当我一筹莫展时,突然想到:DirectoryOutline是一个Sample部件,Delphi 提供了它的源代码。而当我分析了它的源代码后,我知道应该做什么了,那就是为DirectoryOutline增添一个Reset方法! 

6.7.3 为部件增添一个方法 

严格地说,我们所做的工作属于创建一个新部件。但因为我们有源代码,所以不必从DirectoryOutline继承而是直接修改它。这样我们可以省去与创建部件有关的许多繁琐工作。对创建新部件感兴趣的读者可阅读本书第三编的有关章节。

在Delphi IDE中打开DirectoryOutline的源文件后:

1.把库单元名改为DirPlus,类名改为TDirectoryOutlinePlus,表明这是DirectoryOutline的增强版。而后存入另一个目录中;

  2.添加一个公有方法Reset。这一方法的作用是重新读取当前驱动器的目录。程序清单如下。 

procedure TDirectoryOutlinePlus.Reset;

begin

ChDir(FDrive + ':');

GetDir(0, FDirectory);

FDirectory := ForceCase(FDirectory);

if not (csLoading in ComponentState) then BuildTree;

end;

读者也许被这段代码弄糊涂了。由于篇幅所限,而且涉及到许多自定义部件开发的内容,我们也不准备去详细解释它。假如读者想彻底搞懂它,我建议先看一下本书第三编有关自定义部件开发的内容,而后再对照原DirectoryOutline的源代码进行分析。

3.编译成一个库文件DirPlus.tpu;

4.把DirPlus加入部件的Samples页中。

如何添加一个部件见第三编有关章节的介绍。

当增强的目录树准备好以后,必须修改我们的子窗口设计,但却不必亲自修改源代码。

1.删除子窗口中的TDirectoryOutline类部件DirectoryOutline。此时FileList占据了整个客户区;

2.把FileList的Align属改为None,并留出左边的空白供放部件用;

3.在窗口左部加入TDirectoryOutlinPlus类的部件DirectoryOutline;

4.把DirectoryOutline的Align属性改为Left,FileList的Align属性还原为Client;

5.在DirectoryOutline的事件OnChange列表中选取DirectoryOutlineChange,即原DirectoryOutline的处理过程。

以上工作的最终目标是实现目录创建、删除后屏幕的正确显示。这只需要调用DirectoryOutline的Reset方法即可。

目录删除过程的实现代码如下。 

procedure TFMForm.DeleteDirectory1Click(Sender: TObject);

var

path: String;

k: Integer;

begin

{$I-}

path := DirectoryOutline.Directory;

DirectoryOutline.Directory := ExtractFilePath(Path);

if MessageDlg('Delete ' + path + '?', mtConfirmation,[mbYes, mbNo], 0) = idYes then

RmDir(path);

if IOResult <> 0 then

MessageDlg(' Cannot remove directory! The path might not'+

'exist,non-empty or is the current logged directory.',mtWarning,[mbOk], 0)

else

DirectoryOutline.Reset;

end;

修改后的目录创建过程如下。 

procedure TFMForm.CreateDirectory1Click(Sender: TObject);

var

NewDir: TNewDir;

Dir: String;

begin

{$I-}

NewDir := TNewDir.Create(self);

with NewDir do

begin

CurrentDir.Caption := DirectoryOutline.Directory;

if (ShowModal <> idCancel) and (DirName.Text <> '') then

Dir := ExpandFileName(DirName.text);

end;

MkDir(Dir);

if IOResult <> 0 then

MessageDlg('Cannot Create directory', mtWarning, [mbOk], 0)

else

DirectoryOutline.Reset;

end;

当完成了这些工作,把程序重新编译、运行后,可以发现我们所希望实现的功能完全实现了!同时,我们有了一个更好的目录树部件。 

时间: 2024-10-14 11:50:16

第六章-文件管理(三)(6)的相关文章

第六章-文件管理(三)(8)

6.4.8.2 状态条的显示 状态条用于显示当前目录和当前选中文件.它们的值在DirectoryOutline 和FileList的Change事件处理过程中修改. DirectoryOutline和FileList最终的Change事件处理过程如下: procedure TFMForm.DirectoryOutlineChange(Sender: TObject); begin CreateCaption; FileList.clear; FileList.Directory := Direc

第六章-文件管理(三)(4)

6.4.6 其它文件管理功能的实现 在子窗口的Function菜单中,定义了一些其它的文件管理功能: ● Search :查找一个给定名字的文件,若存在则显示该文件属性 ● Disk View :显示当前驱动器的大小和剩余空间 ● View type :确定显示文件的类型 6.4.6.1 文件查找 当用户单击Search菜单项时,程序弹出一个对话框(如图6.10),要求输入待查找的文件名和查找路径.文件名可以是通配符.当用户确认后程序显示第一个匹配文件的属性(如图6.9).查找不到匹配文件则给出

第六章-文件管理(三)(2)

6.4.5.2 文件拷贝.移动.删除.更名 文件拷贝的关键是使用了以文件句柄为操作对象的文件管理函数,因而提供了一种底层的I/O通道.在Object Pascal中这一点是利用无类型文件实现的. 在文件拷贝中首先检查目标文件名是否是一个目录.如是则把原文件的文件名添加到目标路径后,生成目标文件全路径名.而后提取源文件的时间戳,以备拷贝完成后设置目标文件.拷贝过程中使用了返回文件句柄或以文件句柄为参数的文件管理函数FileOpen.FileCreate.FileRead.FileWrite.Fil

第六章-文件管理(三)(1)

2.画出每个自画项目 这在TabSet的OnDrawTab事件处理过程中完成.这一事件处理过程的参数中包含了待画项目索引.画板.待画区域.是否被选中等.这里我们只利用了前三个参数.事实上利用最后一个参数,我们可以对被选中的标签进行一些特殊的视觉效果处理.这一工作就留给读者自己去完成. procedure TFMForm.DriveTabSetDrawTab(Sender: TObject; TabCanvas: TCanvas; R: TRect; Index: Integer; Selecte

第六章-文件管理(三)(7)

6.4.7.4 改变当前目录 改变当前目录的实现非常简单,只要修改DirectoryOutline的Directory属性.但需注意的是:当改变后目录所在驱动器也发生变化时应相应修改DriveTabSet的当前值.由于驱动器名与DriveTabSet的索引属性TabIndex之间并没有确定的对应关系,因而需要通过一个循环进行查找匹配. Change Directory的菜单事件处理过程是FileChange,即与文件的移动.拷贝.更名共用一个事件处理过程.详细情况请读者参看(6.4.5.3)中的

第六章-文件管理(三)(5)

6.4.6.3 改变显示文件的类型 改变显示文件的类型事实上是设置FileList的Mask属性.我们利用一个标准的InputBox输入文件的匹配字符串.而后利用Update方法更新FileList. procedure TFMForm.Viewtype1Click(Sender: TObject); var FileMask: String; begin FileMask := InputBox('File type','Input File type For View :',FileList

第六章-文件管理(三)(3)

6.4.5.3 一致的界面 文件拷贝.文件移动. 文件更名以及后边的改变当前目录在形式上都表现为从一个源文件到一个目标文件.因而可以采用统一的用户界面,即ChangeForm对话框 这四个菜单项共用一个Click事件处理过程,通过对Sender参数的检测,决定将要打开对话框的标题和显示内容.当用户按OK键关闭且目标文件(目录)非空时,程序弹出一个消息对话框要求用户进一步确认,而后执行相应的动作. 共用的事件处理过程FileChange的程序清单如下: procedure TFMForm.File

第六章-文件管理(二)(4)

6.4 文件管理综合举例:文件管理器的实现 在本章的最后,我们利用Delphi提供的文件控件和文件管理函数开发一个简单的文件管理器.虽然这一文件管理器还无法和Windows提供的文件管理器相比拟,但它也为一般的文件操作提供了足够多的功能,而且如果读者感兴趣,还可以对它做进一步的扩充.在后边的拖放操作一章中,我们就为它提供了拖放支持,使它看起来更象一个"文件管理器". 6.4.1 设计基本思路 6.4.1.1 窗口设计 文件管理器的主窗口是一个多文档界面(MDI).有关文件.目录的显示和

第六章-文件管理(二)(2)

6.2.8 结果综合 对不同方法的评估结果,可按一定的公式进行综合.当用户按下"计算"按钮时,系统进行计算并把综合结果写入HazAttr只读编辑框中. 为保证结果显示的正确性,每次增加.修改.删除操作确认后HazAttr编辑框清空. 6.2.9 编辑对话框的输入检查 当用户单击"增加"或"修改"按钮时系统将弹出一个编辑对话框,让用户输入或修改记录内容.其中的三个编辑框,一个组合列表框分别对应TMethod 的四个域.由于TMethod的Resul