简体   繁体   中英

WPF: Drag and drop a file into the whole window (titlebar and window borders included)

In WinForms and other applications (eg Windows Notepad), you can drag and drop (eg a file) into the whole window – this includes the title bar and window borders.

In WPF, you can drag a file only into the window canvas – trying to drag it over the title bar or window borders results in the “no” cursor.

在此处输入图片说明

How can I make an ordinary WPF window (SingleBorderWindow WindowStyle, etc.) accept drag and drop into the whole window?

The difference is that WPF is not calling the OS DragAcceptFiles API when you set AllowDrop="true". DragAcceptFiles registers the entire window as a drop target.

You'll need to pinvoke and have a small window procedure to handle the drop message.

Here's a small test program I made to allow the WPF window to accept the drop anywhere.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

     const int WM_DROPFILES = 0x233;

    [DllImport("shell32.dll")]
    static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);

    [DllImport("shell32.dll")]
    static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder filename, uint cch);

    [DllImport("shell32.dll")]
    static extern void DragFinish(IntPtr hDrop);


    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        var helper = new WindowInteropHelper(this);
        var hwnd = helper.Handle;

        HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
         source.AddHook(WndProc);

        DragAcceptFiles(hwnd, true);
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_DROPFILES) 
        {
            handled = true;
            return HandleDropFiles(wParam);
        }

        return IntPtr.Zero;
    }

    private IntPtr HandleDropFiles(IntPtr hDrop)
    {
        this.info.Text = "Dropped!";

        const int MAX_PATH = 260;

        var count = DragQueryFile(hDrop, 0xFFFFFFFF, null, 0);

        for (uint i = 0; i < count; i++)
        {
            int size = (int) DragQueryFile(hDrop, i, null, 0);

            var filename = new StringBuilder(size + 1);
            DragQueryFile(hDrop, i, filename, MAX_PATH);

            Debug.WriteLine("Dropped: " + filename.ToString());
        }

        DragFinish(hDrop);

        return IntPtr.Zero;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM