Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
Total Issues: 0
Compat issues with assembly UIAutomationTypes:
CannotRemoveAttribute : Attribute 'System.Runtime.InteropServices.InterfaceTypeAttribute' exists on 'System.Windows.Automation.Provider.IRawElementProviderSimple' in the contract but not the implementation.
CannotRemoveAttribute : Attribute 'System.Runtime.InteropServices.InterfaceTypeAttribute' exists on 'System.Windows.Automation.Provider.ITextRangeProvider' in the contract but not the implementation.
Total Issues: 2
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ private static bool IsKnownLegacyEvent(int id)
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool IsKnownNewEvent(int id)
{
if (id == AutomationElementIdentifiers.LiveRegionChangedEvent?.Id)
if ( id == AutomationElementIdentifiers.LiveRegionChangedEvent?.Id
|| id == AutomationElementIdentifiers.NotificationEvent?.Id
|| id == AutomationElementIdentifiers.ActiveTextPositionChangedEvent?.Id)
{
return true;
}
Expand Down Expand Up @@ -117,6 +119,8 @@ private static AutomationEvent GetRegisteredEventObjectHelper(AutomationEvents e
case AutomationEvents.InputReachedOtherElement: eventObject = SynchronizedInputPatternIdentifiers.InputReachedOtherElementEvent; break;
case AutomationEvents.InputDiscarded: eventObject = SynchronizedInputPatternIdentifiers.InputDiscardedEvent; break;
case AutomationEvents.LiveRegionChanged: eventObject = AutomationElementIdentifiers.LiveRegionChangedEvent; break;
case AutomationEvents.Notification: eventObject = AutomationElementIdentifiers.NotificationEvent; break;
case AutomationEvents.ActiveTextPositionChanged: eventObject = AutomationElementIdentifiers.ActiveTextPositionChangedEvent; break;

default:
throw new ArgumentException(SR.Get(SRID.Automation_InvalidEventId), "eventId");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ public enum AutomationEvents
InputDiscarded,
///
LiveRegionChanged,
///
Notification,
///
ActiveTextPositionChanged,
}


Expand Down Expand Up @@ -371,6 +375,29 @@ public void RaiseAsyncContentLoadedEvent(AsyncContentLoadedEventArgs args)
}
}

/// <summary>
/// This method is called by implementation of the peer to raise the automation "notification" event
/// </summary>
// Never inline, as we don't want to unnecessarily link the automation DLL.
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void RaiseNotificationEvent(AutomationNotificationKind notificationKind,
AutomationNotificationProcessing notificationProcessing,
string displayString,
string activityId)
{
if (EventMap.HasRegisteredEvent(AutomationEvents.Notification))
{
IRawElementProviderSimple provider = ProviderFromPeer(this);
if (provider != null)
{
AutomationInteropProvider.RaiseAutomationEvent(
AutomationElementIdentifiers.NotificationEvent,
provider,
new NotificationEventArgs(notificationKind, notificationProcessing, displayString, activityId));
}
}
}

