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
Expand Up @@ -273,6 +273,22 @@ void ITextRangeProvider.ExpandToEnclosingUnit(TextUnit unit)

double[] ITextRangeProvider.GetBoundingRectangles()
{
Rectangle ownerBounds = Drawing.Rectangle.Empty;

if (_enclosingElement.GetPropertyValue(UIA.BoundingRectanglePropertyId) is Rectangle boundsPropertyValue)
{
ownerBounds = boundsPropertyValue;
}

// We accumulate rectangles onto a list.
List<Rectangle> rectangles = new List<Rectangle>();

if (_provider.TextLength == 0)
{
rectangles.Add(ownerBounds);
return _provider.RectListToDoubleArray(rectangles);
}

// if this is an end of line
if (Start == _provider.TextLength)
{
Expand All @@ -292,30 +308,19 @@ double[] ITextRangeProvider.GetBoundingRectangles()

string text = _provider.Text;
ValidateEndpoints();
Rectangle ownerBounds = Drawing.Rectangle.Empty;

if (_enclosingElement.GetPropertyValue(UIA.BoundingRectanglePropertyId) is object boundsPropertyValue)
{
ownerBounds = (Rectangle)boundsPropertyValue;
}

// Get the mapping from client coordinates to screen coordinates.
Point mapClientToScreen = new Point(ownerBounds.X, ownerBounds.Y);

// Clip the rectangles to the edit control's formatting rectangle.
Rectangle clippingRectangle = _provider.BoundingRectangle;

// We accumulate rectangles onto a list.
List<Rectangle> rectangles;

if (_provider.IsMultiline)
{
rectangles = GetMultilineBoundingRectangles(text, mapClientToScreen, clippingRectangle);
return _provider.RectListToDoubleArray(rectangles);
}

rectangles = new List<Rectangle>();

// Figure out the rectangle for this one line.
Point startPoint = _provider.GetPositionFromChar(Start);
Point endPoint = _provider.GetPositionFromCharForUpperRightCorner(End - 1, text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,26 @@ internal void UiaTextRange_ITextRangeProvider_GetAttributeValue_Returns_Correct(
Assert.Equal(attributeValue, actual);
}

[StaFact]
public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsEmpty_for_EmptyText()
{
Mock<IRawElementProviderSimple> enclosingElementMock = new Mock<IRawElementProviderSimple>(MockBehavior.Strict);
enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new Rectangle(10, 33, 96, 19));
IRawElementProviderSimple enclosingElement = enclosingElementMock.Object;
Mock<UiaTextProvider> providerMock = new Mock<UiaTextProvider>(MockBehavior.Strict);
providerMock.Setup(p => p.TextLength).Returns(0);
UiaTextProvider provider = providerMock.Object;
UiaTextRange textRange = new UiaTextRange(enclosingElement, provider, start: 0, end: 0);
var actual = ((ITextRangeProvider)textRange).GetBoundingRectangles();
Assert.Equal(new double[] { 10, 33, 96, 19 }, actual);
}

[StaFact]
public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsEmpty_for_DegenerateRange()
{
IRawElementProviderSimple enclosingElement = new Mock<IRawElementProviderSimple>(MockBehavior.Strict).Object;
Mock<IRawElementProviderSimple> enclosingElementMock = new Mock<IRawElementProviderSimple>(MockBehavior.Strict);
enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new Rectangle(10, 33, 96, 19));
IRawElementProviderSimple enclosingElement = enclosingElementMock.Object;
Mock<UiaTextProvider> providerMock = new Mock<UiaTextProvider>(MockBehavior.Strict);
providerMock.Setup(p => p.TextLength).Returns(5);
UiaTextProvider provider = providerMock.Object;
Expand All @@ -533,7 +549,9 @@ public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsEmpty_f
[StaFact]
public void UiaTextRange_ITextRangeProvider_GetBoundingRectangles_ReturnsExpected_for_Endline()
{
IRawElementProviderSimple enclosingElement = new Mock<IRawElementProviderSimple>(MockBehavior.Strict).Object;
Mock<IRawElementProviderSimple> enclosingElementMock = new Mock<IRawElementProviderSimple>(MockBehavior.Strict);
enclosingElementMock.Setup(m => m.GetPropertyValue(UIA.BoundingRectanglePropertyId)).Returns(new Rectangle(10, 33, 96, 19));
IRawElementProviderSimple enclosingElement = enclosingElementMock.Object;
Mock<UiaTextProvider> providerMock = new Mock<UiaTextProvider>(MockBehavior.Strict);
providerMock.Setup(p => p.TextLength).Returns(3);
providerMock.Setup(p => p.PointToScreen(It.IsAny<Point>())).Returns(Point.Empty);
Expand Down
2 changes: 2 additions & 0 deletions src/System.Windows.Forms/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
~override System.Windows.Forms.ComboBox.OnMouseDown(System.Windows.Forms.MouseEventArgs e) -> void
~override System.Windows.Forms.ComboBox.OnKeyUp(System.Windows.Forms.KeyEventArgs e) -> void
~override System.Windows.Forms.ListView.OnLostFocus(System.EventArgs e) -> void
~override System.Windows.Forms.TabControl.OnGotFocus(System.EventArgs e) -> void
~override System.Windows.Forms.TabControl.OnLostFocus(System.EventArgs e) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal class ComboBoxChildEditUiaProvider : ChildAccessibleObject
private const string COMBO_BOX_EDIT_AUTOMATION_ID = "1001";

private readonly ComboBox _owner;
private readonly ComboBoxUiaTextProvider _textProvider;
private readonly IntPtr _handle;

/// <summary>
Expand All @@ -31,6 +32,8 @@ public ComboBoxChildEditUiaProvider(ComboBox owner, IntPtr childEditControlhandl
{
_owner = owner;
_handle = childEditControlhandle;
_textProvider = new ComboBoxUiaTextProvider(owner);
UseTextProviders(_textProvider, _textProvider);
}

/// <summary>
Expand Down Expand Up @@ -110,7 +113,12 @@ internal override object GetPropertyValue(UiaCore.UIA propertyID)
return _handle;
case UiaCore.UIA.IsOffscreenPropertyId:
return false;

case UiaCore.UIA.IsTextPatternAvailablePropertyId:
return IsPatternSupported(UiaCore.UIA.TextPatternId);
case UiaCore.UIA.IsTextPattern2AvailablePropertyId:
return IsPatternSupported(UiaCore.UIA.TextPattern2Id);
case UiaCore.UIA.IsValuePatternAvailablePropertyId:
return IsPatternSupported(UiaCore.UIA.ValuePatternId);
default:
return base.GetPropertyValue(propertyID);
}
Expand All @@ -127,6 +135,15 @@ internal override UiaCore.IRawElementProviderSimple HostRawElementProvider

internal override bool IsIAccessibleExSupported() => true;

internal override bool IsPatternSupported(UiaCore.UIA patternId) =>
patternId switch
{
UiaCore.UIA.ValuePatternId => true,
UiaCore.UIA.TextPatternId => true,
UiaCore.UIA.TextPattern2Id => true,
_ => base.IsPatternSupported(patternId)
};

/// <summary>
/// Gets the runtime ID.
/// </summary>
Expand Down
Loading