2012-01-03 14 views
8

I Utilizzare il seguente codice per il trascinamento di singoli file.Trascina più file associati da Outlook a C# Window Form

private void FormRegion2_DragEnter_1(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent(DataFormats.FileDrop)) 
     { e.Effect = DragDropEffects.Copy; } 
     // or this tells us if it is an Outlook attachment drop 
     else if (e.Data.GetDataPresent("FileGroupDescriptor")) 
     { e.Effect = DragDropEffects.Copy; } 
     // or none of the above 
     else 
     { e.Effect = DragDropEffects.None; } 
    } 

    private void FormRegion2_DragDrop_1(object sender, DragEventArgs e) 
    { 
     string[] fileNames = null; 


     if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true) 
     { 
      fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);     
      foreach (string fileName in fileNames) 
      { 
      } 
     } 
     else if (e.Data.GetDataPresent("FileGroupDescriptor")) 
     { 
      object s = e.Data.GetData("FileGroupDescriptor"); 

      Stream theStream = (Stream)e.Data.GetData("FileGroupDescriptor"); 
      byte[] fileGroupDescriptor = new byte[512]; 
      theStream.Read(fileGroupDescriptor, 0, 512); 

      StringBuilder fileName = new StringBuilder(""); 

      for (int i = 76; fileGroupDescriptor[i] != 0; i++) 
      { fileName.Append(Convert.ToChar(fileGroupDescriptor[i])); } 

      string theFile = fileName.ToString();    
      String fileName1 = System.IO.Path.GetFileName(theFile);     

     } 

    } 

Il mio problema è che non sono in grado di ottenere più nome di file. Come è possibile ottenere più il nome del file

Thx

+0

Questo è un sacco di codice ... Dove esattamente si verifica il problema? Cosa ottieni invece? –

+0

Sono in grado di ottenere il nome di un singolo file, ma voglio ottenere più nomi di file. Come è possibile –

+1

Se trascino più file, non sono in grado di ottenere entrambi il nome del file. Sono solo in grado di ottenere il primo nome di file utilizzando il codice di cui sopra. Così come ottengo entrambi i nomi di file qualsiasi soluzione plz –

risposta

9

ho risolvere il mio problema solo aggiungere che il codice in qualsiasi file cs.

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 
using System.Text; 
using System.Reflection; 
using System.Windows.Forms; 

    namespace iwantedue.Windows.Forms 
{ 

public class OutlookDataObject: System.Windows.Forms.IDataObject 
{ 
    #region NativeMethods 

    private class NativeMethods 
    { 
     [DllImport("kernel32.dll")] 
     static extern IntPtr GlobalLock(IntPtr hMem); 

     [DllImport("ole32.dll", PreserveSig = false)] 
     public static extern ILockBytes CreateILockBytesOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease); 

     [DllImport("OLE32.DLL", CharSet = CharSet.Auto, PreserveSig = false)] 
     public static extern IntPtr GetHGlobalFromILockBytes(ILockBytes pLockBytes); 

     [DllImport("OLE32.DLL", CharSet = CharSet.Unicode, PreserveSig = false)] 
     public static extern IStorage StgCreateDocfileOnILockBytes(ILockBytes plkbyt, uint grfMode, uint reserved); 

