Vanara/PInvoke/Ole/Ole32/MessageDispatcher.cs

447 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
}
}
}