2011-11-14 128 views
2

我有一个应用程序,允许用户将文件或整个文件夹拖放到一个特殊的“拖放区域”,此时所有文件都将被处理。该应用程序正在使用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

[本页](http://groups.google.com/group/microsoft.public.platformsdk.shell/browse_thread/thread/fdeda20d6841f433?pli = 1)似乎有Jim Barry的答案。它看起来不好玩。 –

回答

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这种方法,你会得到的路径序列(假设项目当然有路径...例如,“我的电脑”没有路径)