自制支援檔案拖放的VCL元件 (轉)

worldblog發表於2007-12-08
自制支援檔案拖放的VCL元件 (轉)[@more@] 用過的朋友都知道,Winamp的介面能支援拖放,當你想欣賞某檔案時,只需要
將檔案拖到Winamp的視窗上,然後放開滑鼠就行了。那我們如何讓自己的也實現這樣的功能
呢?我們可以透過改進開發工具提供的標準來實現。下面以環境中的ListBox元件為
例,讓ListBox支援檔案拖放。
 首先介紹一下要用到的:
 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 }
{ E: sunisoft@21cn.com }
{ : }
unit DropFileListBox;
interface
uses
 , Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Api; //增加ShellApi單元,因為所使用的三個API函式宣告於此單元檔案中
type
 TMyNotifyEvent = procedure (Sender: T;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);overr;
 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;
 N: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.

 該元件後即可使用,我們可以新建一個工程,將該元件放置在Form上,然後在
TDropFileListBox元件的OnDropFiles事件中寫下具體處理拖放操作的程式碼。

 例如將所有拖放的檔名加入該列表中,新增程式碼如下:

procedure TForm1.DropFileListBox1DropFiles(Sender: TObject;FileNames: TStringList);
begin
 DropFileListBox1.Items.AddStrings(FileNames);
end;

 執行一下看看,是不是很有趣?本文僅僅對於ListBox元件做了擴充套件,你也可以對其它元件做
類似的擴充套件,實現支援檔案的拖放。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989770/,如需轉載,請註明出處,否則將追究法律責任。

相關文章