如何使用filegroupdescriptor将文件拖动到资源管理器c#

如何使用filegroupdescriptor将文件拖动到资源管理器c#,c#,drag-and-drop,explorer,C#,Drag And Drop,Explorer,我想将列表框的一个元素拖放到资源管理器中。开始拖放时,我需要按需准备文件并将其保存到内存流中。 你能给我一个关于如何使用FileGroupDescriptor数据结构的例子吗? 谢谢 Andrea你可以在这里找到一个如何做到这一点的例子;这里还有一些关于该主题的好信息: 简而言之,您需要做的是使用FILEDESCRIPTOR(您可以在pinvoke.net上找到其声明详细信息)结构初始化数据对象,以便传输文件及其内容。下面是如何将1文件从winforms列表框传输到资源管理器的示例 listbo

我想将列表框的一个元素拖放到资源管理器中。开始拖放时,我需要按需准备文件并将其保存到内存流中。 你能给我一个关于如何使用FileGroupDescriptor数据结构的例子吗? 谢谢
Andrea

你可以在这里找到一个如何做到这一点的例子;这里还有一些关于该主题的好信息:

简而言之,您需要做的是使用FILEDESCRIPTOR(您可以在pinvoke.net上找到其声明详细信息)结构初始化数据对象,以便传输文件及其内容。下面是如何将1文件从winforms列表框传输到资源管理器的示例

listbox的鼠标按下事件处理程序:

private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
    DataObject dataObject = new DataObject();
    DragFileInfo filesInfo = new DragFileInfo("d:\\test.txt");

    using (MemoryStream infoStream = GetFileDescriptor(filesInfo),
                        contentStream = GetFileContents(filesInfo))
    {
        dataObject.SetData(CFSTR_FILEDESCRIPTORW, infoStream);
        dataObject.SetData(CFSTR_FILECONTENTS, contentStream);
        dataObject.SetData(CFSTR_PERFORMEDDROPEFFECT, null);

        DoDragDrop(dataObject, DragDropEffects.All);
    }
}
初始化数据对象所需的代码:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct FILEDESCRIPTOR
{
    public UInt32 dwFlags;
    public Guid clsid;
    public System.Drawing.Size sizel;
    public System.Drawing.Point pointl;
    public UInt32 dwFileAttributes;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
    public UInt32 nFileSizeHigh;
    public UInt32 nFileSizeLow;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
    public String cFileName;
}

public const string CFSTR_PREFERREDDROPEFFECT = "Preferred DropEffect";
public const string CFSTR_PERFORMEDDROPEFFECT = "Performed DropEffect";
public const string CFSTR_FILEDESCRIPTORW = "FileGroupDescriptorW";
public const string CFSTR_FILECONTENTS = "FileContents";

public const Int32 FD_WRITESTIME = 0x00000020;
public const Int32 FD_FILESIZE = 0x00000040;
public const Int32 FD_PROGRESSUI = 0x00004000;

public struct DragFileInfo
{
    public string FileName;
    public string SourceFileName;
    public DateTime WriteTime;
    public Int64 FileSize;

    public DragFileInfo(string fileName)
    {
        FileName = Path.GetFileName(fileName);
        SourceFileName = fileName;
        WriteTime = DateTime.Now;
        FileSize = (new FileInfo(fileName)).Length;
    }
}

private MemoryStream GetFileDescriptor(DragFileInfo fileInfo)
{
    MemoryStream stream = new MemoryStream();
    stream.Write(BitConverter.GetBytes(1), 0, sizeof(UInt32));

    FILEDESCRIPTOR fileDescriptor = new FILEDESCRIPTOR();

    fileDescriptor.cFileName = fileInfo.FileName;
    Int64 fileWriteTimeUtc = fileInfo.WriteTime.ToFileTimeUtc();
    fileDescriptor.ftLastWriteTime.dwHighDateTime = (Int32)(fileWriteTimeUtc >> 32);
    fileDescriptor.ftLastWriteTime.dwLowDateTime = (Int32)(fileWriteTimeUtc & 0xFFFFFFFF);
    fileDescriptor.nFileSizeHigh = (UInt32)(fileInfo.FileSize >> 32);
    fileDescriptor.nFileSizeLow = (UInt32)(fileInfo.FileSize & 0xFFFFFFFF);
    fileDescriptor.dwFlags = FD_WRITESTIME | FD_FILESIZE | FD_PROGRESSUI;

    Int32   fileDescriptorSize = Marshal.SizeOf(fileDescriptor);
    IntPtr  fileDescriptorPointer = Marshal.AllocHGlobal(fileDescriptorSize);
    Byte[]  fileDescriptorByteArray = new Byte[fileDescriptorSize];

    try
    {
        Marshal.StructureToPtr(fileDescriptor, fileDescriptorPointer, true);
        Marshal.Copy(fileDescriptorPointer, fileDescriptorByteArray, 0, fileDescriptorSize);
    }
    finally
    {
        Marshal.FreeHGlobal(fileDescriptorPointer);
    }
    stream.Write(fileDescriptorByteArray, 0, fileDescriptorByteArray.Length);
    return stream;
}

private MemoryStream GetFileContents(DragFileInfo fileInfo)
{
    MemoryStream stream  = new MemoryStream();            
    using (BinaryReader reader = new BinaryReader(File.OpenRead(fileInfo.SourceFileName)))
    {
        Byte[] buffer = new Byte[fileInfo.FileSize];
        reader.Read(buffer, 0, (Int32)fileInfo.FileSize);
        if (buffer.Length == 0) buffer = new Byte[1];
        stream.Write(buffer, 0, buffer.Length);
    }
    return stream;
}
希望这能给你一个如何进行的想法,
关于

我在C++中确实很差,但是这有错误的<代码> siZeFo()/Cux>运算符使用的问题吗?他们说,
marshall.SizeOf
给出了编组后的大小。