Delphi — перетаскивание с помощью ListView

Добрый вечер :-)!

У меня есть этот код для использования метода Drag & Drop для файлов:

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;

В области ListView есть DragCursor, а в Memo1 нет записей. Когда я использую, например, ListBox и метод DragAcceptFiles(ListBox1.Handle, True), все в порядке.

Для свойства ListView DragMode я установил значение dmAutomatic.

Спасибо :-)


person Nanik    schedule 22.03.2011    source источник
comment
не работает не является хорошим описанием любой проблемы, с которой вы столкнулись. Пожалуйста, уточните свой вопрос и не забудьте включить полное описание любого неожиданного поведения, того, что вы видите и что вы хотите увидеть.. если есть какая-либо ошибка или исключение, включите также сообщение об ошибке и имя класса исключения.   -  person jachguate    schedule 22.03.2011
comment
Пожалуйста, не публикуйте повторяющиеся вопросы.   -  person Tim Post♦    schedule 22.03.2011
comment
@jachguate: Спасибо, метод DropFiles, вероятно, ничего не делает, но ошибки нет.   -  person Nanik    schedule 22.03.2011
comment
@Tim Post: извините, проблема с обновлением страницы. Я не знаю, как я могу удалить второй пост?   -  person Nanik    schedule 22.03.2011
comment
Теперь у вас есть пара ответов, объясняющих проблему. Для решения, более подходящего для производства, вы можете рассмотреть возможность создания подкласса представления списка, чтобы вы могли изменить его обработку сообщений менее хакерским способом.   -  person David Heffernan    schedule 22.03.2011


Ответы (2)


Вы вызвали DragAcceptFiles для ListView, поэтому Windows отправляет WM_DROPFILES в ваш ListView, а не в форму. Вы должны поймать сообщение WM_DROPFILES из 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;
person Andreas Hausladen    schedule 22.03.2011
comment
Спасибо за ваше решение :-)! - person Nanik; 23.03.2011

Ваша проблема в том, что вы регистрируете окно просмотра списка как цель перетаскивания, но обрабатываете сообщение WM_DROPFILES в классе формы. Сообщение отправляется в элемент управления представлением списка, вы должны обработать сообщение там.

person Sertac Akyuz    schedule 22.03.2011