Skip to content

Commit b9b4c7e

Browse files
author
Dmitrii Drobotov
committed
Refactor and make fixes after code review
* Update ListViewLabelEditAccessibleObject after TextProvider refactoring * Add new unit tests for constructor arguments
1 parent 4333780 commit b9b4c7e

File tree

7 files changed

+171
-129
lines changed

7 files changed

+171
-129
lines changed

src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.SetWinEventHook.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ internal static partial class Interop
99
internal static partial class User32
1010
{
1111
[DllImport(Libraries.User32, ExactSpelling = true, SetLastError = true)]
12-
public static extern nint SetWinEventHook(
13-
uint eventMin, uint eventMax, nint hmodWinEventProc, WINEVENTPROC pfnWinEventProc, uint idProcess, uint idThread, WINEVENT dwFlags);
12+
private static extern nint SetWinEventHook(uint eventMin, uint eventMax, nint hmodWinEventProc,
13+
WINEVENTPROC pfnWinEventProc, uint idProcess, uint idThread, WINEVENT dwFlags);
1414

1515
public static nint SetWinEventHook(uint eventId, WINEVENTPROC pfnWinEventProc)
16-
=> SetWinEventHook(
17-
eventId, eventId, Kernel32.GetModuleHandleW(null), pfnWinEventProc, (uint)Environment.ProcessId, Kernel32.GetCurrentThreadId(), WINEVENT.INCONTEXT);
16+
=> SetWinEventHook(eventId, eventId, Kernel32.GetModuleHandleW(null), pfnWinEventProc,
17+
(uint)Environment.ProcessId, Kernel32.GetCurrentThreadId(), WINEVENT.INCONTEXT);
1818
}
1919
}

