您的位置:首页 > 运维架构

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

2009-05-29 13:33 295 查看
转自
/article/5124813.html
如何在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,x40000,
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,x10000,
SHELLICONSIZE = 4,
SMALLICON = 1,
SYSICONINDEX = 0x4000,
TYPENAME = 0x400,
USEFILEATTRIBUTES = 0x10
}
public enum FILE_ATTRIBUTE
{x00000001,
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: