我有一个WPF窗口,它显示文件夹(ListView)的内容,并实现了将文件从窗口拖放到桌面或资源管理器窗口(使用GongSolutions拖放库)。
我可以毫无问题地检测应用程序内的删除,但我需要检测何时删除发生在应用程序外部(桌面或资源管理器窗口),以便我可以刷新窗口以反映已移动的文件。
有什么方法可以检测应用程序外部发生的掉落吗?
我知道我可以使用 FileSystemWatcher 来检测文件的离开,但这有一个缺点,如果用户一次拖放多个文件,它会触发多次。使用计时器对 FileSystemWatcher 事件进行分组显然会由于计时器而产生延迟,因此我想检测丢弃,因此我可以在丢弃发生后立即刷新一次。
为了在 WPF 应用程序之外跟踪鼠标位置,我们需要 钩子订阅整个Windows操作系统的消息并进行过滤 只有我们感兴趣。有关如何捕获的精彩博客文章 无论鼠标位置如何,都可以在此处找到鼠标消息。
here链接已损坏,因此我没有将其超链接添加到报价中。
以上段落引用自developer.de博客。您可以在 WPF 应用程序窗口之外找到有关检查 drop 的答案。这也是 OneDrive 上示例项目文件的链接。
首先我们需要一个属性来指示鼠标何时位于范围之外 申请。
public static bool IsMouseOutsideApp
{
get;
set;
}
然后我们需要修改HookCallback方法,使得当鼠标左键按下时 按钮已弹起,并将属性 (IsMouseOutsideApp) 设置为 true(如果 鼠标在应用程序之外。
internal static IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_LBUTTONUP == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
//check if POint in main window
Point pt = new Point(hookStruct.pt.x, hookStruct.pt.y);
var ptw = App.Current.MainWindow.PointFromScreen(pt);
var w = App.Current.MainWindow.Width;
var h = App.Current.MainWindow.Height;
//if point is outside MainWindow
if (ptw.X < 0 || ptw.Y < 0 || ptw.X > w || ptw.Y > h)
IsMouseOutsideApp = true;
else
IsMouseOutsideApp = false;
}
return CallNextHookEx(m_hookID, nCode, wParam, lParam);
}
我们需要实现的最后一件事是 DragSourceQueryContinueDrag 事件。实现很简单:
/// <summary>
/// Continuosly tracking Dragging mouse position
/// </summary>
///
///
private void DragSourceQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
//when keystate is non, draop is heppen
if (e.KeyStates == DragDropKeyStates.None)
{
//unsubscribe event
this.QueryContinueDrag -= queryhandler;
e.Handled = true;
//Unhooking on Mouse Up
InterceptMouse.UnhookWindowsHookEx(InterceptMouse.m_hookID);
//notifiy user about drop result
Task.Run(
() =>;
{
//Drop hepend outside Instantly app
if (InterceptMouse.IsMouseOutsideApp)
MessageBox.Show("Dragged outside app");
else
MessageBox.Show("Dragged inside app");
}
);
}
}