Как узнать, что пользователь перетаскивает что-то, когда курсор не находится в моем окне? - PullRequest
3 голосов
/ 01 июня 2010

Мы все знаем, что вы можете реализовать функцию перетаскивания для своего окна, чтобы она принимала операцию перетаскивания, но мой вопрос заключается в том, как обнаружить операцию перетаскивания, которая выполняется другие окна , например, перетаскивание файла в проводнике Windows? Что я хочу сделать, так это то, что когда пользователь перетаскивает файл, появляется мое скрытое окно.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 02 июня 2010

То, что вы просите, изначально не поддерживается. Во время операции перетаскивания только инициатор перетаскивания знает, что операция выполняется, и только те окна, которые фактически перетаскиваются, уведомляются о том, что операция может произойти с ними.

Единственный вариант, о котором я могу подумать сейчас, - это реализовать глобальный хук мыши через SetWindowsHookEx() в DLL и заставить его отслеживать, когда пользователь удерживает нажатой левую кнопку и перемещает мышь за пределы исходного окна. Но нет способа получить информацию о том, что перетаскивается.

0 голосов
/ 12 декабря 2012

Когда начинается большинство операций перетаскивания, система создает окно обратной связи с классом «SysDragImage». Можно отследить создание и уничтожение этого окна обратной связи и соответственно отреагировать в вашем приложении.

Вот пример кода (объявление класса формы пропускается, чтобы сделать его короче):

procedure WinEventProc(hWinEventHook: THandle; event: DWORD;
  hwnd: HWND; idObject, idChild: Longint; idEventThread, dwmsEventTime: DWORD); stdcall;
var
  ClassName: string;
begin
  SetLength(ClassName, 255);
  SetLength(ClassName, GetClassName(hWnd, pchar(ClassName), 255));

  if pchar(ClassName) = 'SysDragImage' then
  begin
    if event = EVENT_OBJECT_CREATE then
      Form1.Memo1.Lines.Add('Drag Start')
    else
      Form1.Memo1.Lines.Add('Drag End');    
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FEvent1 := SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, 0, @WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
  FEvent2 := SetWinEventHook(EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY, 0, @WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWinEvent(FEvent1);
  UnhookWinEvent(FEvent2);
end;

Единственная проблема здесь - когда вы нажимаете Escape сразу после начала перетаскивания, система не генерирует событие EVENT_OBJECT_DESTROY. Но это легко решить, запустив таймер EVENT_OBJECT_CREATE и периодически отслеживая, все ли окна обратной связи еще активны.

0 голосов
/ 01 июня 2010

Я использую DropMaster от Raize Software. http://www.raize.com/devtools/Products.asp

Вы также можете использовать от Меландера, но я не проверял это. http://melander.dk/delphi/dragdrop/.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...