今天在论坛看到一个贴子,问如何知道在拖放<我的电脑>
试了一下。发现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 IntPtrILCombine(
IntPtrpidl1,IntPtrpidl2);
[DllImport( " shell32.dll " )]
public static extern void ILFree(
IntPtrpidl);
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 IntPtrhIcon;
public int iIcon;
public SFGAOdwAttributes;
[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 IntPtrSHGetFileInfo(
IntPtrppidl,
FILE_ATTRIBUTEdwFileAttributes,
ref SHFILEINFOsfi,
int cbFileInfo,
SHGFIuFlags);
protected override void OnDragDrop(DragEventArgsdrgevent)
{
base .OnDragDrop(drgevent);
MemoryStreamdata = (MemoryStream)drgevent.Data.GetData( " ShellIDListArray " );
byte []b = data.ToArray();
IntPtrp = Marshal.AllocHGlobal(b.Length);
Marshal.Copy(b, 0 ,p,b.Length);
// Getnumberofitems.
UInt32cidl = (UInt32)Marshal.ReadInt32(p);
int offset = sizeof (UInt32);
IntPtrparentpidl = (IntPtr)(( int )p + (UInt32)Marshal.ReadInt32(p,offset));
// Getsubitems.
for ( int i = 1 ;i <= cidl; ++ i)
{
offset += sizeof (UInt32);
IntPtrrelpidl = (IntPtr)(( int )p + (UInt32)Marshal.ReadInt32(p,offset));
IntPtrabspidl = ILCombine(parentpidl,relpidl);
SHFILEINFOsf = 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);
}
}
public static extern IntPtrILCombine(
IntPtrpidl1,IntPtrpidl2);
[DllImport( " shell32.dll " )]
public static extern void ILFree(
IntPtrpidl);
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 IntPtrhIcon;
public int iIcon;
public SFGAOdwAttributes;
[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 IntPtrSHGetFileInfo(
IntPtrppidl,
FILE_ATTRIBUTEdwFileAttributes,
ref SHFILEINFOsfi,
int cbFileInfo,
SHGFIuFlags);
protected override void OnDragDrop(DragEventArgsdrgevent)
{
base .OnDragDrop(drgevent);
MemoryStreamdata = (MemoryStream)drgevent.Data.GetData( " ShellIDListArray " );
byte []b = data.ToArray();
IntPtrp = Marshal.AllocHGlobal(b.Length);
Marshal.Copy(b, 0 ,p,b.Length);
// Getnumberofitems.
UInt32cidl = (UInt32)Marshal.ReadInt32(p);
int offset = sizeof (UInt32);
IntPtrparentpidl = (IntPtr)(( int )p + (UInt32)Marshal.ReadInt32(p,offset));
// Getsubitems.
for ( int i = 1 ;i <= cidl; ++ i)
{
offset += sizeof (UInt32);
IntPtrrelpidl = (IntPtr)(( int )p + (UInt32)Marshal.ReadInt32(p,offset));
IntPtrabspidl = ILCombine(parentpidl,relpidl);
SHFILEINFOsf = 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);
}
}