mirror of https://github.com/dahall/Vanara.git
Removed IComEnumerator references - doesn't work due to Reflection/COM object limitations
parent
e3d402bbfc
commit
fd35f79e22
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue