private MemoryStream GetFileDescriptor(OleDataObjectItem[] SelectedItems) { MemoryStream FileDescriptorMemoryStream = new MemoryStream(); // Write out the FILEGROUPDESCRIPTOR.cItems value FileDescriptorMemoryStream.Write(BitConverter.GetBytes(SelectedItems.Length), 0, sizeof(UInt32)); Win32.NativeMethods.FILEDESCRIPTORW FileDescriptor = new Win32.NativeMethods.FILEDESCRIPTORW(); foreach (OleDataObjectItem si in SelectedItems) { FileDescriptor.cFileName = si.FileName; Int64 FileWriteTimeUtc = si.WriteTime.ToFileTimeUtc(); FileDescriptor.ftLastWriteTime.dwHighDateTime = (Int32)(FileWriteTimeUtc >> 32); FileDescriptor.ftLastWriteTime.dwLowDateTime = (Int32)(FileWriteTimeUtc & 0xFFFFFFFF); FileDescriptor.nFileSizeHigh = (UInt32)(si.FileSize >> 32); FileDescriptor.nFileSizeLow = (UInt32)(si.FileSize & 0xFFFFFFFF); FileDescriptor.dwFlags = Win32.NativeMethods.FD_WRITESTIME | Win32.NativeMethods.FD_FILESIZE | Win32.NativeMethods.FD_PROGRESSUI; // Marshal the FileDescriptor structure into a byte array and write it to the MemoryStream. Int32 FileDescriptorSize = Marshal.SizeOf(FileDescriptor); IntPtr FileDescriptorPointer = Marshal.AllocHGlobal(FileDescriptorSize); Marshal.StructureToPtr(FileDescriptor, FileDescriptorPointer, true); Byte[] FileDescriptorByteArray = new Byte[FileDescriptorSize]; Marshal.Copy(FileDescriptorPointer, FileDescriptorByteArray, 0, FileDescriptorSize); Marshal.FreeHGlobal(FileDescriptorPointer); FileDescriptorMemoryStream.Write(FileDescriptorByteArray, 0, FileDescriptorByteArray.Length); } return(FileDescriptorMemoryStream); }
private MemoryStream GetFileDescriptor(OleDataObjectItem[] SelectedItems) { MemoryStream FileDescriptorMemoryStream = new MemoryStream(); // Write out the FILEGROUPDESCRIPTOR.cItems value FileDescriptorMemoryStream.Write(BitConverter.GetBytes(SelectedItems.Length), 0, sizeof(UInt32)); Win32.NativeMethods.FILEDESCRIPTORW FileDescriptor = new Win32.NativeMethods.FILEDESCRIPTORW(); foreach (OleDataObjectItem si in SelectedItems) { FileDescriptor.cFileName = si.FileName; Int64 FileWriteTimeUtc = si.WriteTime.ToFileTimeUtc(); FileDescriptor.ftLastWriteTime.dwHighDateTime = (Int32)(FileWriteTimeUtc >> 32); FileDescriptor.ftLastWriteTime.dwLowDateTime = (Int32)(FileWriteTimeUtc & 0xFFFFFFFF); FileDescriptor.nFileSizeHigh = (UInt32)(si.FileSize >> 32); FileDescriptor.nFileSizeLow = (UInt32)(si.FileSize & 0xFFFFFFFF); FileDescriptor.dwFlags = Win32.NativeMethods.FD_WRITESTIME | Win32.NativeMethods.FD_FILESIZE | Win32.NativeMethods.FD_PROGRESSUI; // Marshal the FileDescriptor structure into a byte array and write it to the MemoryStream. Int32 FileDescriptorSize = Marshal.SizeOf(FileDescriptor); IntPtr FileDescriptorPointer = Marshal.AllocHGlobal(FileDescriptorSize); Marshal.StructureToPtr(FileDescriptor, FileDescriptorPointer, true); Byte[] FileDescriptorByteArray = new Byte[FileDescriptorSize]; Marshal.Copy(FileDescriptorPointer, FileDescriptorByteArray, 0, FileDescriptorSize); Marshal.FreeHGlobal(FileDescriptorPointer); FileDescriptorMemoryStream.Write(FileDescriptorByteArray, 0, FileDescriptorByteArray.Length); } return FileDescriptorMemoryStream; }
/// <summary> /// Retrieves the data associated with the specified data format, using a Boolean to determine whether to convert the data to the format. /// </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="autoConvert">true to convert the data to the specified format; otherwise, false.</param> /// <returns> /// The data associated with the specified format, or null. /// </returns> public object GetData(string format, bool autoConvert) { //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 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); //read the cItem from the FILEGROUPDESCRIPTORA int fileDescriptorCount = Marshal.ReadInt32(fileGroupDescriptorAPointer); //create a new array to store file names in of the number of items in the file group descriptor string[] fileNames = new string[fileDescriptorCount]; //get the pointer to the first file descriptor IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)); //loop for the number of files acording to the file group descriptor for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileDescriptorCount; fileDescriptorIndex++) { //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name Win32.NativeMethods.FILEDESCRIPTORA fileDescriptor = (Win32.NativeMethods.FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(Win32.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); //read the cItem from the FILEGROUPDESCRIPTORW int fileDescriptorCount = Marshal.ReadInt32(fileGroupDescriptorWPointer); //create a new array to store file names in of the number of items in the file group descriptor string[] fileNames = new string[fileDescriptorCount]; //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 < fileDescriptorCount; fileDescriptorIndex++) { //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name Win32.NativeMethods.FILEDESCRIPTORW fileDescriptor = (Win32.NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(Win32.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)); }