用過Winamp的朋友都知道,Winamp的界面能支持文件拖放,當你想欣賞某MP3文件時,只需要
將文件拖到Winamp的窗口上,然後放開鼠標就行了。那我們如何讓自己的程序也實現這樣的功能
呢?我們可以通過改進開發工具提供的標准組件來實現。下面以Delphi環境中的ListBox組件為
例,讓ListBox支持文件拖放。
首先介紹一下要用到的API函數:
DragAcceptFiles() 初始化某窗口使其允許/禁止接受文件拖放
DragQueryFile() 查詢拖放的文件名
DragFinish() 釋放拖放文件時使用的資源
實現的基本原理如下:首先調用DragAcceptFiles()函數初始化組件窗口,使其允許接受文件
拖放,然後等待WM_DropFiles消息(一旦用戶進行了拖放文件操作,組件窗口即可獲得此消息),
獲得消息後即可使用DragQueryFile()函數查詢被拖放的文件名,最後調用DragFinish()釋放資
源。
因為在VCL類庫中,ListBox組件,所屬類名為:TListBox,所以我們可以從TListBox繼承建立
自己的組件。新組件名為:TDropFileListBox,它比標准TListBox增加了一個OnDropFiles事件和
一個DropEnabled屬性。當DropEnabled為True時即可接受文件拖放,文件拖放完成後激發
OnDropFiles事件,該事件提供一個FileNames參數讓用戶獲得文件名。
組件的代碼如下:
{ TDropFileListBox V1.00 Component }
{ Copyright (c) 2000.5 by Shen Min, Sunisoft }
{ Email: [email protected] }
{ Web: http://www.sunistudio.com }
unit DropFileListBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ShellApi; //增加ShellApi單元,因為所使用的三個API函數聲明於此單元文件中
type
TMyNotifyEvent = procedure (Sender: TObject;FileNames:TStringList) of object; //自定
義事件類型。
TDropFileListBox = class(TListBox) //新的類從TListBox繼承
private
{ Private declarations }
FEnabled:Boolean; //屬性DropEnabled的內部變量
protected
FDropFile:TMyNotifyEvent; //事件指針
procedure DropFiles(var Mes:TMessage);message WM_DROPFILES;
procedure FDropEnabled(Enabled:Boolean); //設置DropEnabled屬性的過程
{ Protected declarations }
public
constructor Create(AOwner: TComponent);override;
destructor Destroy;override;
{ Public declarations }
published
property OnDropFiles:TMyNotifyEvent read FDropFile write FDropFile;
property DropEnabled:Boolean read FEnabled write FDropEnabled;
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Sunisoft', [TDropFileListBox]); //注冊組件到組件板上
end;
constructor TDropFileListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled:=true; //類被構造時,使DropEnabeld的默認值為True
end;
destructor TDropFileListBox.Destroy;
begin
inherited Destroy;
end;
//改變屬性DropEnabled的調用過程
procedure TDropFileListBox.FDropEnabled(Enabled:Boolean);
begin
FEnabled:=Enabled;
DragAcceptFiles(Self.Handle,Enabled);//設置組件窗口是否接受文件拖放
end;
//接受WM_DropFiles消息的過程
procedure TDropFileListBox.DropFiles(var Mes:TMessage);
var FN:TStringList;
FileName:array [1..256] of char;
sFN:String;
i,Count,p:integer;
begin
FN:=TStringList.Create;
Count:=DragQueryFile(Mes.WParam,$FFFFFFFF,@FileName,256);//得到拖放文件的個數
For i:=0 to Count-1 do
begin
DragQueryFile(mes.WParam,i,@FileName,256);//查詢文件名稱
sFN:=FileName;
p:=pos(chr(0),sFN);//去掉文件名末尾的ASCII碼為0的字符
sFN:=copy(sFN,1,p-1);
FN.Add(sFN);
end;
DragFinish(mes.WParam); //釋放所使用的資源
if Assigned(FDropFile) then
FDropFile(self, FN); //調用事件,並返回文件名列表參數
FN.Free;
end;
end.
該組件安裝後即