Vanara/PInvoke/Ole/Ole32/MessageDispatcher.cs

447 lines
22 KiB
C#
Raw Normal View History

using System;
using System.Runtime.InteropServices;
using System.Security;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Ole32
{
/// <summary>Represents the trust level of an activatable class.</summary>
/// <remarks>
/// <para>Classes can be activated depending on the trust level of the caller and the trust classification of the activatable class.</para>
/// <para>RegisteredTrustLevel is an alias for this enumeration.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/ne-inspectable-trustlevel typedef enum TrustLevel { BaseTrust,
// PartialTrust, FullTrust } ;
[PInvokeData("inspectable.h", MSDNShortId = "75E30E4B-EE5F-41C4-AC22-91D542E920EB")]
public enum TrustLevel
{
/// <summary>The component has access to resources that are not protected.</summary>
BaseTrust,
/// <summary>The component has access to resources requested in the app manifest and approved by the user.</summary>
PartialTrust,
/// <summary>The component requires the full privileges of the user.</summary>
FullTrust,
}
/// <summary>Provides functionality required for all Windows Runtime classes.</summary>
/// <remarks><c>IInspectable</c> methods have no effect on COM apartments and are safe to call from user interface threads.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nn-inspectable-iinspectable
[PInvokeData("inspectable.h", MSDNShortId = "0657E51F-D4C0-46C6-927D-B01E54B6846C")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
public interface IInspectable
{
/// <summary>Gets the interfaces that are implemented by the current Windows Runtime class.</summary>
/// <param name="iidCount">
/// <para>Type: <c>ULONG*</c></para>
/// <para>
/// The number of interfaces that are implemented by the current Windows Runtime object, excluding the IUnknown and IInspectable implementations.
/// </para>
/// </param>
/// <param name="iids">
/// <para>Type: <c>IID**</c></para>
/// <para>
/// A pointer to an array that contains an IID for each interface implemented by the current Windows Runtime object. The IUnknown
/// and IInspectable interfaces are excluded.
/// </para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The HSTRING was created successfully.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>Failed to allocate iids.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Use the <c>GetIids</c> method to discover the interfaces that are implemented by a Windows Runtime object.</para>
/// <para>A QueryInterface call on any IID in the iids array must succeed.</para>
/// <para>The caller is responsible for freeing the IID array by using the CoTaskMemFree function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-getiids HRESULT GetIids( ULONG
// *iidCount, IID **iids );
[PreserveSig]
HRESULT GetIids(out uint iidCount, out SafeCoTaskMemHandle iids);
/// <summary>Gets the fully qualified name of the current Windows Runtime object.</summary>
/// <param name="className">
/// <para>Type: <c>HSTRING*</c></para>
/// <para>The fully qualified name of the current Windows Runtime object.</para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The className string was created successfully.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>Failed to allocate className string.</term>
/// </item>
/// <item>
/// <term>E_ILLEGAL_METHOD_CALL</term>
/// <term>className refers to a class factory or a static interface.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Use the <c>GetRuntimeClassName</c> method to retrieve the namespace-qualified name of a Windows Runtime object.</para>
/// <para>The caller is responsible for freeing the className string by using the WindowsDeleteString function.</para>
/// <para>The following table shows example class name strings that cold be returned by the <c>GetRuntimeClassName</c> method.</para>
/// <list type="table">
/// <listheader>
/// <term>Example Class Name</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>Fabrikam.Kitchen.IToaster</term>
/// <term>An interface in the Fabrikam.Kitchen namespace.</term>
/// </item>
/// <item>
/// <term>Fabrikam.Kitchen.Chef</term>
/// <term>An class in the Fabrikam.Kitchen namespace.</term>
/// </item>
/// <item>
/// <term>Windows.Foundation.Collections.IVector`1&lt;TailspinToys.IStore&gt;</term>
/// <term>A vector of TailspinToys.IStore interfaces.</term>
/// </item>
/// <item>
/// <term>Windows.Foundation.Collections.IVector`1&lt;Windows.Foundation.Collections.IMap’2&lt;String, TailspinToys.IStore&gt;&gt;</term>
/// <term>A vector of maps of strings to TailspinToys.IStore interfaces.</term>
/// </item>
/// </list>
/// <para>
/// The <c>GetRuntimeClassName</c> method provides the most specific type information that the server object guarantees that it
/// implements. The type name may be a runtime class name, interface group name, interface name, or parameterized interface name.
/// </para>
/// <para>
/// The <c>GetRuntimeClassName</c> method returns <c>E_ILLEGAL_METHOD_CALL</c> if the class name refers to a class factory or a
/// static interface.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-getruntimeclassname HRESULT
// GetRuntimeClassName( HSTRING *className );
[PreserveSig]
HRESULT GetRuntimeClassName([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string className);
/// <summary>Gets the trust level of the current Windows Runtime object.</summary>
/// <param name="trustLevel">
/// <para>Type: <c>TrustLevel*</c></para>
/// <para>The trust level of the current Windows Runtime object. The default is <c>BaseLevel</c>.</para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This method always returns <c>S_OK</c>.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-gettrustlevel HRESULT
// GetTrustLevel( TrustLevel *trustLevel );
[PreserveSig]
HRESULT GetTrustLevel(out TrustLevel trustLevel);
}
/// <summary>
/// Callback interface implemented by components that need to perform special processing of window messages on an ASTA thread.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/imessagedispatcher/nn-imessagedispatcher-imessagedispatcher
[PInvokeData("imessagedispatcher.h", MSDNShortId = "60FD9084-CC79-48FE-AB26-C8FCB4288851")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("F5F84C8F-CFD0-4CD6-B66B-C5D26FF1689D")]
public interface IMessageDispatcher : IInspectable
{
/// <summary>Gets the interfaces that are implemented by the current Windows Runtime class.</summary>
/// <param name="iidCount">
/// <para>Type: <c>ULONG*</c></para>
/// <para>
/// The number of interfaces that are implemented by the current Windows Runtime object, excluding the IUnknown and IInspectable implementations.
/// </para>
/// </param>
/// <param name="iids">
/// <para>Type: <c>IID**</c></para>
/// <para>
/// A pointer to an array that contains an IID for each interface implemented by the current Windows Runtime object. The IUnknown
/// and IInspectable interfaces are excluded.
/// </para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The HSTRING was created successfully.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>Failed to allocate iids.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Use the <c>GetIids</c> method to discover the interfaces that are implemented by a Windows Runtime object.</para>
/// <para>A QueryInterface call on any IID in the iids array must succeed.</para>
/// <para>The caller is responsible for freeing the IID array by using the CoTaskMemFree function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-getiids HRESULT GetIids( ULONG
// *iidCount, IID **iids );
[PreserveSig]
new HRESULT GetIids(out uint iidCount, out SafeCoTaskMemHandle iids);
/// <summary>Gets the fully qualified name of the current Windows Runtime object.</summary>
/// <param name="className">
/// <para>Type: <c>HSTRING*</c></para>
/// <para>The fully qualified name of the current Windows Runtime object.</para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The className string was created successfully.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>Failed to allocate className string.</term>
/// </item>
/// <item>
/// <term>E_ILLEGAL_METHOD_CALL</term>
/// <term>className refers to a class factory or a static interface.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Use the <c>GetRuntimeClassName</c> method to retrieve the namespace-qualified name of a Windows Runtime object.</para>
/// <para>The caller is responsible for freeing the className string by using the WindowsDeleteString function.</para>
/// <para>The following table shows example class name strings that cold be returned by the <c>GetRuntimeClassName</c> method.</para>
/// <list type="table">
/// <listheader>
/// <term>Example Class Name</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>Fabrikam.Kitchen.IToaster</term>
/// <term>An interface in the Fabrikam.Kitchen namespace.</term>
/// </item>
/// <item>
/// <term>Fabrikam.Kitchen.Chef</term>
/// <term>An class in the Fabrikam.Kitchen namespace.</term>
/// </item>
/// <item>
/// <term>Windows.Foundation.Collections.IVector`1&lt;TailspinToys.IStore&gt;</term>
/// <term>A vector of TailspinToys.IStore interfaces.</term>
/// </item>
/// <item>
/// <term>Windows.Foundation.Collections.IVector`1&lt;Windows.Foundation.Collections.IMap’2&lt;String, TailspinToys.IStore&gt;&gt;</term>
/// <term>A vector of maps of strings to TailspinToys.IStore interfaces.</term>
/// </item>
/// </list>
/// <para>
/// The <c>GetRuntimeClassName</c> method provides the most specific type information that the server object guarantees that it
/// implements. The type name may be a runtime class name, interface group name, interface name, or parameterized interface name.
/// </para>
/// <para>
/// The <c>GetRuntimeClassName</c> method returns <c>E_ILLEGAL_METHOD_CALL</c> if the class name refers to a class factory or a
/// static interface.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-getruntimeclassname HRESULT
// GetRuntimeClassName( HSTRING *className );
[PreserveSig]
new HRESULT GetRuntimeClassName([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string className);
/// <summary>Gets the trust level of the current Windows Runtime object.</summary>
/// <param name="trustLevel">
/// <para>Type: <c>TrustLevel*</c></para>
/// <para>The trust level of the current Windows Runtime object. The default is <c>BaseLevel</c>.</para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>This method always returns <c>S_OK</c>.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nf-inspectable-iinspectable-gettrustlevel HRESULT
// GetTrustLevel( TrustLevel *trustLevel );
[PreserveSig]
new HRESULT GetTrustLevel(out TrustLevel trustLevel);
/// <summary>Performs custom dispatching when window messages are available to be dispatched on an ASTA thread.</summary>
/// <returns>If this method succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/imessagedispatcher/nf-imessagedispatcher-imessagedispatcher-pumpmessages
// HRESULT PumpMessages( );
[PreserveSig]
HRESULT PumpMessages();
}
/// <summary>
/// Called by message dispatchers on an ASTA thread after dispatching a windows message to provide an opportunity for short-running
/// infrastructural COM calls and other high-priority or short-running COM work to be dispatched between messages. This helps to
/// provide similar responsiveness to these infrastructural calls in an ASTA as in a classic STA, even when there is a long stream of
/// window messages to be handled.
/// </summary>
/// <returns>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
/// <remarks>
/// <para>
/// This function dispatches any high-priority COM calls or work that are queued on the ASTA thread, then returns. It returns quickly
/// if there is no work to perform.
/// </para>
/// <para>This function silently does nothing when called on non-ASTA threads.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/messagedispatcherapi/nf-messagedispatcherapi-cohandlepriorityeventsfrommessagepump
// void CoHandlePriorityEventsFromMessagePump( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("messagedispatcherapi.h", MSDNShortId = "24EA766D-82F8-4E57-AAB8-A06ECE644319")]
public static extern void CoHandlePriorityEventsFromMessagePump();
/// <summary>
/// Registers or unregisters the per-thread message dispatcher that is to be invoked when there are window messages available to
/// dispatch within COM wait APIs on an ASTA thread. This function is usually called by CoreWindow, but in certain circumstances
/// other components that need to specialize how messages are dispatched on an ASTA thread can also call this function.
/// </summary>
/// <param name="pMessageDispatcher">
/// If non-null, message dispatcher object to register. This object must also implement IWeakReferenceSource. If null, unregisters
/// the current message dispatcher.
/// </param>
/// <remarks>
/// <para>
/// This function is supported only in ASTA threads. An attempt to set the message dispatcher on a non-ASTA thread silently fails
/// with no side effects.
/// </para>
/// <para>An attempt to set an object that does not implement IWeakReferenceSource silently fails with no side effects.</para>
/// <para>
/// A call to this function with a valid and non-null pMessageDispatcher parameter registers this object to receive a PumpMessages
/// callback whenever there are window messages available to dispatch with COM wait APIs on that ASTA thread. A Windows Runtime weak
/// reference to this object is held, and the object receives callbacks, until the registration is replaced or the ASTA
/// uninitialized. Each call to this function replaces the previously registered message dispatcher, if any.
/// </para>
/// <para>
/// There is no way to check if a message dispatcher is registered on an ASTA thread or to retrieve a previously registered message
/// dispatcher. This function should only be called under circumstances where it is known that this will not collide with another
/// registration, specifically:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// In Windows Store app UI threads, this function is called by CoreWindow to register its dispatcher. No other components should
/// call this function on these threads.
/// </term>
/// </item>
/// <item>
/// <term>
/// UI frameworks may support an authoring mode, in which applications are run in the desktop environment and therefore do not have a
/// CoreWindow in their UI threads. In lieu of CoreWindow support, these UI frameworks may register a message dispatcher on UI
/// threads to handle special window message processing usually handled by CoreWindow (such as accelerators). It is not required to
/// call this function if the UI framework has no need for this functionality.
/// </term>
/// </item>
/// <item>
/// <term>
/// IAppVisibility browsers are not restricted to the Windows Store app APIs and therefore may have their own custom window message
/// processing using user32 APIs. However, these applications still have ASTA UI threads as provided by app object, and may register
/// a message dispatcher to handle this special processing. It is not required to call this function if the browser has no need for
/// this functionality.
/// </term>
/// </item>
/// </list>
/// <para>
/// The case of IAppVisibility browsers requires care to avoid CoreWindow replacing the browsers message dispatcher. It is assumed
/// that the browser has no need for CoreWindows dispatcher. The browser should call <c>CoSetMessageDispatcher</c> no sooner than
/// its IViewProvider::Initialize, or, in the case of views that implement IInitializeWithWindowFactory, no sooner than after it has
/// created a window on the thread.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/messagedispatcherapi/nf-messagedispatcherapi-cosetmessagedispatcher void
// CoSetMessageDispatcher( PMessageDispatcher pMessageDispatcher );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("messagedispatcherapi.h", MSDNShortId = "3D6CFE01-8D3D-474E-A7D0-9B129ECD4EEA")]
public static extern void CoSetMessageDispatcher(IMessageDispatcher pMessageDispatcher);
/// <summary>Marshals HSTRING values.</summary>
/// <seealso cref="System.Runtime.InteropServices.ICustomMarshaler"/>
internal class HStringMarshaler : ICustomMarshaler
{
private HStringMarshaler(string cookie)
{
}
/// <summary>Gets the instance.</summary>
/// <param name="cookie">The cookie.</param>
/// <returns>A new instance of this class.</returns>
public static ICustomMarshaler GetInstance(string cookie) => new HStringMarshaler(cookie);
/// <summary>Performs necessary cleanup of the managed data when it is no longer needed.</summary>
/// <param name="ManagedObj">The managed object to be destroyed.</param>
public void CleanUpManagedData(object ManagedObj) { }
/// <summary>Performs necessary cleanup of the unmanaged data when it is no longer needed.</summary>
/// <param name="pNativeData">A pointer to the unmanaged data to be destroyed.</param>
[SecurityCritical]
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData != IntPtr.Zero)
WindowsDeleteString(pNativeData);
}
/// <summary>Returns the size of the native data to be marshaled.</summary>
/// <returns>The size in bytes of the native data.</returns>
public int GetNativeDataSize() => 0;
/// <summary>Converts the managed data to unmanaged data.</summary>
/// <param name="ManagedObj">The managed object to be converted.</param>
/// <returns>Returns the COM view of the managed object.</returns>
[SecurityCritical]
public IntPtr MarshalManagedToNative(object ManagedObj)
{
var s = ManagedObj?.ToString();
WindowsCreateString(s, s?.Length ?? 0, out var hstring).ThrowIfFailed();
return hstring;
}
/// <summary>Converts the unmanaged data to managed data.</summary>
/// <param name="pNativeData">A pointer to the unmanaged data to be wrapped.</param>
/// <returns>Returns the managed view of the COM data.</returns>
[SecurityCritical]
public object MarshalNativeToManaged(IntPtr pNativeData) => pNativeData == IntPtr.Zero ? null : (string)WindowsGetStringRawBuffer(pNativeData, out var len);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern HRESULT WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString, int length, out IntPtr hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern HRESULT WindowsDeleteString(IntPtr hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern StrPtrUni WindowsGetStringRawBuffer(IntPtr hstring, out uint length);
}
}
}