gpt4 book ai didi

c# - 如何使用文件组描述符将文件拖到资源管理器 C#

转载 作者:太空狗 更新时间:2023-10-29 20:15:21 25 4
gpt4 key购买 nike

我想将列表框的一个元素拖放到资源管理器中。当拖放开始时,我需要按需准备文件并将其保存到内存流中。你能给我提供一个例子,说明如何使用 FileGroupDescriptor 数据结构来做到这一点吗?谢谢。安德里亚

最佳答案

您可以在此处找到有关如何执行此操作的示例 Transferring Virtual Files to Windows Explorer in C# ;这里还有一些关于该主题的好信息:Outlook Drag and Drop in C#

简而言之,您要做的是使用 FILEDESCRIPTOR(您可以在 pinvoke.net 上找到它的声明详细信息)结构初始化 DataObject 以获取传输的文件及其内容。下面是一个关于如何将 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# - 如何使用文件组描述符将文件拖到资源管理器 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1845654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com