     [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000000B-0000-0000-C000-000000000046")] 
     public interface IStorage 
     { 
      [return: MarshalAs(UnmanagedType.Interface)] 
      IStream CreateStream([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, [In, MarshalAs(UnmanagedType.U4)] int grfMode, [In, MarshalAs(UnmanagedType.U4)] int reserved1, [In, MarshalAs(UnmanagedType.U4)] int reserved2); 
      [return: MarshalAs(UnmanagedType.Interface)] 
      IStream OpenStream([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, IntPtr reserved1, [In, MarshalAs(UnmanagedType.U4)] int grfMode, [In, MarshalAs(UnmanagedType.U4)] int reserved2); 
      [return: MarshalAs(UnmanagedType.Interface)] 
      IStorage CreateStorage([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, [In, MarshalAs(UnmanagedType.U4)] int grfMode, [In, MarshalAs(UnmanagedType.U4)] int reserved1, [In, MarshalAs(UnmanagedType.U4)] int reserved2); 
      [return: MarshalAs(UnmanagedType.Interface)] 
      IStorage OpenStorage([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, IntPtr pstgPriority, [In, MarshalAs(UnmanagedType.U4)] int grfMode, IntPtr snbExclude, [In, MarshalAs(UnmanagedType.U4)] int reserved); 
      void CopyTo(int ciidExclude, [In, MarshalAs(UnmanagedType.LPArray)] Guid[] pIIDExclude, IntPtr snbExclude, [In, MarshalAs(UnmanagedType.Interface)] IStorage stgDest); 
      void MoveElementTo([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, [In, MarshalAs(UnmanagedType.Interface)] IStorage stgDest, [In, MarshalAs(UnmanagedType.BStr)] string pwcsNewName, [In, MarshalAs(UnmanagedType.U4)] int grfFlags); 
      void Commit(int grfCommitFlags); 
      void Revert(); 
      void EnumElements([In, MarshalAs(UnmanagedType.U4)] int reserved1, IntPtr reserved2, [In, MarshalAs(UnmanagedType.U4)] int reserved3, [MarshalAs(UnmanagedType.Interface)] out object ppVal); 
      void DestroyElement([In, MarshalAs(UnmanagedType.BStr)] string pwcsName); 
      void RenameElement([In, MarshalAs(UnmanagedType.BStr)] string pwcsOldName, [In, MarshalAs(UnmanagedType.BStr)] string pwcsNewName); 
      void SetElementTimes([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, [In] System.Runtime.InteropServices.ComTypes.FILETIME pctime, [In] System.Runtime.InteropServices.ComTypes.FILETIME patime, [In] System.Runtime.InteropServices.ComTypes.FILETIME pmtime); 
      void SetClass([In] ref Guid clsid); 
      void SetStateBits(int grfStateBits, int grfMask); 
      void Stat([Out]out System.Runtime.InteropServices.ComTypes.STATSTG pStatStg, int grfStatFlag); 
     } 

     [ComImport, Guid("0000000A-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
     public interface ILockBytes 
     { 
      void ReadAt([In, MarshalAs(UnmanagedType.U8)] long ulOffset, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, [In, MarshalAs(UnmanagedType.U4)] int cb, [Out, MarshalAs(UnmanagedType.LPArray)] int[] pcbRead); 
      void WriteAt([In, MarshalAs(UnmanagedType.U8)] long ulOffset, IntPtr pv, [In, MarshalAs(UnmanagedType.U4)] int cb, [Out, MarshalAs(UnmanagedType.LPArray)] int[] pcbWritten); 
      void Flush(); 
      void SetSize([In, MarshalAs(UnmanagedType.U8)] long cb); 
      void LockRegion([In, MarshalAs(UnmanagedType.U8)] long libOffset, [In, MarshalAs(UnmanagedType.U8)] long cb, [In, MarshalAs(UnmanagedType.U4)] int dwLockType); 
      void UnlockRegion([In, MarshalAs(UnmanagedType.U8)] long libOffset, [In, MarshalAs(UnmanagedType.U8)] long cb, [In, MarshalAs(UnmanagedType.U4)] int dwLockType); 
      void Stat([Out]out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, [In, MarshalAs(UnmanagedType.U4)] int grfStatFlag); 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public sealed class POINTL 
     { 
      public int x; 
      public int y; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public sealed class SIZEL 
     { 
      public int cx; 
      public int cy; 
     } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public sealed class FILEGROUPDESCRIPTORA 
     { 
      public uint cItems; 
      public FILEDESCRIPTORA[] fgd; 
     } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public sealed class FILEDESCRIPTORA 
     { 
      public uint dwFlags; 
      public Guid clsid; 
      public SIZEL sizel; 
      public POINTL pointl; 
      public uint dwFileAttributes; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; 
      public uint nFileSizeHigh; 
      public uint nFileSizeLow; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
      public string cFileName; 
     } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     public sealed class FILEGROUPDESCRIPTORW 
     { 
      public uint cItems; 
      public FILEDESCRIPTORW[] fgd; 
     } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     public sealed class FILEDESCRIPTORW 
     { 
      public uint dwFlags; 
      public Guid clsid; 
      public SIZEL sizel; 
      public POINTL pointl; 
      public uint dwFileAttributes; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; 
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; 
      public uint nFileSizeHigh; 
      public uint nFileSizeLow; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
      public string cFileName; 
     } 
    } 

    #endregion 

    #region Property(s) 

    /// <summary> 
    /// Holds the <see cref="System.Windows.Forms.IDataObject"/> that this class is wrapping 
    /// </summary> 
    private System.Windows.Forms.IDataObject underlyingDataObject; 



    private System.Runtime.InteropServices.ComTypes.IDataObject comUnderlyingDataObject; 



    private System.Windows.Forms.IDataObject oleUnderlyingDataObject; 
    private MethodInfo getDataFromHGLOBLALMethod; 
    #endregion 

    #region Constructor(s) 

    public OutlookDataObject(System.Windows.Forms.IDataObject underlyingDataObject) 
    { 

     this.underlyingDataObject = underlyingDataObject; 
     this.comUnderlyingDataObject = (System.Runtime.InteropServices.ComTypes.IDataObject)this.underlyingDataObject; 

     FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance); 
     this.oleUnderlyingDataObject = (System.Windows.Forms.IDataObject)innerDataField.GetValue(this.underlyingDataObject); 
     this.getDataFromHGLOBLALMethod = this.oleUnderlyingDataObject.GetType().GetMethod("GetDataFromHGLOBLAL", BindingFlags.NonPublic | BindingFlags.Instance); 
    } 

    #endregion 

    #region IDataObject Members 

    public object GetData(Type format) 
    { 
     return this.GetData(format.FullName); 
    } 


    public object GetData(string format) 
    { 
     return this.GetData(format, true); 
    } 

    public object GetData(string format, bool autoConvert) 
    { 
     switch(format) 
     { 
      case "FileGroupDescriptor": 
       IntPtr fileGroupDescriptorAPointer = IntPtr.Zero; 
       try 
       { 
        //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream 
        MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData("FileGroupDescriptor", autoConvert); 
        byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length]; 
        fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); 
        fileGroupDescriptorStream.Close(); 

        //copy the file group descriptor into unmanaged memory 
        fileGroupDescriptorAPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length); 
        Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorAPointer, fileGroupDescriptorBytes.Length); 

        //marshal the unmanaged memory to to FILEGROUPDESCRIPTORA struct 
        object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorAPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORA)); 
        NativeMethods.FILEGROUPDESCRIPTORA fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORA)fileGroupDescriptorObject; 

        //create a new array to store file names in of the number of items in the file group descriptor 
        string[] fileNames = new string[fileGroupDescriptor.cItems]; 

        //get the pointer to the first file descriptor 
        IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptor.cItems)); 

        //loop for the number of files acording to the file group descriptor 
        for(int fileDescriptorIndex = 0;fileDescriptorIndex < fileGroupDescriptor.cItems;fileDescriptorIndex++) 
        { 

         //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name 
         NativeMethods.FILEDESCRIPTORA fileDescriptor = (NativeMethods.FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORA)); 
         fileNames[fileDescriptorIndex] = fileDescriptor.cFileName; 

         //move the file descriptor pointer to the next file descriptor 
         fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor)); 
        } 

