拖拽Drop for SpecialFolders

时间:2011-11-14 17:21:09

标签: wpf drag-and-drop special-folders

我有一个应用程序,允许用户将文件或整个文件夹拖放到一个特殊的“放置区域”,此时处理所有文件。该应用程序正在使用WPF开发,这个特定的XAML视图将“AllowDrop”设置为true并在代码隐藏中处理Drop事件。

所有内容都适用于普通文件和标准Windows文件夹。但是,如果用户删除了一个特殊的Windows文件夹(例如,图片,视频),则该功能不起作用。这似乎是因为DragEventArgs.Data的内容不是DataFormats.FileDrop枚举。其他文件夹或文件并非如此。

我处理掉落的代码部分是:

private void OnDrop(object Sender, DragEventArgs E)
{
    if (E.Data.GetDataPresent(DataFormats.FileDrop))
    {
        var _droppedFilePaths = E.Data.GetData(DataFormats.FileDrop, true) as string[];

        // Process the files....
    }
}

有没有办法确定丢弃数据是否包含Windows 7图片库并映射回其实际路径?

1 个答案:

答案 0 :(得分:0)

使用描述here的解决方案,我编写了以下方法:

const string ShellIdListArrayName = "Shell IDList Array";

static IEnumerable<string> GetPathsFromShellIDListArray(IDataObject data)
{
    if (data.GetDataPresent(ShellIdListArrayName))
    {
        var ms = (MemoryStream)data.GetData(ShellIdListArrayName);
        byte[] bytes = ms.ToArray();

        IntPtr p = Marshal.AllocHGlobal(bytes.Length);
        Marshal.Copy(bytes, 0, p, bytes.Length);
        uint cidl = (uint)Marshal.ReadInt32(p, 0);

        int offset = sizeof(uint);
        IntPtr parentpidl = (IntPtr)((int)p + (uint)Marshal.ReadInt32(p, offset));
        StringBuilder path = new StringBuilder(256);
        SHGetPathFromIDList(parentpidl, path);

        for (int i = 1; i <= cidl; ++i)
        {
            offset += sizeof(uint);
            IntPtr relpidl = (IntPtr)((int)p + (uint)Marshal.ReadInt32(p, offset));
            IntPtr abspidl = ILCombine(parentpidl, relpidl);
            if (SHGetPathFromIDList(abspidl, path) != 0)
            {
                yield return path.ToString();
            }
            ILFree(abspidl);
        }
    }
}

[DllImport("shell32.dll")]
public static extern int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath); 

[DllImport("shell32.dll")]
public static extern IntPtr ILCombine(IntPtr pidl1, IntPtr pidl2);

[DllImport("shell32.dll")]
public static extern void ILFree(IntPtr pidl);

您可以将e.Data从事件处理程序传递给此方法,然后您将获得一系列路径(假设项目确实有路径...例如,“我的计算机”没有路径)

相关问题