2009-12-04 20 views
7

Gezinmek için bir liste kutusunun bir öğesinin sürükleyip bırakılmasını isterim. Sürükle ve bırak başladığında, dosyayı istek üzerine hazırlamalı ve bir bellek akışına kaydetmem gerek. FileGroupDescriptor veri yapısını kullanarak nasıl yapılacağına dair bir örnek verebilir misiniz? Teşekkürler. AndreaDosya gezgini sürüklemek için filegroupdescriptor nasıl kullanılır C#

cevap

9

Burada bunun nasıl yapılacağı hakkında bir örnek bulabilirsiniz Transferring Virtual Files to Windows Explorer in C#; Ayrıca burada konu hakkında bazı iyi bilgiler: Outlook Drag and Drop in C#

Yapmanız gereken şey, FILEDESCRIPTOR ile birlikte DataObject'i (pinvoke.net üzerindeki bildirim detaylarını bulabilirsiniz) yapı (lar) ını almaktır. aktarıldı ve içeriği. Aşağıda, kaşif için ListBox winform'larından dosyasını nasıl aktarabileceğinize dair bir örnek verilmiştir. liste kutusu için

fare aşağı olay işleyicisi: DataObject başlatmaya yarayacak

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

kodu: Bu size atılacak adımlar konusunda bir fikir verecektir

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

umut, Saygılarımızla

+0

Ben C++ 'da gerçekten fakirim ama bu makalede tartışıldığı gibi yanlış 'sizeof()' operatörüne sahip olmanın aynı sorunu var mı? http://www.codeproject.com/KB/cs/UnmanagedArraysInCSharp.aspx "Marshal.SizeOf" ifadesinin AFTER marshalling boyutuna sahip olduğunu söylüyorlar. – Maslow

İlgili konular