        //return the array of filenames 
        return fileNames; 
       } 
       finally 
       { 
        //free unmanaged memory pointer 
        Marshal.FreeHGlobal(fileGroupDescriptorAPointer); 
       } 

      case "FileGroupDescriptorW": 
       //override the default handling of FileGroupDescriptorW which returns a 
       //MemoryStream and instead return a string array of file names 
       IntPtr fileGroupDescriptorWPointer = IntPtr.Zero; 
       try 
       { 
        //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream 
        MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData("FileGroupDescriptorW"); 
        byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length]; 
        fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length); 
        fileGroupDescriptorStream.Close(); 

        //copy the file group descriptor into unmanaged memory 
        fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length); 
        Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length); 

        //marshal the unmanaged memory to to FILEGROUPDESCRIPTORW struct 
        object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORW)); 
        NativeMethods.FILEGROUPDESCRIPTORW fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORW)fileGroupDescriptorObject; 

        //create a new array to store file names in of the number of items in the file group descriptor 
        string[] fileNames = new string[fileGroupDescriptor.cItems]; 

        //get the pointer to the first file descriptor 
        //get the pointer to the first file descriptor 
        IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems)); 


        //loop for the number of files acording to the file group descriptor 
        for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++) 
        { 
         //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name 
         NativeMethods.FILEDESCRIPTORW fileDescriptor = (NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORW)); 
         fileNames[fileDescriptorIndex] = fileDescriptor.cFileName; 

         //move the file descriptor pointer to the next file descriptor 
         fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor)); 
        } 

        //return the array of filenames 
        return fileNames; 
       } 
       finally 
       { 
        //free unmanaged memory pointer 
        Marshal.FreeHGlobal(fileGroupDescriptorWPointer); 
       } 

      case "FileContents": 
       //override the default handling of FileContents which returns the 
       //contents of the first file as a memory stream and instead return 
       //a array of MemoryStreams containing the data to each file dropped 

       //get the array of filenames which lets us know how many file contents exist 
       string[] fileContentNames = (string[])this.GetData("FileGroupDescriptor"); 

       //create a MemoryStream array to store the file contents 
       MemoryStream[] fileContents = new MemoryStream[fileContentNames.Length]; 

       //loop for the number of files acording to the file names 
       for(int fileIndex = 0;fileIndex < fileContentNames.Length;fileIndex++) 
       { 
        //get the data at the file index and store in array 
        fileContents[fileIndex] = this.GetData(format, fileIndex); 
       } 

       //return array of MemoryStreams containing file contents 
       return fileContents; 
     } 

     //use underlying IDataObject to handle getting of data 
     return this.underlyingDataObject.GetData(format, autoConvert); 
    } 

    /// <summary> 
    /// Retrieves the data associated with the specified data format at the specified index. 
    /// </summary> 
    /// <param name="format">The format of the data to retrieve. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <param name="index">The index of the data to retrieve.</param> 
    /// <returns> 
    /// A <see cref="MemoryStream"/> containing the raw data for the specified data format at the specified index. 
    /// </returns> 
    public MemoryStream GetData(string format, int index) 
    { 
     //create a FORMATETC struct to request the data with 
     FORMATETC formatetc = new FORMATETC(); 
     formatetc.cfFormat = (short)DataFormats.GetFormat(format).Id; 
     formatetc.dwAspect = DVASPECT.DVASPECT_CONTENT; 
     formatetc.lindex = index; 
     formatetc.ptd = new IntPtr(0); 
     formatetc.tymed = TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE | TYMED.TYMED_HGLOBAL; 

     //create STGMEDIUM to output request results into 
     STGMEDIUM medium = new STGMEDIUM(); 

     //using the Com IDataObject interface get the data using the defined FORMATETC 
     this.comUnderlyingDataObject.GetData(ref formatetc, out medium); 

     //retrieve the data depending on the returned store type 
     switch(medium.tymed) 
     { 
      case TYMED.TYMED_ISTORAGE: 
       //to handle a IStorage it needs to be written into a second unmanaged 
       //memory mapped storage and then the data can be read from memory into 
       //a managed byte and returned as a MemoryStream 

       NativeMethods.IStorage iStorage = null; 
       NativeMethods.IStorage iStorage2 = null; 
       NativeMethods.ILockBytes iLockBytes = null; 
       System.Runtime.InteropServices.ComTypes.STATSTG iLockBytesStat; 
       try 
       { 
        //marshal the returned pointer to a IStorage object 
        iStorage = (NativeMethods.IStorage)Marshal.GetObjectForIUnknown(medium.unionmember); 
        Marshal.Release(medium.unionmember); 

        //create a ILockBytes (unmanaged byte array) and then create a IStorage using the byte array as a backing store 
        iLockBytes = NativeMethods.CreateILockBytesOnHGlobal(IntPtr.Zero, true); 
        iStorage2 = NativeMethods.StgCreateDocfileOnILockBytes(iLockBytes, 0x00001012, 0); 

        //copy the returned IStorage into the new IStorage 
        iStorage.CopyTo(0, null, IntPtr.Zero, iStorage2); 
        iLockBytes.Flush(); 
        iStorage2.Commit(0); 

        //get the STATSTG of the ILockBytes to determine how many bytes were written to it 
        iLockBytesStat = new System.Runtime.InteropServices.ComTypes.STATSTG(); 
        iLockBytes.Stat(out iLockBytesStat, 1); 
        int iLockBytesSize = (int)iLockBytesStat.cbSize; 

        //read the data from the ILockBytes (unmanaged byte array) into a managed byte array 
        byte[] iLockBytesContent = new byte[iLockBytesSize]; 
        iLockBytes.ReadAt(0, iLockBytesContent, iLockBytesContent.Length, null); 

        //wrapped the managed byte array into a memory stream and return it 
        return new MemoryStream(iLockBytesContent); 
       } 
       finally 
       { 
        //release all unmanaged objects 
        Marshal.ReleaseComObject(iStorage2); 
        Marshal.ReleaseComObject(iLockBytes); 
        Marshal.ReleaseComObject(iStorage); 
       } 

      case TYMED.TYMED_ISTREAM: 
       //to handle a IStream it needs to be read into a managed byte and 
       //returned as a MemoryStream 

       IStream iStream = null; 
       System.Runtime.InteropServices.ComTypes.STATSTG iStreamStat; 
       try 
       { 
        //marshal the returned pointer to a IStream object 
        iStream = (IStream)Marshal.GetObjectForIUnknown(medium.unionmember); 
        Marshal.Release(medium.unionmember); 

        //get the STATSTG of the IStream to determine how many bytes are in it 
        iStreamStat = new System.Runtime.InteropServices.ComTypes.STATSTG(); 
        iStream.Stat(out iStreamStat, 0); 
        int iStreamSize = (int)iStreamStat.cbSize; 

        //read the data from the IStream into a managed byte array 
        byte[] iStreamContent = new byte[iStreamSize]; 
        iStream.Read(iStreamContent, iStreamContent.Length, IntPtr.Zero); 

        //wrapped the managed byte array into a memory stream and return it 
        return new MemoryStream(iStreamContent); 
       } 
       finally 
       { 
        //release all unmanaged objects 
        Marshal.ReleaseComObject(iStream); 
       } 

      case TYMED.TYMED_HGLOBAL: 
       //to handle a HGlobal the exisitng "GetDataFromHGLOBLAL" method is invoked via 
       //reflection 

       return (MemoryStream)this.getDataFromHGLOBLALMethod.Invoke(this.oleUnderlyingDataObject, new object[] { DataFormats.GetFormat((short)formatetc.cfFormat).Name, medium.unionmember }); 
     } 

     return null; 
    } 

    /// <summary> 
    /// Determines whether data stored in this instance is associated with, or can be converted to, the specified format. 
    /// </summary> 
    /// <param name="format">A <see cref="T:System.Type"></see> representing the format for which to check. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <returns> 
    /// true if data stored in this instance is associated with, or can be converted to, the specified format; otherwise, false. 
    /// </returns> 
    public bool GetDataPresent(Type format) 
    { 
     return this.underlyingDataObject.GetDataPresent(format); 
    } 

    /// <summary> 
    /// Determines whether data stored in this instance is associated with, or can be converted to, the specified format. 
    /// </summary> 
    /// <param name="format">The format for which to check. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <returns> 
    /// true if data stored in this instance is associated with, or can be converted to, the specified format; otherwise false. 
    /// </returns> 
    public bool GetDataPresent(string format) 
    { 
     return this.underlyingDataObject.GetDataPresent(format); 
    } 

    /// <summary> 
    /// Determines whether data stored in this instance is associated with the specified format, using a Boolean value to determine whether to convert the data to the format. 
    /// </summary> 
    /// <param name="format">The format for which to check. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <param name="autoConvert">true to determine whether data stored in this instance can be converted to the specified format; false to check whether the data is in the specified format.</param> 
    /// <returns> 
    /// true if the data is in, or can be converted to, the specified format; otherwise, false. 
    /// </returns> 
    public bool GetDataPresent(string format, bool autoConvert) 
    { 
     return this.underlyingDataObject.GetDataPresent(format, autoConvert); 
    } 

    /// <summary> 
    /// Returns a list of all formats that data stored in this instance is associated with or can be converted to. 
    /// </summary> 
    /// <returns> 
    /// An array of the names that represents a list of all formats that are supported by the data stored in this object. 
    /// </returns> 
    public string[] GetFormats() 
    { 
     return this.underlyingDataObject.GetFormats(); 
    } 


    public string[] GetFormats(bool autoConvert) 
    { 
     return this.underlyingDataObject.GetFormats(autoConvert); 
    } 

    /// <summary> 
    /// Stores the specified data in this instance, using the class of the data for the format. 
    /// </summary> 
    /// <param name="data">The data to store.</param> 
    public void SetData(object data) 
    { 
     this.underlyingDataObject.SetData(data); 
    } 

    /// <summary> 
    /// Stores the specified data and its associated class type in this instance. 
    /// </summary> 
    /// <param name="format">A <see cref="T:System.Type"></see> representing the format associated with the data. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <param name="data">The data to store.</param> 
    public void SetData(Type format, object data) 
    { 
     this.underlyingDataObject.SetData(format, data); 
    } 

    /// <summary> 
    /// Stores the specified data and its associated format in this instance. 
    /// </summary> 
    /// <param name="format">The format associated with the data. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <param name="data">The data to store.</param> 
    public void SetData(string format, object data) 
    { 
     this.underlyingDataObject.SetData(format, data); 
    } 

    /// <summary> 
    /// Stores the specified data and its associated format in this instance, using a Boolean value to specify whether the data can be converted to another format. 
    /// </summary> 
    /// <param name="format">The format associated with the data. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param> 
    /// <param name="autoConvert">true to allow the data to be converted to another format; otherwise, false.</param> 
    /// <param name="data">The data to store.</param> 
    public void SetData(string format, bool autoConvert, object data) 
    { 
     this.underlyingDataObject.SetData(format, autoConvert, data); 
    } 

    #endregion 
} 
} 

