4

Good evening :-)!

I have this code to use Drag & Drop method for files:

TForm1 = class(TForm)
...
public
    procedure DropFiles(var msg: TMessage ); message WM_DROPFILES;
end;

procedure TForm1.FormCreate(Sender: TObject)
begin
    DragAcceptFiles(ListView1.Handle, True);
end;

procedure TForm1.DropFiles(var msg: TMessage );
var
  i, count  : integer;
  dropFileName : array [0..511] of Char;
  MAXFILENAME: integer;
begin
  MAXFILENAME := 511;
  count := DragQueryFile(msg.WParam, $FFFFFFFF, dropFileName, MAXFILENAME);
  for i := 0 to count - 1 do
  begin
    DragQueryFile(msg.WParam, i, dropFileName, MAXFILENAME);
    Memo1.Lines.Add(dropFileName);
  end;
  DragFinish(msg.WParam);
end;

In area of ListView is DragCursor, but in Memo1 aren't any records. When I use for example ListBox and method DragAcceptFiles(ListBox1.Handle, True) ever is fine.

ListView property DragMode I set to dmAutomatic.

Thanks :-)

Nanik
  • 43
  • 1
  • 4
  • 1
    doesn't work is not a good description of whatever problem you have. Please, elaborate your question and don't forget to include a complete description of any unexpected behavior, what you see and what you want to see.. if there's any error or exception involved, include also the error message and exception class name. – jachguate Mar 22 '11 at 20:24
  • Please **do not** post duplicate questions. – Tim Post Mar 22 '11 at 20:29
  • @jachguate: Thanks, the method DropFiles probably do nothing, but there isn't any error. – Nanik Mar 22 '11 at 20:39
  • @Tim Post: I'm sorry, it's problem with refreshing page. I don't know, how I can delete the second post? – Nanik Mar 22 '11 at 20:40
  • You have a couple of answers now that explain the problem. For a more production worthy solution you may wish to consider subclassing the list view so that you can modify its message handling in a less hacky way. – David Heffernan Mar 22 '11 at 20:57

2 Answers2

8

You've called DragAcceptFiles for the ListView, so Windows sends the WM_DROPFILES to your ListView and not to your Form. You have to catch the WM_DROPFILES message from the ListView.

  private
    FOrgListViewWndProc: TWndMethod;
    procedure ListViewWndProc(var Msg: TMessage);
  // ...
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Redirect the ListView's WindowProc to ListViewWndProc
  FOrgListViewWndProc := ListView1.WindowProc;
  ListView1.WindowProc := ListViewWndProc;

  DragAcceptFiles(ListView1.Handle, True);
end;

procedure TForm1.ListViewWndProc(var Msg: TMessage);
begin
  // Catch the WM_DROPFILES message, and call the original ListView WindowProc 
  // for all other messages.
  case Msg.Msg of
    WM_DROPFILES:
      DropFiles(Msg);
  else
    if Assigned(FOrgListViewWndProc) then
      FOrgListViewWndProc(Msg);
  end;
end;
Andreas Hausladen
  • 8,081
  • 1
  • 41
  • 44
1

Your problem is, you're registering the list view window as a drop target, but handling the WM_DROPFILES message in the form class. The message is sent to the list view control, you should handle the message there.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169