0

Ich habe eine Funktionalität entwickelt, wo Benutzer Drag-E-Mail-Anhänge auf meiner Anwendung ziehen kann. Ich extrahiere die gelöschten Anlagennamen übergeben "FileGroupDescriptor" -Format und verwenden "FileContents" -Format zum Extrahieren der Anlage Stream.Es funktioniert gut auf meinem System, aber Bei einigen anderen Systemen ist diese Funktionalität nicht in der Lage, Anhangsdaten zu extrahieren. Also dachte ich über die Implementierung einer Funktionalität nach, bei der ich das Typformat nicht hart codiere und es von IDataObject selbst abrufe. Gibt es eine Möglichkeit, es zu tun? Bitte, unter dem Code, den ich verwende:Wie bekomme ich die GetData-Funktion von IDataObject, ohne den Typ zu kennen?

public object GetData(string format, bool autoConvert) 
{ 
     try 
     { 
      //handle the "FileGroupDescriptor" and "FileContents" format request in this class otherwise pass through to underlying IDataObject 
      switch (format) 
      { 
       case "FileGroupDescriptor": 
        //override the default handling of FileGroupDescriptor which returns a 
        //MemoryStream and instead return a string array of file names 
        IntPtr fileGroupDescriptorAPointer = IntPtr.Zero; 
        try 
        { 
         //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream 
         Object o = underlyingDataObject.GetData(typeof(Object)); 
         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)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)); 

         //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)((long)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 
         IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptorWPointer)); 

         //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); 
     } 
     catch (Exception ex) 
     { 

     } 
} 

ich die obige Funktion mit dem folgenden Code aufrufen:

if (e.Data.GetDataPresent(DataFormats.FileDrop)) 
// drag drop from explorer to outlook DM Repository 
     filenames = (string[])(e.Data.GetData(DataFormats.FileDrop)); 
else 
{ 
     OutlookDataObject dataObject = new OutlookDataObject(e.Data); 
     filenames = (string[])dataObject.GetData("FileGroupDescriptor"); 
     filestreams = (MemoryStream[])dataObject.GetData("FileContents"); 
} 

Antwort

Verwandte Themen