using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using static Vanara.PInvoke.Shell32; namespace Vanara.Windows.Shell { /// A folder or container of instances. public class ShellItemArray : IReadOnlyList, IDisposable { private IShellItemArray array; /// Initializes a new instance of the class. /// The shell items. public ShellItemArray(IShellItemArray shellItems) { array = shellItems; } /// Initializes a new instance of the class. /// The shell items to add to this array. public ShellItemArray(IEnumerable shellItems) : this(shellItems.Select(i => (IntPtr)i.PIDL).ToArray()) { } /// Initializes a new instance of the class. /// The IDList items to add to this array. public ShellItemArray(IEnumerable pidls) : this(pidls.Select(p => (IntPtr)p).ToArray()) { } /// Initializes a new instance of the class. /// The IDList items to add to this array. private ShellItemArray(IntPtr[] pidls) { SHCreateShellItemArrayFromIDLists((uint)pidls.Length, pidls, out array).ThrowIfFailed(); } /// Initializes a new instance of the class. private ShellItemArray() { } /// Gets the number of elements contained in the . public int Count => (int)array.GetCount(); /// Gets the instance behind this class. /// The instance. public IEnumShellItems IEnumShellItems => array.EnumItems(); /// Gets the instance behind this class. /// The instance. public IShellItemArray IShellItemArray => array; /// Gets the at the specified index. /// The . /// The index. /// A instance. public ShellItem this[int index] => ShellItem.Open(array.GetItemAt((uint)index)); /// Determines whether the contains a specific value. /// The object to locate in the . /// true if is found in the ; otherwise, false. public bool Contains(ShellItem item) => item != null && GetItems().Any(item.Equals); /// /// Copies the elements of the to an , starting at a particular index. /// /// /// The one-dimensional that is the destination of the elements copied from . The /// must have zero-based indexing. /// /// The zero-based index in at which copying begins. public void CopyTo(ShellItem[] array, int arrayIndex) { var a = GetItems().Select(ShellItem.Open).ToArray(); Array.Copy(a, 0, array, arrayIndex, a.Length); } /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public virtual void Dispose() { if (array != null) { Marshal.ReleaseComObject(array); array = null; } } /// Returns an enumerator that iterates through the collection. /// A that can be used to iterate through the collection. public IEnumerator GetEnumerator() => GetItems().Select(ShellItem.Open).GetEnumerator(); /// Returns an enumerator that iterates through a collection. /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); /// Gets the items. protected IEnumerable GetItems() { for (uint i = 0; i < array.GetCount(); i++) yield return array.GetItemAt(i); } } }