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

我想将列表框的元素拖放到资源管理器中。 当拖放开始时,我需要按需准备文件并将其保存到内存流中。 您能否提供一个使用FileGroupDescriptor数据结构的示例? 谢谢。 安德里亚

你可以在这里找到一个如何在C#中将虚拟文件传输到Windows资源管理器的示例; 这里还有一些关于这个主题的好信息: 在C#中进行Outlook拖放

简而言之,您需要做的是使用FILEDESCRIPTOR初始化DataObject(您可以在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; } 

希望这会让你知道如何继续,问候