internal static void RaiseFocusChangedEventHelper(IInputElement newFocus)
{
// Callers have only checked if automation clients are present so filter for any interest in this particular event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2268,6 +2268,8 @@ public enum AutomationEvents
InputReachedOtherElement = 16,
InputDiscarded = 17,
LiveRegionChanged = 18,
Notification = 19,
ActiveTextPositionChanged = 20,
}
public enum AutomationOrientation
{
Expand Down Expand Up @@ -2350,6 +2352,7 @@ public void InvalidatePeer() { }
protected internal System.Windows.Automation.Provider.IRawElementProviderSimple ProviderFromPeer(System.Windows.Automation.Peers.AutomationPeer peer) { throw null; }
public void RaiseAsyncContentLoadedEvent(System.Windows.Automation.AsyncContentLoadedEventArgs args) { }
public void RaiseAutomationEvent(System.Windows.Automation.Peers.AutomationEvents eventId) { }
public void RaiseNotificationEvent(System.Windows.Automation.AutomationNotificationKind notificationKind, System.Windows.Automation.AutomationNotificationProcessing notificationProcessing, string displayString, string activityId) { }
public void RaisePropertyChangedEvent(System.Windows.Automation.AutomationProperty property, object oldValue, object newValue) { }
public void ResetChildrenCache() { }
public void SetFocus() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic; // List<T>
using System.Windows.Automation.Provider; // IRawElementProviderSimple
using System.Windows.Documents; // ITextPointer
using MS.Internal.Automation; // EventMap

namespace System.Windows.Automation.Peers
{
Expand All @@ -25,6 +26,36 @@ protected ContentTextAutomationPeer(FrameworkContentElement owner)
: base(owner)
{ }

/// <summary>
/// This method is called by implementation of the peer to raise the automation "ActiveTextPositionChanged" event
/// </summary>
// Never inline, as we don't want to unnecessarily link the automation DLL.
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public virtual void RaiseActiveTextPositionChangedEvent(TextPointer rangeStart, TextPointer rangeEnd)
{
if (EventMap.HasRegisteredEvent(AutomationEvents.ActiveTextPositionChanged))
{
IRawElementProviderSimple provider = ProviderFromPeer(this);
if (provider != null)
{
ActiveTextPositionChangedEventArgs args = new ActiveTextPositionChangedEventArgs(TextRangeFromTextPointers(rangeStart, rangeEnd));
AutomationInteropProvider.RaiseAutomationEvent(
AutomationElementIdentifiers.ActiveTextPositionChangedEvent,
provider,
args);
}
}
}

/// <summary>
/// Convert TextPointers to ITextRangeProvider
/// </summary>
private ITextRangeProvider TextRangeFromTextPointers(TextPointer rangeStart, TextPointer rangeEnd)
{
TextAdaptor textAdaptor = GetPattern(PatternInterface.Text) as TextAdaptor;
return textAdaptor?.TextRangeFromTextPointers(rangeStart, rangeEnd);
}

/// <summary>
/// Maps AutomationPeer to provider object.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Collections.Generic; // List<T>
using System.Windows.Automation.Provider; // IRawElementProviderSimple
using System.Windows.Documents; // ITextPointer
using MS.Internal.Automation; // EventMap, TextAdaptor

namespace System.Windows.Automation.Peers
{
Expand All @@ -24,6 +25,36 @@ protected TextAutomationPeer(FrameworkElement owner)
: base(owner)
{}

/// <summary>
/// This method is called by implementation of the peer to raise the automation "ActiveTextPositionChanged" event
/// </summary>
// Never inline, as we don't want to unnecessarily link the automation DLL.
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public virtual void RaiseActiveTextPositionChangedEvent(TextPointer rangeStart, TextPointer rangeEnd)
{
if (EventMap.HasRegisteredEvent(AutomationEvents.ActiveTextPositionChanged))
{
IRawElementProviderSimple provider = ProviderFromPeer(this);
if (provider != null)
{
ActiveTextPositionChangedEventArgs args = new ActiveTextPositionChangedEventArgs(TextRangeFromTextPointers(rangeStart, rangeEnd));
AutomationInteropProvider.RaiseAutomationEvent(
AutomationElementIdentifiers.ActiveTextPositionChangedEvent,
provider,
args);
}
}
}

/// <summary>
/// Convert TextPointers to ITextRangeProvider
/// </summary>
private ITextRangeProvider TextRangeFromTextPointers(TextPointer rangeStart, TextPointer rangeEnd)
{
TextAdaptor textAdaptor = GetPattern(PatternInterface.Text) as TextAdaptor;
return textAdaptor?.TextRangeFromTextPointers(rangeStart, rangeEnd);
}

/// <summary>
/// GetNameCore will return a value matching (in priority order)
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,34 @@ internal void ScrollIntoView(ITextPointer start, ITextPointer end, bool alignToT
}
}

// convert a range given by TextPointers to a UIA TextRange
// (helper method for raising ActiveTextPositionChanged event)
internal ITextRangeProvider TextRangeFromTextPointers(ITextPointer rangeStart, ITextPointer rangeEnd)
{
// special case for the entire range
if (rangeStart == null && rangeEnd == null)
return null;

// map null into the appropriate endpoint
rangeStart = rangeStart ?? _textContainer.Start;
rangeEnd = rangeEnd ?? _textContainer.End;

// if either pointer belongs to the wrong tree, return null (meaning "entire range")
if (rangeStart.TextContainer != _textContainer || rangeEnd.TextContainer != _textContainer)
return null;

// swap the pointers, if necessary
if (rangeStart.CompareTo(rangeEnd) > 0)
{
ITextPointer temp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = rangeStart;
}

// return the resulting range
return new TextRangeAdaptor(this, rangeStart, rangeEnd, _textPeer);
}

#endregion Internal Methods

//-------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2351,6 +2351,7 @@ void System.Windows.Automation.Provider.IValueProvider.SetValue(string val) { }
public abstract partial class ContentTextAutomationPeer : System.Windows.Automation.Peers.FrameworkContentElementAutomationPeer
{
protected ContentTextAutomationPeer(System.Windows.FrameworkContentElement owner) : base (default(System.Windows.FrameworkContentElement)) { }
public virtual void RaiseActiveTextPositionChangedEvent(System.Windows.Documents.TextPointer rangeStart, System.Windows.Documents.TextPointer rangeEnd) { }
}
public partial class ContextMenuAutomationPeer : System.Windows.Automation.Peers.FrameworkElementAutomationPeer
{
Expand Down Expand Up @@ -3098,6 +3099,7 @@ public abstract partial class TextAutomationPeer : System.Windows.Automation.Pee
{
protected TextAutomationPeer(System.Windows.FrameworkElement owner) : base (default(System.Windows.FrameworkElement)) { }
protected override string GetNameCore() { throw null; }
public virtual void RaiseActiveTextPositionChangedEvent(System.Windows.Documents.TextPointer rangeStart, System.Windows.Documents.TextPointer rangeEnd) { }
}
public partial class TextBlockAutomationPeer : System.Windows.Automation.Peers.FrameworkElementAutomationPeer
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,14 @@ internal static AutomationElement Wrap(SafeNodeHandle hnode)
/// <summary>Event ID: LayoutInvalidated - Indicates that many element locations/extents/offscreenedness have changed.</summary>
public static readonly AutomationEvent LayoutInvalidatedEvent = AutomationElementIdentifiers.LayoutInvalidatedEvent;

/// <summary>Event ID: Notification - used mainly by servers to raise a generic notification.</summary>
public static readonly AutomationEvent NotificationEvent = AutomationElementIdentifiers.NotificationEvent;

/// <summary>Event ID: ActiveTextPositionChanged - Indicates that the active position within a text element has changed.</summary>
public static readonly AutomationEvent ActiveTextPositionChangedEvent = AutomationElementIdentifiers.ActiveTextPositionChangedEvent;

#endregion Events

#endregion Public Constants and Readonly Fields


Expand All @@ -292,7 +298,7 @@ internal static AutomationElement Wrap(SafeNodeHandle hnode)
// Public Methods
//
//------------------------------------------------------

#region Public Methods

#region Equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public sealed partial class AutomationElement
internal AutomationElement() { }
public static readonly System.Windows.Automation.AutomationProperty AcceleratorKeyProperty;
public static readonly System.Windows.Automation.AutomationProperty AccessKeyProperty;
public static readonly System.Windows.Automation.AutomationEvent ActiveTextPositionChangedEvent;
public static readonly System.Windows.Automation.AutomationEvent AsyncContentLoadedEvent;
public static readonly System.Windows.Automation.AutomationEvent AutomationFocusChangedEvent;
public static readonly System.Windows.Automation.AutomationProperty AutomationIdProperty;
Expand Down Expand Up @@ -80,6 +81,7 @@ internal AutomationElement() { }
public static readonly System.Windows.Automation.AutomationEvent MenuOpenedEvent;
public static readonly System.Windows.Automation.AutomationProperty NameProperty;
public static readonly System.Windows.Automation.AutomationProperty NativeWindowHandleProperty;
public static readonly System.Windows.Automation.AutomationEvent NotificationEvent;
public static readonly object NotSupported;
public static readonly System.Windows.Automation.AutomationProperty OrientationProperty;
public static readonly System.Windows.Automation.AutomationProperty PositionInSetProperty;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

//
// This file specifies type-forwarding attributes, used by both the
// real assembly and the reference assembly.
//

using System;
using System.Runtime.CompilerServices;

[assembly: TypeForwardedTo(typeof(System.Windows.Automation.Provider.IRawElementProviderSimple))]
[assembly: TypeForwardedTo(typeof(System.Windows.Automation.Provider.ITextRangeProvider))]
[assembly: TypeForwardedTo(typeof(System.Windows.Automation.Provider.ProviderOptions))]
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ internal static void UiaRaiseAsyncContentLoadedEvent(IRawElementProviderSimple p
CheckError(RawUiaRaiseAsyncContentLoadedEvent(provider, asyncContentLoadedState, PercentComplete));
}

internal static void UiaRaiseNotificationEvent(IRawElementProviderSimple provider,
AutomationNotificationKind notificationKind, AutomationNotificationProcessing notificationProcessing, string displayString, string activityId)
{
CheckError(RawUiaRaiseNotificationEvent(provider, notificationKind, notificationProcessing, displayString, activityId));
}

internal static void UiaRaiseActiveTextPositionChangedEvent(IRawElementProviderSimple provider, ITextRangeProvider textRange)
{
CheckError(RawUiaRaiseActiveTextPositionChangedEvent(provider, textRange));
}

internal static bool UiaClientsAreListening()
{
return RawUiaClientsAreListening();
Expand Down Expand Up @@ -124,6 +135,13 @@ private static void CheckError(int hr)
[DllImport(DllImport.UIAutomationCore, EntryPoint = "UiaRaiseAsyncContentLoadedEvent", CharSet = CharSet.Unicode)]
private static extern int RawUiaRaiseAsyncContentLoadedEvent(IRawElementProviderSimple provider, AsyncContentLoadedState asyncContentLoadedState, double PercentComplete);

[DllImport(DllImport.UIAutomationCore, EntryPoint = "UiaRaiseNotificationEvent", CharSet = CharSet.Unicode)]
private static extern int RawUiaRaiseNotificationEvent(IRawElementProviderSimple provider,
AutomationNotificationKind notificationKind, AutomationNotificationProcessing notificationProcessing, string displayString, string activityId);

[DllImport(DllImport.UIAutomationCore, EntryPoint = "UiaRaiseActiveTextPositionChangedEvent", CharSet = CharSet.Unicode)]
private static extern int RawUiaRaiseActiveTextPositionChangedEvent(IRawElementProviderSimple provider, ITextRangeProvider textRange);

[DllImport(DllImport.UIAutomationCore, EntryPoint = "UiaClientsAreListening", CharSet = CharSet.Unicode)]
private static extern bool RawUiaClientsAreListening();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,37 @@ public static void RaiseAutomationEvent(AutomationEvent eventId, IRawElementProv
UiaCoreProviderApi.UiaRaiseAsyncContentLoadedEvent(provider, asyncArgs.AsyncContentLoadedState, asyncArgs.PercentComplete);
return;
}

// PRESHARP will flag this as warning 56506/6506:Parameter 'e' to this public method must be validated: A null-dereference can occur here.
// False positive, e is checked, see above
#pragma warning suppress 6506
if (e.EventId == AutomationElementIdentifiers.NotificationEvent)
{
NotificationEventArgs notificationArgs = e as NotificationEventArgs;
if (notificationArgs == null)
ThrowInvalidArgument("e");

UiaCoreProviderApi.UiaRaiseNotificationEvent(provider,
notificationArgs.NotificationKind,
notificationArgs.NotificationProcessing,
notificationArgs.DisplayString,
notificationArgs.ActivityId);
return;
}

// PRESHARP will flag this as warning 56506/6506:Parameter 'e' to this public method must be validated: A null-dereference can occur here.
// False positive, e is checked, see above
#pragma warning suppress 6506
if (e.EventId == AutomationElementIdentifiers.ActiveTextPositionChangedEvent)
{
ActiveTextPositionChangedEventArgs activeTextPositionChangedArgs = e as ActiveTextPositionChangedEventArgs;
if (activeTextPositionChangedArgs == null)
ThrowInvalidArgument("e");

UiaCoreProviderApi.UiaRaiseActiveTextPositionChangedEvent(provider, activeTextPositionChangedArgs.TextRange);
return;
}

// PRESHARP will flag this as warning 56506/6506:Parameter 'e' to this public method must be validated: A null-dereference can occur here.
// False positive, e is checked, see above
#pragma warning suppress 6506
Expand Down
Loading