2011-11-14 88 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這種方法,你會得到的路徑序列(假設項目當然有路徑...例如,「我的電腦」沒有路徑)