diff --git a/PInvoke/Shared/Collections/IEnumFromCom.cs b/PInvoke/Shared/Collections/IEnumFromCom.cs
new file mode 100644
index 00000000..0e9d08a7
--- /dev/null
+++ b/PInvoke/Shared/Collections/IEnumFromCom.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Vanara.PInvoke;
+
+namespace Vanara.Collections
+{
+ /// A generic interface to identify matching COM enumerator interfaces
+ /// The type of the elem.
+ public interface ICOMEnum
+ {
+ /*
+ /// Retrieves the specified number of items in the enumeration sequence.
+ ///
+ /// The number of items to be retrieved. If there are fewer than the requested number of items left in the sequence, this method
+ /// retrieves the remaining elements.
+ ///
+ ///
+ /// An array of enumerated items.
+ ///
+ /// The enumerator is responsible for calling AddRef, and the caller is responsible for calling Release through each pointer
+ /// enumerated. If celt is greater than 1, the caller must also pass a non-NULL pointer passed to pceltFetched to know how many
+ /// pointers to release.
+ ///
+ ///
+ ///
+ /// The number of items that were retrieved. This parameter is always less than or equal to the number of items requested.
+ ///
+ /// If the method retrieves the number of items requested, the return value is S_OK. Otherwise, it is S_FALSE.
+ HRESULT Next(uint celt, TElem[] rgelt, out uint pceltFetched);
+
+ /// Skips over the specified number of items in the enumeration sequence.
+ /// The number of items to be skipped.
+ /// If the method skips the number of items requested, the return value is S_OK. Otherwise, it is S_FALSE.
+ HRESULT Skip(uint celt);
+
+ /// Resets the enumeration sequence to the beginning.
+ ///
+ /// There is no guarantee that the same set of objects will be enumerated after the reset operation has completed. A static
+ /// collection is reset to the beginning, but it can be too expensive for some collections, such as files in a directory, to
+ /// guarantee this condition.
+ ///
+ void Reset();
+ */
+ }
+
+ ///
+ /// 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 is null || reset is 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);
+
+ /// Initializes a new instance of the class from a COM enumeration interface instance.
+ /// The COM enumeration interface instance.
+ public static IEnumFromCom Create(TIntf enumObj) where TIntf : class, ICOMEnum
+ {
+ if (enumObj is null)
+ throw new ArgumentNullException(nameof(enumObj));
+ var cew = new ComEnumWrapper(enumObj);
+ return new IEnumFromCom(cew.ComObjTryGetNext, cew.ComObjReset);
+ }
+
+ private bool TryGet(out TItem item)
+ {
+ var res = new TItem[1];
+ item = default;
+ if (cnext(1, res, out var ret) != HRESULT.S_OK)
+ return false;
+ item = res[0];
+ return true;
+ }
+
+ private class ComEnumWrapper where T : class, ICOMEnum
+ {
+ private readonly T obj;
+
+ public ComEnumWrapper(T o) => obj = o;
+
+ public void ComObjReset() => ComInvoke("Reset");
+
+ public HRESULT ComObjTryGetNext(uint celt, TItem[] rgelt, out uint celtFetched)
+ {
+ var para = new object[] { celt, rgelt, 0U };
+ var hr = (HRESULT)ComInvoke("Next", para);
+ celtFetched = (uint)para[2];
+ return hr;
+ }
+
+ private object ComInvoke(string meth, object[] p = null) => typeof(T).GetMethod(meth).Invoke(obj, p);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PInvoke/Shared/Collections/IEnumGenerics.cs b/PInvoke/Shared/Collections/IEnumGenerics.cs
index 92627a87..41f41d30 100644
--- a/PInvoke/Shared/Collections/IEnumGenerics.cs
+++ b/PInvoke/Shared/Collections/IEnumGenerics.cs
@@ -2,8 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Reflection;
-using Vanara.PInvoke;
namespace Vanara.Collections
{
@@ -25,46 +23,6 @@ namespace Vanara.Collections
/// true if an item is returned, otherwise false.
public delegate bool TryGetNext(TIEnum enumObj, out TItem value);
- /// A generic interface to identify matching COM enumerator interfaces
- /// The type of the elem.
- public interface ICOMEnum
- {
- /*
- /// Retrieves the specified number of items in the enumeration sequence.
- ///
- /// The number of items to be retrieved. If there are fewer than the requested number of items left in the sequence, this method
- /// retrieves the remaining elements.
- ///
- ///
- /// An array of enumerated items.
- ///
- /// The enumerator is responsible for calling AddRef, and the caller is responsible for calling Release through each pointer
- /// enumerated. If celt is greater than 1, the caller must also pass a non-NULL pointer passed to pceltFetched to know how many
- /// pointers to release.
- ///
- ///
- ///
- /// The number of items that were retrieved. This parameter is always less than or equal to the number of items requested.
- ///
- /// If the method retrieves the number of items requested, the return value is S_OK. Otherwise, it is S_FALSE.
- HRESULT Next(uint celt, TElem[] rgelt, out uint pceltFetched);
-
- /// Skips over the specified number of items in the enumeration sequence.
- /// The number of items to be skipped.
- /// If the method skips the number of items requested, the return value is S_OK. Otherwise, it is S_FALSE.
- HRESULT Skip(uint celt);
-
- /// Resets the enumeration sequence to the beginning.
- ///
- /// There is no guarantee that the same set of objects will be enumerated after the reset operation has completed. A static
- /// collection is reset to the beginning, but it can be too expensive for some collections, such as files in a directory, to
- /// guarantee this condition.
- ///
- // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nf-objidl-ienumunknown-reset HRESULT Reset( );
- void Reset();
- */
- }
-
/// An implementation the interface that can iterate through next and reset methods.
public class IEnumeratorFromNext : IEnumerator where TIEnum : class
{
@@ -127,74 +85,6 @@ namespace Vanara.Collections
}
}
- ///
- /// 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;
- private readonly object comObj;
-
- /// 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 is null || reset is null)
- throw new ArgumentNullException();
- cnext = next;
- base.next = TryGet;
- base.reset = reset;
- }
-
- /// Initializes a new instance of the class from a COM enumeration interface instance.
- /// The COM enumeration interface instance.
- public IEnumFromCom(ICOMEnum enumObj) : base()
- {
- if (enumObj is null)
- throw new ArgumentNullException(nameof(enumObj));
- comObj = enumObj;
- cnext = ComObjTryGetNext;
- next = TryGet;
- reset = ComObjReset;
- }
-
- ///
- /// 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 HRESULT ComObjTryGetNext(uint celt, TItem[] rgelt, out uint celtFetched)
- {
- var para = new object[] { celt, rgelt, 0U };
- var hr = (HRESULT)comObj.GetType().InvokeMember("Next", BindingFlags.InvokeMethod, null, comObj, para);
- celtFetched = (uint)para[2];
- return hr;
- }
-
- private void ComObjReset() => comObj.GetType().InvokeMember("Reset", BindingFlags.InvokeMethod, null, comObj, null);
-
- private bool TryGet(out TItem item)
- {
- var res = new TItem[1];
- item = default;
- if (cnext(1, res, out var ret) != HRESULT.S_OK)
- 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.