如何检测 WFP 应用程序外部的 drop

问题描述 投票:0回答:1

我有一个WPF窗口,它显示文件夹(ListView)的内容,并实现了将文件从窗口拖放到桌面或资源管理器窗口(使用GongSolutions拖放库)。

我可以毫无问题地检测应用程序内的删除,但我需要检测何时删除发生在应用程序外部(桌面或资源管理器窗口),以便我可以刷新窗口以反映已移动的文件。

有什么方法可以检测应用程序外部发生的掉落吗?

我知道我可以使用 FileSystemWatcher 来检测文件的离开,但这有一个缺点,如果用户一次拖放多个文件,它会触发多次。使用计时器对 FileSystemWatcher 事件进行分组显然会由于计时器而产生延迟,因此我想检测丢弃,因此我可以在丢弃发生后立即刷新一次。

c# wpf drag-and-drop
1个回答
0
投票

为了在 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");
            }
            );
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.