如何在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 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);



}

}

你可能感兴趣的:(thread,windows,Microsoft,Social)