|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Drawing;
using Windows.Win32.System.Variant;
using Windows.Win32.UI.Accessibility;
namespace System.Windows.Forms;
public partial class ErrorProvider
{
internal partial class ControlItem
{
private class ControlItemAccessibleObject : AccessibleObject
{
private readonly ControlItem _controlItem;
private readonly ErrorWindow? _window;
private readonly Control _control;
private readonly ErrorProvider _provider;
public ControlItemAccessibleObject(
ControlItem controlItem,
ErrorWindow? window,
Control control,
ErrorProvider provider)
{
_controlItem = controlItem;
_window = window;
_control = control;
_provider = provider;
}
public override Rectangle Bounds
=> _control.ParentInternal is not null && _control.ParentInternal.IsHandleCreated
? _control.ParentInternal.RectangleToScreen(_controlItem.GetIconBounds(_provider.Region.Size))
: Rectangle.Empty;
private int ControlItemsCount => _window?.ControlItems.Count ?? 0;
private int CurrentIndex => _window?.ControlItems.IndexOf(_controlItem) ?? -1;
internal override IRawElementProviderFragment.Interface? FragmentNavigate(NavigateDirection direction)
=> direction switch
{
NavigateDirection.NavigateDirection_Parent => Parent,
NavigateDirection.NavigateDirection_NextSibling => GetNextSibling(),
NavigateDirection.NavigateDirection_PreviousSibling => GetPreviousSibling(),
_ => base.FragmentNavigate(direction),
};
internal override IRawElementProviderFragmentRoot.Interface? FragmentRoot => Parent;
internal override int GetChildId()
{
return CurrentIndex + 1;
}
private AccessibleObject? GetNextSibling()
{
int currentIndex = CurrentIndex;
// Is a last child
if (currentIndex >= ControlItemsCount - 1 || currentIndex < 0)
{
return null;
}
return _window?.ControlItems[currentIndex + 1].AccessibilityObject;
}
private AccessibleObject? GetPreviousSibling()
{
int currentIndex = CurrentIndex;
// Is a first child
if (currentIndex <= 0 || currentIndex > ControlItemsCount - 1)
{
return null;
}
return _window?.ControlItems[currentIndex - 1].AccessibilityObject;
}
internal override VARIANT GetPropertyValue(UIA_PROPERTY_ID propertyID) =>
propertyID switch
{
UIA_PROPERTY_ID.UIA_ControlTypePropertyId
=> (VARIANT)(int)UIA_CONTROLTYPE_ID.UIA_ImageControlTypeId,
UIA_PROPERTY_ID.UIA_NativeWindowHandlePropertyId
=> UIAHelper.WindowHandleToVariant(_window?.Handle ?? HWND.Null),
_ => base.GetPropertyValue(propertyID)
};
internal override bool IsIAccessibleExSupported() => true;
internal override bool IsPatternSupported(UIA_PATTERN_ID patternId)
{
if (patternId == UIA_PATTERN_ID.UIA_LegacyIAccessiblePatternId)
{
return true;
}
return base.IsPatternSupported(patternId);
}
internal override bool IsReadOnly => true;
[AllowNull]
public override string Name => string.IsNullOrEmpty(base.Name) ? _controlItem.Error : base.Name;
internal override bool CanGetNameInternal => false;
public override AccessibleObject? Parent => _window?.AccessibilityObject;
private protected override bool IsInternal => true;
public override AccessibleRole Role => AccessibleRole.Alert;
/// <summary>
/// Gets the runtime ID.
/// </summary>
internal override int[] RuntimeId
{
get
{
if (_window is null)
{
return [_controlItem.GetHashCode()];
}
int[] id = _window.AccessibilityObject.RuntimeId;
Debug.Assert(id.Length >= 3);
return [id[0], id[1], id[2], _controlItem.GetHashCode()];
}
}
public override AccessibleStates State => AccessibleStates.HasPopup | AccessibleStates.ReadOnly;
}
}
}
|