E scrivere drop del genere

private void FormRegion2_DragDrop_1(object sender, DragEventArgs e) 
    {   
     string[] fileNames = null;   

     if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true) 
     { 
      fileNames = (string[])e.Data.GetData(DataFormats.FileDrop); 
      foreach (string fileName in fileNames) 
      { 
       // do what you are going to do with each filename 
      } 
     } 
     else if (e.Data.GetDataPresent("FileGroupDescriptor")) 
     {        
      OutlookDataObject dataObject = new OutlookDataObject(e.Data); 
      string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");     
      for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++) 
      {     
       //Write your logic here u get multiple file name here 
      }    
     } 
    } 
+1

È tutto quel codice davvero necessario (per illustrare la soluzione)? –

+1

sì Tutto il codice che scrivo sia per FileGroupDescriptor che FileGroupDescriptorW –

+5

Sono ragionevolmente sicuro che tutto questo codice * non * sia necessario. Non è necessario P/Richiamare molte funzioni; molti di loro hanno gestito wrapper. Dubito anche che tu abbia scritto tutto questo codice da solo. Sembra qualcosa che hai copiato da qualcun altro. Dovresti dare credito laddove il credito è dovuto. –

3

C'è un bug nella risposta da V_B. E 'nella sezione:

case "FileGroupDescriptorW": 

