如何使用filegroupdescriptor拖动文件资源管理器C# [英] How to use filegroupdescriptor to drag file to explorer c#

查看:495
本文介绍了如何使用filegroupdescriptor拖动文件资源管理器C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拖一个列表框的元素拖放到浏览器。当拖放开始,我需要prepare对需求的文件并将其保存到内存流。
你能为我提供有关如何使用FileGroupDesc​​riptor数据结构来做到这一点的例子吗?
谢谢。
安德烈

I would like to drag and drop an element of a listbox to explorer. When the drag and drop is started, I need to prepare the file on demand and save it to a memory stream. Can you provide me with an example on how to do it using the FileGroupDescriptor data structure? Thanks. Andrea

推荐答案

您可以找到关于如何做到这一点这里的在C#中传输虚拟文件到Windows资源管理器;同样的话题在这里一些好的信息:展望拖放在C#

you can find an example on how to do this here Transferring Virtual Files to Windows Explorer in C#; also some good info on the topic here: Outlook Drag and Drop in C#

总之你要做的就是给init数据对象与文件描述符(你可以找到pinvoke.net其声明的详细信息)的结构(S)文件(S)入门转移及其内容。下面是你如何可以从列表框的WinForms转移 1 文件资源管理器的例子。

In short what you have to do is to init the DataObject with FILEDESCRIPTOR (you can find its declaration details on pinvoke.net) structure(s) for file(s) getting transfered and their content. Below is an example on how you could transfer 1 file from winforms ListBox to explorer.

在列表框中按下鼠标事件处理程序:

mouse down event handler for the 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);
    }
}

给init数据对象所需的

code:

code needed to init the dataobject:

[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;
}

希望这会给你如何进行的想法,
问候

hope this will give you an idea on how to proceed, regards

这篇关于如何使用filegroupdescriptor拖动文件资源管理器C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