第六章文件管理器功能初具但操作不足,最大缺陷:不支持文件拖放移動/拷貝。本節彌補。
源控件(文件列表框)與目標控件(目錄樹、驅動器標簽)可位於不同子窗口。驅動器當前目錄為任意子窗口最新操作結果,與拖動源/目標無關。
定義全局數組:
var CurrentDirList: 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,保證數組項非空。
判斷源控件用 is 操作符類型檢查:
if Source is TFileListBox then ...
若用 if Source = FileList then 會限制在本子窗口範圍。
procedure TFMForm.FileListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
with Sender as TFileListBox do
if ItemAtPos(Point(X, Y), True) >= 0 then
BeginDrag(False); // False:允許單獨處理鼠標事件不立即拖動
end;
ItemAtPos 檢查文件是否存在。BeginDrag(False) 常見模式。
// 目錄樹:無條件接受
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;
// 目錄樹:文件移動
procedure TFMForm.DirectoryOutlineDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if Source is TFileListBox then
with DirectoryOutline do
ConfirmChange('Move', FileList.FileName, Items[GetItem(X, Y)].FullPath);
end;
// 驅動器標簽:文件拷貝
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
if CurrentDirList[TabIndex] <> '' then
ConfirmChange('Copy', TheFileName, CurrentDirList[TabIndex]);
end;
目標路徑:目錄樹用 Items[GetItem(X,Y)].FullPath,驅動器標簽用 CurrentDirList[TabIndex]。
procedure TFMForm.FileListEndDrag(Sender, Target: TObject; X, Y: Integer);
begin
if Target <> nil then FileList.Update;
end;
文件管理器是綜合實例,深入鑽研可體會 Delphi 編程精髓。