如何在DragDrop特殊文件夹时得到相关信息

今天在论坛看到一个贴子,问如何知道在拖放<我的电脑>

http://social.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/2a4fc136-3d57-4c64-87de-f19aa9a76d0e/

 

试了一下。发现DragEventArgs.Data可以得到"Shell IDList Array"格式的数据,它实际指向一个CIDA structurer

http://msdn.microsoft.com/en-us/library/bb773212.aspx

通过它,我们就可以得到对应的PIDL (如果对 PIDL 不熟悉,请看Windows外壳名字空间的浏览)。

有了PIDL, 我们就和容易得到文件的相关信息。

 

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


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

        
public enum SFGAO : uint
        {
            BROWSABLE 
= 0x8000000,
            CANCOPY 
= 1,
            CANDELETE 
= 0x20,
            CANLINK 
= 4,
            CANMONIKER 
= 0x400000,
            CANMOVE 
= 2,
            CANRENAME 
= 0x10,
            CAPABILITYMASK 
= 0x177,
            COMPRESSED 
= 0x4000000,
            CONTENTSMASK 
= 0x80000000,
            DISPLAYATTRMASK 
= 0xfc000,
            DROPTARGET 
= 0x100,
            ENCRYPTED 
= 0x2000,
            FILESYSANCESTOR 
= 0x10000000,
            FILESYSTEM 
= 0x40000000,
            FOLDER 
= 0x20000000,
            GHOSTED 
= 0x8000,
            HASPROPSHEET 
= 0x40,
            HASSTORAGE 
= 0x400000,
            HASSUBFOLDER 
= 0x80000000,
            HIDDEN 
= 0x80000,
            ISSLOW 
= 0x4000,
            LINK 
= 0x10000,
            NEWCONTENT 
= 0x200000,
            NONENUMERATED 
= 0x100000,
            READONLY 
= 0x40000,
            REMOVABLE 
= 0x2000000,
            SHARE 
= 0x20000,
            STORAGE 
= 8,
            STORAGEANCESTOR 
= 0x800000,
            STORAGECAPMASK 
= 0x70c50008,
            STREAM 
= 0x400000,
            VALIDATE 
= 0x1000000
        }
        
public const int MAX_PATH = 260;


        [StructLayout(LayoutKind.Sequential, CharSet 
= CharSet.Auto)]
        
public struct SHFILEINFO
        {
            
public IntPtr hIcon;
            
public int iIcon;
            
public SFGAO dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst 
= MAX_PATH)]
            
public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst 
= 80)]
            
public string szTypeName;
        }



        
public enum SHGFI : uint
        {
            ADDOVERLAYS 
= 0x20,
            ATTR_SPECIFIED 
= 0x20000,
            ATTRIBUTES 
= 0x800,
            DISPLAYNAME 
= 0x200,
            EXETYPE 
= 0x2000,
            ICON 
= 0x100,
            ICONLOCATION 
= 0x1000,
            LARGEICON 
= 0,
            LINKOVERLAY 
= 0x8000,
            OPENICON 
= 2,
            OVERLAYINDEX 
= 0x40,
            PIDL 
= 8,
            SELECTED 
= 0x10000,
            SHELLICONSIZE 
= 4,
            SMALLICON 
= 1,
            SYSICONINDEX 
= 0x4000,
            TYPENAME 
= 0x400,
            USEFILEATTRIBUTES 
= 0x10
        }


        
public enum FILE_ATTRIBUTE
        {
            READONLY 
= 0x00000001,
            HIDDEN 
= 0x00000002,
            SYSTEM 
= 0x00000004,
            DIRECTORY 
= 0x00000010,
            ARCHIVE 
= 0x00000020,
            DEVICE 
= 0x00000040,
            NORMAL 
= 0x00000080,
            TEMPORARY 
= 0x00000100,
            SPARSE_FILE 
= 0x00000200,
            REPARSE_POINT 
= 0x00000400,
            COMPRESSED 
= 0x00000800,
            OFFLINE 
= 0x00001000,
            NOT_CONTENT_INDEXED 
= 0x00002000,
            ENCRYPTED 
= 0x00004000
        }


        [DllImport(
"shell32",
            EntryPoint 
= "SHGetFileInfo",
            ExactSpelling 
= false,
            CharSet 
= CharSet.Auto,
            SetLastError 
= true)]
        
public static extern IntPtr SHGetFileInfo(
            IntPtr ppidl,
            FILE_ATTRIBUTE dwFileAttributes,
            
ref SHFILEINFO sfi,
            
int cbFileInfo,
            SHGFI uFlags);


protected override void OnDragDrop(DragEventArgs drgevent)
        {
            
base.OnDragDrop(drgevent);
            
            
            MemoryStream data 
= (MemoryStream)drgevent.Data.GetData("Shell IDList Array");
            
byte[] b = data.ToArray();
            IntPtr p 
= Marshal.AllocHGlobal(b.Length);
            Marshal.Copy(b, 
0, p, b.Length);


            
// Get number of items. 
            UInt32 cidl = (UInt32)Marshal.ReadInt32(p);
                                     
            
int offset = sizeof(UInt32);
            IntPtr parentpidl 
= (IntPtr)((int)p + (UInt32)Marshal.ReadInt32(p, offset));
            

            
// Get subitems. 
            for (int i = 1; i <= cidl; ++i)
            {
                offset 
+= sizeof(UInt32);
                IntPtr relpidl 
= (IntPtr)((int)p + (UInt32)Marshal.ReadInt32(p, offset));
                IntPtr abspidl 
= ILCombine(parentpidl, relpidl);
                SHFILEINFO sf
=new SHFILEINFO();
                
if (SHGetFileInfo(abspidl, 0ref sf, Marshal.SizeOf(sf), SHGFI.PIDL | SHGFI.DISPLAYNAME | SHGFI.TYPENAME).ToInt32()>0)
                {
                    MessageBox.Show(sf.szDisplayName);
                }

                ILFree(abspidl);



            }

        }

 

 

 

 

 

 

posted @ 2009-02-09 14:26  feiyun0112  阅读(...)  评论(...编辑  收藏