diff --git a/PInvoke/Shared/Collections/IEnumGenerics.cs b/PInvoke/Shared/Collections/IEnumGenerics.cs index 2ba3470c..c36ee260 100644 --- a/PInvoke/Shared/Collections/IEnumGenerics.cs +++ b/PInvoke/Shared/Collections/IEnumGenerics.cs @@ -2,12 +2,57 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using Vanara.PInvoke; namespace Vanara.Collections { /// - /// Creates an enumerable class from a counter and an indexer. Useful if a class doesn't support or like some COM objects. + /// Creates an enumerable class from a get next method in the form of HRESULT Next(uint, TItem[], out uint) and a reset method. Useful if + /// a class doesn't support or like some COM objects. + /// + /// The type of the item. + public class IEnumFromCom : IEnumFromNext + { + private readonly ComTryGetNext cnext; + + /// Initializes a new instance of the class. + /// The method used to try to get the next item in the enumeration. + /// The method used to reset the enumeration to the first element. + public IEnumFromCom(ComTryGetNext next, Action reset) : base() + { + if (next == null || reset == null) throw new ArgumentNullException(); + cnext = next; + base.next = TryGet; + base.reset = reset; + } + + /// + /// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration. + /// + /// The number of items requested. + /// An array of items to be returned. + /// The number of items retrieved in the parameter. + /// + /// This method supports the following return values: S_OK = The number of items returned is equal to the number specified in the + /// parameter. S_FALSE = The number of items returned is less than the number specified in the + /// parameter. + /// + public delegate HRESULT ComTryGetNext(uint celt, TItem[] rgelt, out uint celtFetched); + + private bool TryGet(out TItem item) + { + var res = new TItem[1]; + item = default; + if (cnext(1, res, out var ret).Failed) + return false; + item = res[0]; + return true; + } + } + + /// + /// Creates an enumerable class from a counter and an indexer. Useful if a class doesn't support or + /// like some COM objects. /// /// The type of the item. public class IEnumFromIndexer : IReadOnlyList @@ -80,8 +125,11 @@ namespace Vanara.Collections /// The type of the item. public class IEnumFromNext : IEnumerable { - private readonly TryGetNext next; - private readonly Action reset; + /// The next function delegate. + protected TryGetNext next; + + /// The reset function delegate. + protected Action reset; /// Initializes a new instance of the class. /// The method used to try to get the next item in the enumeration. @@ -93,6 +141,9 @@ namespace Vanara.Collections this.reset = reset; } + /// Initializes a new instance of the class. + protected IEnumFromNext() { } + /// /// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration. ///