標準 TListView 不支援直接接收檔案總管拖曳的檔案。本文示範如何透過 Windows API (DragAcceptFiles, WM_DROPFILES) 擴充 TListView 使其能接收檔案拖放,並在報表檢視模式下顯示檔名與路徑。
DragAcceptFiles(ListView.Handle, True) 讓控件接受 WM_DROPFILES 訊息。Application.OnMessage 事件中攔截 WM_DROPFILES。DragQueryFile 取得檔案數量與完整路徑。DragFinish 結束拖放作業。ListView 欄位。unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, ComCtrls;
type
TForm1 = class(TForm)
ListView1: TListView;
procedure FormCreate(Sender: TObject);
private
procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
// 設定報表檢視雙欄
ListView1.ViewStyle := vsReport;
ListView1.Columns.Add.Caption := 'FileName';
ListView1.Columns.Add.Caption := 'Path';
// 允許拖放檔案
DragAcceptFiles(ListView1.Handle, True);
// 掛鉤應用程式訊息迴圈
Application.OnMessage := AppMessage;
end;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
FileCount, I: Integer;
FileName: string;
Item: TListItem;
begin
// 僅處理送給 ListView1 的 WM_DROPFILES
if (Msg.Message = WM_DROPFILES) and (Msg.Hwnd = ListView1.Handle) then
begin
FileCount := DragQueryFile(Msg.WParam, $FFFFFFFF, nil, 0);
try
for I := 0 to FileCount - 1 do
begin
SetLength(FileName, MAX_PATH);
DragQueryFile(Msg.WParam, I, PChar(FileName), MAX_PATH);
FileName := PChar(FileName); // 修正長度
Item := ListView1.Items.Add;
Item.Caption := ExtractFileName(FileName);
Item.SubItems.Add(ExtractFilePath(FileName));
end;
finally
DragFinish(Msg.WParam);
end;
Handled := True;
end;
end;
end.
ListView1 區域。uses 加入 ShellAPI。AppMessage 會攔截所有訊息,邏輯務必精簡,避免影響效能。