如何在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,  0 ref  sf, Marshal.SizeOf(sf), SHGFI.PIDL  |  SHGFI.DISPLAYNAME  |  SHGFI.TYPENAME).ToInt32() > 0 )
                {
                    MessageBox.Show(sf.szDisplayName);
                }

                ILFree(abspidl);



            }

        }

 

 

 

 

 

 

你可能感兴趣的:(如何在DragDrop特殊文件夹时得到相关信息)