Проблема с обнаружением движений мыши в TcxGrid при перетаскивании файлов из Windows Explorer - PullRequest
0 голосов
/ 25 октября 2009

Недавно я добавил в большое приложение, написанное на Delphi (версия 2009), функцию, которая позволяет пользователю перетаскивать файлы из проводника Windows и помещать их в элемент управления TcxGrid.Я достиг этого с помощью обычного метода присоединения моего собственного окна к процедуре и перехвата сообщения WM_DROPFILES:

 originalGridWindowProc := cxGrid.WindowProc; // remember the old one
 cxGrid.WindowProc := GridWindowProc;  // assign the new one
 DragAcceptFiles(cxGrid.Handle, LongBool(True)); // setup to accept dropped files

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

Моей первой мыслью было посмотреть, сработает ли событие mouseover для элемента управления grid.Да, но не во время операции перетаскивания.

Затем я использовал программу Winspector, чтобы увидеть, какие сообщения были отправлены в элемент управления grid, когда мышь перемещается по сетке, и теперь я могу определить, над какой строкой находится мышь, и выделить ее.Я использую ту же технику, что и выше, но в этом случае я перезаписываю процедуру окна для GridSite, а не саму сетку, потому что именно там сообщения, кажется, идут в соответствии с Winspector:

  originalGridSiteWindowProc := cxGrid.ActiveView.Site.WindowProc;
  cxGrid.ActiveView.Site.WindowProc := GridSiteWindowProc;

Вот тело GridSiteWindowProc:

procedure Tfrm.GridSiteWindowProc(var message: TMessage);
var
  hitTest: TcxCustomGridHitTest;
  gridRecord: TcxCustomGridRecord;
begin
  //Log(IntToStr(message.Msg));
  case message.Msg of
    WM_NCHITTEST: begin
      hitTest := cxGrid.ActiveView.GetHitTest(cxGrid.ScreenToClient(Mouse.CursorPos));
      if hitTest is TcxGridRecordCellHitTest then begin
        gridRecord := TcxGridRecordCellHitTest(HitTest).GridRecord;
        if Not gridRecord.Focused then
          gridRecord.Focused := True;
      end;
      originalGridSiteWindowProc(message);
    end
    else
      originalGridSiteWindowProc(message);
  end;
end;

Как видите, я перехватываю сообщение WM_NCHITTEST для достижения этой цели.Согласно Winspector, это сообщение также отправляется в окно узла сетки во время операции перетаскивания, но если я раскомментирую тот оператор Log (), который выведет значение сообщения в список строк (который я затем вручную дам в поле memo),Я определил, что по какой-то причине я получаю только одно или два из этих сообщений при перетаскивании файла по сетке.

Теперь - вот интересная часть: если я запускаю Winspector и отслеживаю сообщения, идущие в это окно, я неожиданно начинаю получать все сообщения WM_NCHITTEST во время операции перетаскивания файла.Это также имеет место, если я вывожу целочисленное значение всех сообщений, поступающих в окно proc, непосредственно в отдельное окно журнала, а не в буфер списка строк.Я надеюсь, что кто-то сможет предложить некоторую подсказку относительно того, почему это происходит или как заставить это работать.

1 Ответ

3 голосов
/ 25 октября 2009

Вместо того, чтобы использовать сообщение WM_DROPFILES, вы должны использовать OLE Drag'n'Drop. Посмотрите на API RegisterDropTarget. Вы можете получить более подробную информацию о , где происходит перетаскивание. Вы также можете принять больше видов объектов перетаскивания.

...