L'implementazione originale sotto per determinare il numero di elementi nella matrice è un po' traballante, oltre che getterebbe exeptions danneggiamento della memoria quando avremmo trascinare file su una vista ad albero Infragistics su 8. vincere

Ricerca di "drag drop WIN8 FILEGROUPDESCRIPTORW scrittura della memoria protetta" mi ha portato a un post sul

https://social.msdn.microsoft.com/Forums/en-US/c9871410-1069-4dcb-a87d-b9c86ccbdd43/marshalptrtostructure-problem-when-drag-drop-mail-items-from-outlook-express?forum=winforms

Quello ha spiegato che si tratta di un problema con il marshaller e ci hanno suggerito di utilizzare Marshal.ReadInt32 e poi 'aumentare il puntatore' e 'letto ogni all'interno di un ciclo'

Visto che è esattamente ciò che è stato fatto nel seguente codice (che non ho scritto,), Penso che questa sia stata l'intenzione degli autori per tutto il tempo. Il sito ci stuzzica con la promessa di maggiori informazioni con un altro link morto.

Ho provato a modificare il commento, ma è stato respinto dalla revisione tra pari. Immagino che il software di lavoro non sia importante.

sostituire

object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORW)); 
NativeMethods.FILEGROUPDESCRIPTORW fgd = (NativeMethods.FILEGROUPDESCRIPTORW)fileGroupDescriptorObject; 
files = new NativeMethods.FILEDESCRIPTOR[fgd.cItems]; 
pdata = (IntPtr)((int)pdata + Marshal.SizeOf(pdata)); 
for (int index = 0; index < fgd.cItems; index++) 

