Operasi Drag Drop dari Windows Explorer ke Kontrol
September 12, 2006 at 11:43 am | Posted in Code Samples, Tutorials | 3 CommentsTags: delphi programming, drag drop files, DragAcceptFiles, DragFinish, DragQueryFile, WM_DROPFILES
Artikel ini sesungguhnya adalah posting saya di milis Delphindo untuk menjawab pertanyaan mengenai bagaimana mendapatkan daftar nama-nama file yang drag drop dari Windows Explorer ke suatu control. Jika anda pernah menggunakan WinAmp, anda tentu tahu bahwa kita bisa menambahkan file-file musik ke dalam PlayList dengan cara mendrag-drop file-file dari Windows Explorer ke Listbox playList WinAmp.
Pertanyaannya sekarang adalah:Bagaimana?
Mendaftarkan Handle Window
Untuk bisa menerima drag drop dari shell explorer, kita perlu mendaftarkan handle window. Prosesnya dikerjakan dengan
memanggil fungsi DragAcceptFiles() dideklarasi di shellapi.pas
Fungsi ini mengharapkan dua parameter. Parameter pertama adalah handle yang akan menerima proses drag-drop,
parameter kedua memberitahukan tipe proses registrasi atau unregistrasi. Jika true berarti window handle akan menerima pemberitahuan ketika terjadi drag drop dan bila FALSE maka window handle akan dibuang dari daftar handle yang akan menerima pemberitahuan drag drop.
Memproses Message WM_DROPFILES
Message WM_DROPFILES akan dikirim ke handle window yang telah terdaftar untuk menerima notifikasi. wParam akan berisi handle
ke drag dop yangs sedang terjadi. Handle ini selanjutnya dapat kita pergunakan untuk mendapatkan informasi seperti jumlah file yang
di drag drop dan juga nama-nama filenya. Karena menggunakan handle window, hanya kontrol yang memiliki handle window yang dapat
menerima message ini. WM_DROPFILES akan dikirim melalui Window procedure handle yang bersangkutan.
Mendapatkan Jumlah File yang di drag drop
DragQueryFile kita pergunakan untuk mendapatkan jumlah file yang draq
total_file:=DragQueryFile(hDrop,$FFFFFFFF,nil,0);
Fungsi ini butuh empat parameter, tapi untuk mendapatkan info jumlah file hanya dua parameter awal yang relevan. Sisanya kita isi nil dan 0. Parameter pertama adalah handle drag drop, kedua adalah index file, harus kita isi dengan $FFFFFFFF.
Mendapatkan Panjang Nama File yang di drag drop
Kita perlu tahu panjang nama file, agar kita dapat mengalokasikan buffer untuk menampung data nama file ini.
Untuk mendapatkan panjang nama file, kita masih menggunakan fungsi yang sama yakni DragQueyFile(), namun dengan sedikit parameter berbeda, yakni
Fileindex kita isi dengan 0 hingga total_file-1
filename_len:=DragQueryFile(hDrop,FileIndex,nil,0);
Mendapatkan Nama File yang di drag drop
Kita perlu tahu nama file. Untuk mendapatkan nama file, kita gunakan lagi DragQueyFile(),
Fileindex kita isi dengan 0 hingga total_file-1,
DragQueryFile(hDrop,FileIndex,aFilename,filename_len);
afilename adalah data bertipe PChar yang sebelumnya telah dialokasikan buffernya sebanyak filename_len.
Mengakhiri Proses Drag Drop
Kita panggil DragFinish() untuk memberitahukan bahwa kita telah selesai dengan proses drag drop. Fungsi ini akan
membebaskan memori yang dialokasikan untuk menyimpan daftar nama file. Handle drag drop kita lewatkan ke fungsi ini.
Berikutnya kita buat implementasinya. Kita akan mengenkapsulasi fungsionalitas drag drop menjadi satu komponen yang
akan memudahkan proses drag dop ke sebuah kontrol.
berikut ini source code-nya:
{
================================
TDragDrop v.1.0
=================================
Komponen yg mengenkapsulasi proses
drag drop files dari file manager
ke window control
=================================
(c)2004 Zamrony P Juhara
=================================
}
unit DragDrop;
interface
uses
SysUtils, Classes,Controls,Windows,Messages;
type
TDragDropFilesEvent=procedure(Sender:TObject;const FileIndex,TotalFile:integer;
const Filename:string) of object;
TDragDrop = class(TComponent)
private
OldWndProc:TWndMethod;
FAccept: boolean;
FOnDragDropFiles: TDragDropFilesEvent;
FControl: TWinControl;
procedure SetDragAccept;
procedure WndProc(var msg:TMessage);
procedure AcceptFiles(const hDrop:THandle);
function GetTotalDroppedFiles(const hDrop:THandle):integer;
function GetDroppedFilename(const hDrop:THandle;const FileIndex:integer):string;
function GetDroppedFilenameLength(const hDrop:THandle;const FileIndex:integer):cardinal;
procedure AcceptFinish(const hDrop:THandle);
procedure SetAccept(const Value: boolean);
procedure SetControl(const Value: TWinControl);
procedure SetOnDragDropFiles(const Value: TDragDropFilesEvent);
protected
procedure DoDragDropFiles(const FileIndex,TotalFile:integer;
const Filename:string);virtual;
public
published
property Control:TWinControl read FControl write SetControl;
property Accept:boolean read FAccept write SetAccept;
property OnDragDropFiles:TDragDropFilesEvent read FOnDragDropFiles write SetOnDragDropFiles;
end;
procedure Register;
implementation
uses ShellAPI;
procedure Register;
begin
RegisterComponents('zaMm Components', [TDragDrop]);
end;
{ TDragDrop }
procedure TDragDrop.AcceptFiles(const hDrop:THandle);
var i,totalFile:integer;
Filename:string;
begin
TotalFile:=GetTotalDroppedFiles(hDrop);
for i:=0 to TotalFile-1 do
begin
FileName:=GetDroppedFilename(hDrop,i);
DoDragDropFiles(i,TotalFile,Filename);
if Assigned(FOnDragDropFiles) then
FOnDragDropFiles(Self,i,TotalFile,Filename);
end;
AcceptFinish(hDrop);
end;
procedure TDragDrop.AcceptFinish(const hDrop: THandle);
begin
DragFinish(hDrop);
end;
procedure TDragDrop.DoDragDropFiles(const FileIndex, TotalFile: integer;
const Filename: string);
begin
//defaultnya gak melakukan apa-apa
//override utk mengubah proses AcceptFiles
end;
function TDragDrop.GetDroppedFilename(const hDrop: THandle;
const FileIndex: integer): string;
var afilename:PChar;
size:cardinal;
begin
result:='';
size:=GetDroppedFilenameLength(hDrop,FileIndex);
if Size<>0 then
begin
aFilename:=StrAlloc(Size);
try
DragQueryFile(hDrop,FileIndex,aFilename,Size);
result:=aFilename;
finally
StrDispose(aFilename);
end;
end;
end;
function TDragDrop.GetDroppedFilenameLength(const hDrop: THandle;
const FileIndex: integer): cardinal;
var size:cardinal;
begin
size:=0;
size:=DragQueryFile(hDrop,FileIndex,nil,size);
//tambah satu karena kita menggunakan string
result:=size+1;
end;
function TDragDrop.GetTotalDroppedFiles(const hDrop: THandle): integer;
begin
result:=DragQueryFile(hDrop,$FFFFFFFF,nil,0);
end;
procedure TDragDrop.SetAccept(const Value: boolean);
begin
FAccept := Value;
//kalo runtime
if not(csDesigning in ComponentState) then
SetDragAccept;
end;
procedure TDragDrop.SetControl(const Value: TWinControl);
begin
FControl := Value;
//kalo runtime
if not(csDesigning in ComponentState) then
SetDragAccept;
end;
procedure TDragDrop.SetDragAccept;
begin
if FControl<>nil then
begin
if FAccept then
begin
//kalo accept subclass default window proedure
OldWndProc:=FControl.WindowProc;
FControl.WindowProc:=WndProc;
end else
FControl.WindowProc:=OldWndProc;
DragAcceptFiles(FControl.Handle,FAccept);
end;
end;
procedure TDragDrop.SetOnDragDropFiles(const Value: TDragDropFilesEvent);
begin
FOnDragDropFiles := Value;
end;
procedure TDragDrop.WndProc(var msg: TMessage);
begin
//msg.WParam berisi handle Drop struktur
if msg.Msg=WM_DROPFILES then
begin
AcceptFiles(msg.WParam);
msg.Result:=0;
end else
OldWndProc(msg);
end;
end.
contoh penggunaan:
Buat aplikasi baru. Drag drop TListbox. Pada formCreate tambahkan baris kode berikut:
procedure TForm1.FormCreate(sender:TObject);
begin
DragDrop1:=TDragDrop.Create(self);
DragDrop1.OnDragDropFiles:=DragDropFiles;
DragDrop1.Control:=ListBox1;
DragDrop1.Accept:=true;
end;
procedure TForm1.DragDropFiles(Sender: TObject; const FileIndex,
TotalFile: Integer; const Filename: String);
begin
ListBox1.Items.Add(Filename);
end;
Tiap kali ada file dari windows explorer didrag drop ke komponen listbox1 maka nama-nama
file yg didrag drop akan ditampilkan di listbox1
Source code bisa di download di sini
3 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a reply to Mozza Cancel reply
Blog at WordPress.com.
Entries and comments feeds.
Wew, siip, kini gw bisa bikin aplikasi mp3 player yang fantastis, bisa drag & drop langsung dari Windows Explorer. Thansk banget yah Delphindo, vivo Delphindo!!!
Comment by snip3r_dp— February 17, 2007 #
kepala hotak kau… aku cai len bagi len
pedu r……
Comment by ali sabah— April 2, 2008 #
iyo i.. notepad ku error, bikin pake delphi.. kok ga bisa ngedrag file…. akhirnya bisa , ntar tek coba
Comment by Mozza— November 25, 2009 #