开发者

How to know user is dragging something when the cursor is not in my window?

We all know you can implement drag-and-drop feature for your Window so that it accepts drag and drop operation, but my question is, how to detect a drag-and-drop operation that's is in progress in other windows, for example, drag开发者_开发问答ging a file in the Windows Explorer? What I want to do is that when a user is dragging a file then my hidden window shows up.

Thank you!


What you are asking for is not natively supported. During a drag&drop operation, only the originator of the drag knows the operation is in progress, and only windows actually being dragged over get notifed that the operation may occur on them.

The only option I can think of right now is to implement a global mouse hook via SetWindowsHookEx() in a DLL and have it keep track of when the user holds down the left button and moves the mouse outside of the source window. But there is no way to get information about what is being dragged.


When most of Drag&Drop operations start, system creates a feedback window with "SysDragImage" class. It's possible to catch the creation and destruction of this feedback window, and react in your application accordingly.

Here's a sample code (form class declaration is skipped to make it shorter):

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;

The only issue here is when you press Escape right after beginning of the Drag & Drop, the system won't generate EVENT_OBJECT_DESTROY event. But this can easily be solved by starting timer on EVENT_OBJECT_CREATE, and periodically monitoing if the feedback windows is still alive.


I use DropMaster from Raize Software. http://www.raize.com/devtools/Products.asp

You can also use from Melander, but i didn't test this one. http://melander.dk/delphi/dragdrop/.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