con

int ITEMCOUNT = Marshal.ReadInt32(pdata);     
files = new NativeMethods.FILEDESCRIPTOR[ITEMCOUNT]; 
// Set our pointer offset to the beginning of the FILEDESCRIPTOR* array 
pdata = (IntPtr)((long)pdata + Marshal.SizeOf(pdata)); 
// Walk the array, converting each FILEDESCRIPTOR* to a FILEDESCRIPTOR 
for (int index = 0; index < ITEMCOUNT; index++) 
+1

Non ti è capitato di trovare che il nome del file fosse Mancano i suoi primi due personaggi quando lo facevi, vero? – pquest

+0

Sfortunatamente, questo codice non ha molto senso. A che serve leggere un intero (in 'ITEMCOUNT') e quindi modificare' pdata' senza motivo? Inoltre, nessuno del codice si trova all'interno del ciclo, che non è quello che suggeriva quel collegamento. – Christian

+0

Penso che la cosa più importante che hai fatto qui fosse cambiare il (int) in un (lungo) indirizzo di memoria a 64 bit in modo che fosse consegnato correttamente in ambienti di lavoro a 64 bit. Ci sono quattro posizioni da risolvere, due nel fileGroupDescriptorWPointer e due nelle istruzioni caseGroupDescriptorAPointer. – Brain2000

Problemi correlati