Home » Delphi, Sample Apps, Tips & Tricks, Win32 API » How To Accept Drag And Drop Files Onto A ListView

How To Accept Drag And Drop Files Onto A ListView

Print Friendly



Drag And Drop Files Onto ListViewYou may in need of dragging and dropping files from explorer onto a listview (or another control) on a form. Here’s a simple way to deal with that.

First, we know that each Delphi control has message handler procedure known as Window Proc, for handling messages from Windows.

A ListView has this procedure of course. To implement drag and drop on a ListView, we must override the window proc of the ListView with our customized window proc, and implement code of our needs there.

The steps are:

  1. Save old ListView’s window proc
  2. Create a new window proc for the ListView and our codes there
  3. Filter messages from Windows. If our new window proc receives message that match our need, then process it else pass it to old saved window proc
  4. Enable the ListView to accept files

To have those all done, we need to to add ShellApi to uses list.


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ShellApi;

Then we define two procedures to handle messages, and a variable to save old window proc:

type
TForm3 = class(TForm)
ListView1: TListView;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
OldLvWndProc : TWndMethod;
procedure OnDropFiles(var msg: TWMDropFiles);
procedure LvWndProc(var Msg: TMessage);
public
{ Public declarations }
end;

Now the code for the new window proc to filter messages (we need only WM_DROPFILES):

procedure TForm3.LvWndProc(var Msg: TMessage);
begin
if msg.Msg = WM_DROPFILES then
OnDropFiles(TWMDropFiles(msg))
else
OldLvWndProc(msg);
end;

And the code for handling files dropped on the ListView:

procedure TForm3.OnDropFiles(var msg: TWMDropFiles);
var
FCount, i: Integer;
FName: array [0..MAX_PATH] of char;
begin
ListView1.Items.BeginUpdate;
ListView1.Items.Clear;
try
{How many files droppped?}
FCount := DragQueryFile(msg.Drop, $FFFFFFFF, FName, MAX_PATH);
for i:= 0 to FCount-1 do
begin
{Add them to the ListView}
DragQueryFile(msg.Drop, i, FName, MAX_PATH);
with ListView1.Items.Add do
begin
Caption := STring(FName);
{Is current file a folder or a file?}
if DirectoryExists(string(FName)) then
SubItems.Add('Directory')
else
SubItems.Add('File');
end;
end;
finally
ListView1.Items.EndUpdate;
end;
end;

The last, we enable the ListView to accept files and replace window proc with the new one:

procedure TForm3.FormCreate(Sender: TObject);
begin
OldLvWndProc         := ListView1.WindowProc;
ListView1.WindowProc := LvWndProc;
DragAcceptFiles(ListView1.Handle, True);
end;

And here’s the whole code:

unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ShellApi;

type
TForm3 = class(TForm)
ListView1: TListView;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
OldLvWndProc : TWndMethod;
procedure OnDropFiles(var msg: TWMDropFiles);
procedure LvWndProc(var Msg: TMessage);
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

{$R *.dfm}

{ TForm3 }

procedure TForm3.FormCreate(Sender: TObject);
begin
OldLvWndProc         := ListView1.WindowProc;
ListView1.WindowProc := LvWndProc;
DragAcceptFiles(ListView1.Handle, True);
end;

procedure TForm3.LvWndProc(var Msg: TMessage);
begin
if msg.Msg = WM_DROPFILES then
OnDropFiles(TWMDropFiles(msg))
else
OldLvWndProc(msg);
end;

procedure TForm3.OnDropFiles(var msg: TWMDropFiles);
var
FCount, i: Integer;
FName: array [0..MAX_PATH] of char;
begin
ListView1.Items.BeginUpdate;
ListView1.Items.Clear;
try
{How many files droppped?}
FCount := DragQueryFile(msg.Drop, $FFFFFFFF, FName, MAX_PATH);
for i:= 0 to FCount-1 do
begin
{Add them to the ListView}
DragQueryFile(msg.Drop, i, FName, MAX_PATH);
with ListView1.Items.Add do
begin
Caption := STring(FName);
{Is current file a folder or a file?}
if DirectoryExists(string(FName)) then
SubItems.Add('Directory')
else
SubItems.Add('File');
end;
end;
finally
ListView1.Items.EndUpdate;
end;
end;

end.

Hope this post helps someone who in need. Leave comment if you have any question :)

Download The Source Download The Source
The source code of this post (sample app.):

Drag And Drop Files Onto A ListView (248.4 KiB)


Incoming search terms:

 

Comments

comments

Powered by Facebook Comments

2 Responses to How To Accept Drag And Drop Files Onto A ListView

  1. klo bikin kebalikanya gmn bang,, dari list view di drag ke windows explorer

       New Post

  2. Hi, Your example is very usefull. I need just this example, but drop files onto a TcxTreeList (really to drop files onto a treenode). I made the component change, and the example works, but i can’t select a particular node from the tree to drop the file.
    Could you tell me how to do this?
    Thanks!
    Ramiro

       New Post

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>