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);
}
}
}