/// <summary> /// Returns the hash code of the object. /// </summary> /// <returns></returns> public override int GetHashCode() { if (!hashValue.HasValue) { uint size = ShellNativeMethods.ILGetSize(PIDL); if (size != 0) { byte[] pidlData = new byte[size]; Marshal.Copy(PIDL, pidlData, 0, (int)size); byte[] hashData = ShellObject.hashProvider.ComputeHash(pidlData); hashValue = BitConverter.ToInt32(hashData, 0); } else { hashValue = 0; } } return(hashValue.Value); }
/// <summary> /// Builds the data for the CFSTR_SHELLIDLIST Drag and Clipboard data format from the /// ShellObjects in the collection. /// </summary> /// <returns>A memory stream containing the drag/drop data.</returns> public MemoryStream BuildShellIDList() { if (content.Count == 0) { throw new InvalidOperationException(LocalizedMessages.ShellObjectCollectionEmptyCollection); } MemoryStream mstream = new MemoryStream(); try { BinaryWriter bwriter = new BinaryWriter(mstream); // number of IDLs to be written (shell objects + parent folder) uint itemCount = (uint)(content.Count + 1); // grab the object IDLs IntPtr[] idls = new IntPtr[itemCount]; for (int index = 0; index < itemCount; index++) { if (index == 0) { // Because the ShellObjects passed in may be from anywhere, the // parent folder reference must be the desktop. idls[index] = ((ShellObject)KnownFolders.Desktop).PIDL; } else { idls[index] = content[index - 1].PIDL; } } // calculate offset array (folder IDL + item IDLs) uint[] offsets = new uint[itemCount + 1]; for (int index = 0; index < itemCount; index++) { if (index == 0) { // first offset equals size of CIDA header data offsets[0] = (uint)(sizeof(uint) * (offsets.Length + 1)); } else { offsets[index] = offsets[index - 1] + ShellNativeMethods.ILGetSize(idls[index - 1]); } } // Fill out the CIDA header // // typedef struct _IDA { // UINT cidl; // number of relative IDList // UINT aoffset[1]; // [0]: folder IDList, [1]-[cidl]: item IDList // } CIDA, * LPIDA; // bwriter.Write(content.Count); foreach (uint offset in offsets) { bwriter.Write(offset); } // copy idls foreach (IntPtr idl in idls) { byte[] data = new byte[ShellNativeMethods.ILGetSize(idl)]; Marshal.Copy(idl, data, 0, data.Length); bwriter.Write(data, 0, data.Length); } } catch { mstream.Dispose(); throw; } // return CIDA stream return(mstream); }