src/System.Windows.Forms.Primitives/src/Interop/User32/Interop.WINEVENT.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ internal static partial class Interop
66
{
77
internal static partial class User32
88
{
9-
public enum WINEVENT : int
9+
public enum WINEVENT : uint
1010
{
1111
OUTOFCONTEXT = 0,
1212
SKIPOWNTHREAD = 1,

src/System.Windows.Forms/src/System/Windows/Forms/ListView.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public partial class ListView : Control
179179

180180
private bool _blockLabelEdit;
181181

182-
private ListViewLabelEditNativeWindow _labelEdit;
182+
private ListViewLabelEditNativeWindow? _labelEdit;
183183

184184
// Background image stuff
185185
// Because we have to create a temporary file and the OS does not clean up the temporary files from the machine
@@ -6468,9 +6468,12 @@ private unsafe void WmReflectNotify(ref Message m)
64686468

64696469
case (int)LVN.BEGINLABELEDITW:
64706470
{
6471+
Debug.Assert(_labelEdit is null,
6472+
"A new label editing shouldn't start before the previous one ended");
64716473
if (_labelEdit is not null)
64726474
{
6473-
throw new InvalidOperationException("A new label editing can't be started before the previous one was ended.");
6475+
_labelEdit.ReleaseHandle();
6476+
_labelEdit = null;
64746477
}
64756478

64766479
bool cancelEdit;
@@ -6524,9 +6527,10 @@ private unsafe void WmReflectNotify(ref Message m)
65246527

65256528
case (int)LVN.ENDLABELEDITW:
65266529
{
6530+
Debug.Assert(_labelEdit is not null, "There is no active label edit to end");
65276531
if (_labelEdit is null)
65286532
{
6529-
throw new InvalidOperationException("There is no active label edit to end");
6533+
break;
65306534
}
65316535

65326536
_labelEdit.ReleaseHandle();

src/System.Windows.Forms/src/System/Windows/Forms/ListViewLabelEditAccessibleObject.cs

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using System.Diagnostics;
5+
using System.Drawing;
66
using System.Runtime.InteropServices;
77
using static Interop;
88

@@ -12,57 +12,57 @@ internal class ListViewLabelEditAccessibleObject : AccessibleObject
1212
{
1313
private const string LIST_VIEW_LABEL_EDIT_AUTOMATION_ID = "1";
1414

15-
private ListView _owner;
16-
private IntPtr _handle;
15+
private readonly ListView _owningListView;
16+
private readonly IntPtr _handle;
17+
private readonly ListViewLabelEditUiaTextProvider _textProvider;
1718
private int[]? _runtimeId;
1819

19-
public ListViewLabelEditAccessibleObject(ListView owner, IHandle handle)
20+
public ListViewLabelEditAccessibleObject(ListView owningListView, IHandle handle)
2021
{
21-
_owner = owner;
22+
_owningListView = owningListView.OrThrowIfNull();
2223
_handle = handle.Handle;
2324
UseStdAccessibleObjects(_handle);
25+
_textProvider = new ListViewLabelEditUiaTextProvider(owningListView, handle, this);
26+
}
27+
28+
private protected override string AutomationId => LIST_VIEW_LABEL_EDIT_AUTOMATION_ID;
29+
30+
internal override UiaCore.IRawElementProviderFragment? FragmentNavigate(UiaCore.NavigateDirection direction)
31+
{
32+
AccessibleObject parent = _owningListView.AccessibilityObject;
2433

25-
ListViewLabelEditUiaTextProvider textProvider = new(owner, handle, this);
26-
UseTextProviders(textProvider, textProvider);
34+
return direction switch
35+
{
36+
UiaCore.NavigateDirection.Parent => parent,
37+
UiaCore.NavigateDirection.NextSibling => parent.GetChildIndex(this) is int childId and >= 0 ? parent.GetChild(childId + 1) : null,
38+
UiaCore.NavigateDirection.PreviousSibling => parent.GetChildIndex(this) is int childId and >= 0 ? parent.GetChild(childId - 1) : null,
39+
_ => base.FragmentNavigate(direction),
40+
};
2741
}
2842

43+
internal override UiaCore.IRawElementProviderFragmentRoot FragmentRoot => _owningListView.AccessibilityObject;
44+
2945
internal override object? GetPropertyValue(UiaCore.UIA propertyID)
3046
=> propertyID switch
3147
{
32-
UiaCore.UIA.RuntimeIdPropertyId => RuntimeId,
33-
UiaCore.UIA.BoundingRectanglePropertyId => Bounds,
3448
UiaCore.UIA.ProcessIdPropertyId => Environment.ProcessId,
3549
UiaCore.UIA.ControlTypePropertyId => UiaCore.UIA.EditControlTypeId,
36-
UiaCore.UIA.NamePropertyId => Name,
3750
UiaCore.UIA.AccessKeyPropertyId => string.Empty,
3851
UiaCore.UIA.HasKeyboardFocusPropertyId => true,
3952
UiaCore.UIA.IsKeyboardFocusablePropertyId => (State & AccessibleStates.Focusable) == AccessibleStates.Focusable,
40-
UiaCore.UIA.IsEnabledPropertyId => Enabled,
41-
UiaCore.UIA.AutomationIdPropertyId => LIST_VIEW_LABEL_EDIT_AUTOMATION_ID,
42-
UiaCore.UIA.HelpTextPropertyId => Help ?? string.Empty,
53+
UiaCore.UIA.IsEnabledPropertyId => _owningListView.Enabled,
4354
UiaCore.UIA.IsContentElementPropertyId => true,
44-
UiaCore.UIA.IsPasswordPropertyId => false,
4555
UiaCore.UIA.NativeWindowHandlePropertyId => _handle,
46-
UiaCore.UIA.IsOffscreenPropertyId => false,
47-
UiaCore.UIA.IsTextPatternAvailablePropertyId => IsPatternSupported(UiaCore.UIA.TextPatternId),
48-
UiaCore.UIA.IsTextPattern2AvailablePropertyId => IsPatternSupported(UiaCore.UIA.TextPattern2Id),
49-
UiaCore.UIA.IsValuePatternAvailablePropertyId => IsPatternSupported(UiaCore.UIA.ValuePatternId),
50-
UiaCore.UIA.IsLegacyIAccessiblePatternAvailablePropertyId => IsPatternSupported(UiaCore.UIA.LegacyIAccessiblePatternId),
5156
_ => base.GetPropertyValue(propertyID),
5257
};
5358

54-
internal override UiaCore.IRawElementProviderFragment? FragmentNavigate(UiaCore.NavigateDirection direction)
59+
internal override UiaCore.IRawElementProviderSimple? HostRawElementProvider
5560
{
56-
AccessibleObject parent = _owner.AccessibilityObject;
57-
58-
return direction switch
61+
get
5962
{
60-
UiaCore.NavigateDirection.Parent => parent,
61-
UiaCore.NavigateDirection.NextSibling => parent.GetChildIndex(this) is int childId and >= 0 ? parent.GetChild(childId + 1) : null,
62-
UiaCore.NavigateDirection.PreviousSibling => parent.GetChildIndex(this) is int childId and >= 0 ? parent.GetChild(childId - 1) : null,
63-
UiaCore.NavigateDirection.FirstChild or UiaCore.NavigateDirection.LastChild => null,
64-
_ => base.FragmentNavigate(direction),
65-
};
63+
UiaCore.UiaHostProviderFromHwnd(new HandleRef(this, _handle), out UiaCore.IRawElementProviderSimple provider);
64+
return provider;
65+
}
6666
}
6767

6868
internal override bool IsPatternSupported(UiaCore.UIA patternId) => patternId switch
@@ -74,28 +74,32 @@ public ListViewLabelEditAccessibleObject(ListView owner, IHandle handle)
7474
_ => base.IsPatternSupported(patternId),
7575
};
7676

77+
public override string Name => User32.GetWindowText(_handle);
78+
7779
internal override int[] RuntimeId => _runtimeId ??= new int[] { RuntimeIDFirstItem, PARAM.ToInt(_handle) };
7880

79-
internal override UiaCore.IRawElementProviderFragmentRoot? FragmentRoot => _owner.AccessibilityObject;
81+
internal override UiaCore.ITextRangeProvider DocumentRangeInternal
82+
=> _textProvider.DocumentRange;
8083

81-
internal override UiaCore.IRawElementProviderSimple? HostRawElementProvider
82-
{
83-
get
84-
{
85-
UiaCore.UiaHostProviderFromHwnd(new HandleRef(this, _handle), out UiaCore.IRawElementProviderSimple provider);
86-
return provider;
87-
}
88-
}
84+
internal override UiaCore.ITextRangeProvider[]? GetTextSelection()
85+
=> _textProvider.GetSelection();
8986

90-
public override string Name => User32.GetWindowText(_handle);
87+
internal override UiaCore.ITextRangeProvider[]? GetTextVisibleRanges()
88+
=> _textProvider.GetVisibleRanges();
9189

92-
private bool Enabled
93-
{
94-
get
95-
{
96-
Debug.Assert(_owner.Enabled);
97-
return _owner.Enabled;
98-
}
99-
}
90+
internal override UiaCore.ITextRangeProvider? GetTextRangeFromChild(UiaCore.IRawElementProviderSimple childElement)
91+
=> _textProvider.RangeFromChild(childElement);
92+
93+
internal override UiaCore.ITextRangeProvider? GetTextRangeFromPoint(Point screenLocation)
94+
=> _textProvider.RangeFromPoint(screenLocation);
95+
96+
internal override UiaCore.SupportedTextSelection SupportedTextSelectionInternal
97+
=> _textProvider.SupportedTextSelection;
98+
99+
internal override UiaCore.ITextRangeProvider? GetTextCaretRange(out BOOL isActive)
100+
=> _textProvider.GetCaretRange(out isActive);
101+
102+
internal override UiaCore.ITextRangeProvider GetRangeFromAnnotation(UiaCore.IRawElementProviderSimple annotationElement)
103+
=> _textProvider.RangeFromAnnotation(annotationElement);
100104
}
101105
}

0 commit comments

Comments
 (0)