Removed IComEnumerator references - doesn't work due to Reflection/COM object limitations

pull/133/head
dahall 2020-06-06 13:44:00 -06:00
parent e3d402bbfc
commit fd35f79e22
6 changed files with 9 additions and 98 deletions

View File

@ -199,7 +199,7 @@ namespace Vanara.PInvoke
/// <summary>Enumerates component categories registered in the system.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/comcat/nn-comcat-ienumcategoryinfo
[ComImport, Guid("0002E011-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumCATEGORYINFO : IComEnumerator<CATEGORYINFO>
public interface IEnumCATEGORYINFO
{
/// <summary>Retrieves the specified number of items in the enumeration sequence.</summary>
/// <param name="celt">
@ -256,7 +256,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/api/comcat/nn-comcat-ienumguid
[PInvokeData("comcat.h", MSDNShortId = "NN:comcat.IEnumGUID")]
[ComImport, Guid("0002E000-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumGUID : IComEnumerator<Guid>
public interface IEnumGUID
{
/// <summary>Retrieves the specified number of items in the enumeration sequence.</summary>
/// <param name="celt">

View File

@ -1085,7 +1085,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-ienumcontextprops
[PInvokeData("objidl.h", MSDNShortId = "64591e45-5478-4360-8c1f-08b09b5aef8e")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000001c1-0000-0000-C000-000000000046")]
public interface IEnumContextProps : IComEnumerator<ContextProperty>
public interface IEnumContextProps
{
/// <summary>Retrieves the specified number of items in the enumeration sequence.</summary>
/// <param name="celt">
@ -1156,7 +1156,7 @@ namespace Vanara.PInvoke
/// </summary>
[ComImport, Guid("0000000D-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[PInvokeData("Objidl.h", MSDNShortId = "aa379217")]
public interface IEnumSTATSTG : IComEnumerator<STATSTG>
public interface IEnumSTATSTG
{
/// <summary>
/// The Next method retrieves a specified number of STATSTG structures, that follow in the enumeration sequence. If there are

View File

@ -894,7 +894,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-ienumoleverb
[PInvokeData("oleidl.h", MSDNShortId = "fc9b3474-6f56-4274-af7d-72e0920c0457")]
[ComImport, Guid("00000104-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumOLEVERB : IComEnumerator<OLEVERB>
public interface IEnumOLEVERB
{
/// <summary>Retrieves the specified number of items in the enumeration sequence.</summary>
/// <param name="celt">

View File

@ -115,7 +115,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nn-propidl-ienumstatpropsetstg
[PInvokeData("propidl.h", MSDNShortId = "0000013B-0000-0000-C000-000000000046")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0e6d4d92-6738-11cf-9608-00aa00680db4")]
public interface IEnumSTATPROPSETSTG : IComEnumerator<STATPROPSETSTG>
public interface IEnumSTATPROPSETSTG
{
/// <summary>
/// The <c>Next</c> method retrieves a specified number of STATPROPSETSTG structures that follow subsequently in the enumeration
@ -201,7 +201,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/propidlbase/nn-propidlbase-ienumstatpropstg
[PInvokeData("propidlbase.h", MSDNShortId = "e625e52a-5628-4d18-9282-aa1c141c83af")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000139-0000-0000-C000-000000000046")]
public interface IEnumSTATPROPSTG : IComEnumerator<STATPROPSTG>
public interface IEnumSTATPROPSTG
{
/// <summary>
/// The <c>Next</c> method retrieves a specified number of STATPROPSTG structures, that follow subsequently in the enumeration

View File

@ -1225,7 +1225,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nn-wia_xp-ienumwia_dev_caps
[PInvokeData("wia_xp.h")]
[ComImport, Guid("1fcc4287-aca6-11d2-a093-00c04f72dc3c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumWIA_DEV_CAPS : IComEnumerator<WIA_DEV_CAP>
public interface IEnumWIA_DEV_CAPS
{
/// <summary>The <c>IEnumWIA_DEV_CAPS::Next</c> method fills an array of pointers to WIA_DEV_CAP structures.</summary>
/// <param name="celt">Specifies the number of array elements in the array indicated by the rgelt parameter.</param>
@ -1380,7 +1380,7 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nn-wia_xp-ienumwia_format_info
[PInvokeData("wia_xp.h")]
[ComImport, Guid("81BEFC5B-656D-44f1-B24C-D41D51B4DC81"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumWIA_FORMAT_INFO : IComEnumerator<WIA_FORMAT_INFO>
public interface IEnumWIA_FORMAT_INFO
{
/// <summary>The <c>IEnumWIA_FORMAT_INFO::Next</c> method returns an array of WIA_FORMAT_INFO structures.</summary>
/// <param name="celt">Specifies the number of elements requested.</param>

View File

@ -1,89 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>An interface matching most COM enumerator interfaces. This should be specified as a base for any IEnumXX interfaces.</summary>
/// <typeparam name="T">The type of the value enumeratored by the <c>Next</c> function.</typeparam>
public interface IComEnumerator<T>
{
}
/// <summary>Extension methods to get generic enumerations from COM interfaces.</summary>
public static class ComEnumeratorExtentions
{
/// <summary>Gets an <see cref="IEnumerator{T}"/> instance from an interface or class deriving from <see cref="IComEnumerator{T}"/>.</summary>
/// <typeparam name="T">The type of the enumerated value.</typeparam>
/// <param name="cenum">The instance of an interface or class deriving from <see cref="IComEnumerator{T}"/>.</param>
/// <returns>An <see cref="IEnumerator{T}"/> instance that will iterate over <paramref name="cenum"/>.</returns>
public static IEnumerator<T> GetEnumerator<T>(this IComEnumerator<T> cenum) where T : struct => new ComEnumeratorStruct<T>(cenum);
}
internal class ComEnumeratorStruct<T> : IEnumerator<T> where T : struct
{
private T? cur;
private IComEnumerator<T> instance;
private IComEnumerator_Next next;
private MethodInfo resetMethod;
public ComEnumeratorStruct(IComEnumerator<T> cenum)
{
instance = cenum;
//var mi = cenum.GetType().GetMethod("Next");
//if (!IsMethodCompatibleWithDelegate<IComEnumerator_Next>(mi))
// throw new ArgumentException("The instance does not support the correct 'Next' method format.");
next = (IComEnumerator_Next)Delegate.CreateDelegate(typeof(IComEnumerator_Next), instance, "Next", false, false) ?? throw new ArgumentException("The instance does not support the correct 'Next' method format.");
resetMethod = cenum.GetType().GetMethod("Reset", Type.EmptyTypes) ?? throw new ArgumentException("The instance does not support the correct 'Reset' method format.");
resetMethod.Invoke(instance, null);
}
/// <summary>Retrieves the specified number of items in the enumeration sequence.</summary>
/// <param name="celt">
/// 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.
/// </param>
/// <param name="rgelt">An array of enumerated items.</param>
/// <param name="pceltFetched">
/// The number of items that were retrieved. This parameter is always less than or equal to the number of items requested.
/// </param>
/// <returns>If the method retrieves the number of items requested, the return value is S_OK. Otherwise, it is S_FALSE.</returns>
public delegate HRESULT IComEnumerator_Next(uint celt, T[] rgelt, out uint pceltFetched);
public T Current => cur.HasValue ? cur.Value : throw new InvalidOperationException("The index is invalid.");
object IEnumerator.Current => Current;
public static bool IsMethodCompatibleWithDelegate<TDel>(MethodInfo method) where TDel : Delegate
{
var delegateSignature = typeof(TDel).GetMethod("Invoke");
return delegateSignature.ReturnType == method.ReturnType && delegateSignature.GetParameters().Select(x => x.ParameterType).SequenceEqual(method.GetParameters().Select(x => x.ParameterType));
}
public void Dispose()
{
if (!(instance is null))
{
if (instance.GetType().IsCOMObject)
Marshal.ReleaseComObject(instance);
instance = null;
}
}
public bool MoveNext()
{
if (instance is null) return false;
var i = new T[] { default };
var hr = next.Invoke(1, i, out var cnt);
cur = hr == HRESULT.S_OK && cnt == 1 ? i[0] : (T?)null;
return cur.HasValue;
}
public void Reset() => resetMethod.Invoke(instance, null);
}
}