【发布时间】:2010-06-01 03:36:03
【问题描述】:
我们都知道您可以为您的窗口实现拖放功能,以便它接受拖放操作,但我的问题是,如何检测正在进行的拖放操作其他窗口,例如,在 Windows 资源管理器中拖动文件?我想要做的是,当用户拖动文件时,我的隐藏窗口就会显示出来。
谢谢!
【问题讨论】:
我们都知道您可以为您的窗口实现拖放功能,以便它接受拖放操作,但我的问题是,如何检测正在进行的拖放操作其他窗口,例如,在 Windows 资源管理器中拖动文件?我想要做的是,当用户拖动文件时,我的隐藏窗口就会显示出来。
谢谢!
【问题讨论】:
您所要求的内容不受本机支持。在拖放操作期间,只有拖动的发起者知道该操作正在进行中,并且只有实际被拖动的窗口才会收到可能发生该操作的通知。
我现在能想到的唯一选择是在 DLL 中通过 SetWindowsHookEx() 实现一个全局鼠标挂钩,并让它跟踪用户何时按住左键并将鼠标移出源窗口。但是无法获取有关正在拖动的内容的信息。
【讨论】:
当大多数拖放操作开始时,系统会创建一个带有“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 上启动计时器来轻松解决,并定期监控反馈窗口是否仍然存在。
【讨论】:
我使用 Raize Software 的 DropMaster。 http://www.raize.com/devtools/Products.asp
你也可以从 Melander 使用,但我没有测试这个。 http://melander.dk/delphi/dragdrop/.
【讨论】: