程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 第九章-Delphi拖放編程(4)

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

編輯:Delphi

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編程的精髓。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved