| File: NativeMethods.Automation.cs | Web Access |
| Project: src\src\Aspire.Tray\Windows\Aspire.Tray.Windows.csproj (aspire-tray) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; namespace Aspire.Tray; /// <summary> /// UI Automation provider interfaces and functions used by the flyout panel. The interfaces use /// source-generated COM, which works under NativeAOT without built-in COM interop. Method order /// must match the vtables in UIAutomationCore.idl; property getters are declared as the get_ /// methods they are in COM. Interface pointers that come from or go straight to native code /// (the HWND host provider, a pattern's IUnknown) stay as raw pointers. /// https://learn.microsoft.com/windows/win32/winauto/uiauto-providersoverview /// </summary> internal static unsafe partial class NativeMethods { internal const uint WmGetObject = 0x003D; internal const int UiaRootObjectId = -25; internal const int UiaAppendRuntimeId = 3; // https://learn.microsoft.com/windows/win32/winauto/uiauto-control-pattern-ids internal const int UiaInvokePatternId = 10000; internal const int UiaTogglePatternId = 10015; // https://learn.microsoft.com/windows/win32/winauto/uiauto-automation-element-propids internal const int UiaControlTypePropertyId = 30003; internal const int UiaNamePropertyId = 30005; internal const int UiaHasKeyboardFocusPropertyId = 30008; internal const int UiaIsKeyboardFocusablePropertyId = 30009; internal const int UiaIsEnabledPropertyId = 30010; internal const int UiaAutomationIdPropertyId = 30011; internal const int UiaHelpTextPropertyId = 30013; internal const int UiaIsOffscreenPropertyId = 30022; internal const int UiaFrameworkIdPropertyId = 30024; internal const int UiaToggleToggleStatePropertyId = 30086; // https://learn.microsoft.com/windows/win32/winauto/uiauto-controltype-ids internal const int UiaButtonControlTypeId = 50000; internal const int UiaCheckBoxControlTypeId = 50002; internal const int UiaTextControlTypeId = 50020; internal const int UiaPaneControlTypeId = 50033; // https://learn.microsoft.com/windows/win32/winauto/uiauto-event-ids internal const int UiaAutomationFocusChangedEventId = 20005; // UIA_E_ELEMENTNOTENABLED and UIA_E_ELEMENTNOTAVAILABLE from UIAutomationCoreApi.h. internal const int UiaElementNotEnabled = unchecked((int)0x80040200); internal const int UiaElementNotAvailable = unchecked((int)0x80040201); [LibraryImport("uiautomationcore.dll")] internal static partial nint UiaReturnRawElementProvider(nint window, nuint wParam, nint lParam, nint provider); [LibraryImport("uiautomationcore.dll")] internal static partial int UiaHostProviderFromHwnd(nint window, out nint provider); [LibraryImport("uiautomationcore.dll")] internal static partial int UiaRaiseAutomationEvent(nint provider, int eventId); [LibraryImport("uiautomationcore.dll")] internal static partial int UiaRaiseStructureChangedEvent(nint provider, StructureChangeType changeType, int* runtimeId, int runtimeIdLength); [LibraryImport("uiautomationcore.dll")] internal static partial int UiaRaiseAutomationPropertyChangedEvent(nint provider, int propertyId, NativeVariant oldValue, NativeVariant newValue); [LibraryImport("uiautomationcore.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool UiaClientsAreListening(); [LibraryImport("uiautomationcore.dll")] internal static partial int UiaDisconnectProvider(nint provider); [LibraryImport("oleaut32.dll")] internal static partial nint SafeArrayCreateVector(ushort variantType, int lowerBound, uint elementCount); [LibraryImport("oleaut32.dll")] internal static partial int SafeArrayAccessData(nint array, out nint data); [LibraryImport("oleaut32.dll")] internal static partial int SafeArrayUnaccessData(nint array); [LibraryImport("user32.dll", SetLastError = true)] internal static partial int ScreenToClient(nint window, ref Point point); [Flags] internal enum ProviderOptions { ServerSideProvider = 0x2 } internal enum NavigateDirection { Parent = 0, NextSibling = 1, PreviousSibling = 2, FirstChild = 3, LastChild = 4 } internal enum ToggleState { Off = 0, On = 1 } // StructureChangeType from uiautomationcore.h: ChildAdded 0, ChildRemoved 1, // ChildrenInvalidated 2, ChildrenBulkAdded 3, ChildrenBulkRemoved 4, ChildrenReordered 5. internal enum StructureChangeType { ChildrenInvalidated = 2 } /// <summary> /// The VARIANT layout, for passing a <see cref="ComVariant"/> by value: <see cref="ComVariant"/> /// itself is not accepted by source-generated marshalling while runtime marshalling is enabled. /// 16 bytes on 32-bit Windows, 24 bytes on 64-bit Windows. /// https://learn.microsoft.com/windows/win32/api/oaidl/ns-oaidl-variant /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct NativeVariant { public ushort Type; public ushort Reserved1; public ushort Reserved2; public ushort Reserved3; public nint Value; public nint Record; public static NativeVariant From(ComVariant value) => *(NativeVariant*)&value; } /// <summary>A screen rectangle in physical pixels: left, top, width, height.</summary> [StructLayout(LayoutKind.Sequential)] internal struct UiaRect { public double Left; public double Top; public double Width; public double Height; } } [GeneratedComInterface] [Guid("d6dd68d1-86fd-4332-8666-9abedea2d24c")] internal unsafe partial interface IRawElementProviderSimple { NativeMethods.ProviderOptions get_ProviderOptions(); /// <summary>Returns an AddRef'd IUnknown for the pattern, or null when it is not supported.</summary> nint GetPatternProvider(int patternId); /// <summary> /// Writes the property's VARIANT (VT_EMPTY when the provider has no value) and returns an HRESULT. /// The VARIANT is passed as a pointer because ComVariant is not blittable to the source generator. /// </summary> [PreserveSig] int GetPropertyValue(int propertyId, ComVariant* value); /// <summary>Returns the HWND host provider for a fragment root, or null for its descendants.</summary> nint get_HostRawElementProvider(); } [GeneratedComInterface] [Guid("f7063da8-8359-439c-9297-bbc5299a7d87")] internal partial interface IRawElementProviderFragment { IRawElementProviderFragment? Navigate(NativeMethods.NavigateDirection direction); /// <summary>Returns a SAFEARRAY of VT_I4, or null for the fragment root (the host supplies its id).</summary> nint GetRuntimeId(); NativeMethods.UiaRect get_BoundingRectangle(); nint GetEmbeddedFragmentRoots(); void SetFocus(); IRawElementProviderFragmentRoot get_FragmentRoot(); } [GeneratedComInterface] [Guid("620ce2a5-ab8f-40a9-86cb-de3c75599b58")] internal partial interface IRawElementProviderFragmentRoot { IRawElementProviderFragment? ElementProviderFromPoint(double x, double y); IRawElementProviderFragment? GetFocus(); } [GeneratedComInterface] [Guid("54fcb24b-e18e-47a2-b4d3-eccbe77599a2")] internal partial interface IInvokeProvider { void Invoke(); } [GeneratedComInterface] [Guid("56d00bd0-c4f4-433c-a836-1a52a57e0892")] internal partial interface IToggleProvider { void Toggle(); NativeMethods.ToggleState get_ToggleState(); }