Skip to content

Commit 6b578d2

Browse files
Move sub-classes of "NotifyIcon", "ToolStripDropDownItem", "ToolStripSplitButton" and "ToolStripStatusLabel" classes to their own files (#4612)
1 parent 4db9266 commit 6b578d2

10 files changed

+584
-513
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
#nullable disable
6+
7+
using System.Diagnostics;
8+
using System.Runtime.InteropServices;
9+
using static Interop;
10+
11+
namespace System.Windows.Forms
12+
{
13+
public sealed partial class NotifyIcon
14+
{
15+
/// <summary>
16+
/// Defines a placeholder window that the NotifyIcon is attached to.
17+
/// </summary>
18+
private class NotifyIconNativeWindow : NativeWindow
19+
{
20+
internal NotifyIcon reference;
21+
private GCHandle rootRef; // We will root the control when we do not want to be elligible for garbage collection.
22+
23+
/// <summary>
24+
/// Create a new NotifyIcon, and bind the window to the NotifyIcon component.
25+
/// </summary>
26+
internal NotifyIconNativeWindow(NotifyIcon component)
27+
{
28+
reference = component;
29+
}
30+
31+
~NotifyIconNativeWindow()
32+
{
33+
// This same post is done in Control's Dispose method, so if you change
34+
// it, change it there too.
35+
//
36+
if (Handle != IntPtr.Zero)
37+
{
38+
User32.PostMessageW(this, User32.WM.CLOSE);
39+
}
40+
41+
// This releases the handle from our window proc, re-routing it back to
42+
// the system.
43+
}
44+
45+
public void LockReference(bool locked)
46+
{
47+
if (locked)
48+
{
49+
if (!rootRef.IsAllocated)
50+
{
51+
rootRef = GCHandle.Alloc(reference, GCHandleType.Normal);
52+
}
53+
}
54+
else
55+
{
56+
if (rootRef.IsAllocated)
57+
{
58+
rootRef.Free();
59+
}
60+
}
61+
}
62+
63+
protected override void OnThreadException(Exception e)
64+
{
65+
Application.OnThreadException(e);
66+
}
67+
68+
/// <summary>
69+
/// Pass messages on to the NotifyIcon object's wndproc handler.
70+
/// </summary>
71+
protected override void WndProc(ref Message m)
72+
{
73+
Debug.Assert(reference != null, "NotifyIcon was garbage collected while it was still visible. How did we let that happen?");
74+
reference.WndProc(ref m);
75+
}
76+
}
77+
}
78+
}

src/System.Windows.Forms/src/System/Windows/Forms/NotifyIcon.cs

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
#nullable disable
66

77
using System.ComponentModel;
8-
using System.Diagnostics;
98
using System.Drawing;
10-
using System.Runtime.InteropServices;
119
using static Interop;
1210
using static Interop.Shell32;
1311

@@ -22,7 +20,7 @@ namespace System.Windows.Forms
2220
[Designer("System.Windows.Forms.Design.NotifyIconDesigner, " + AssemblyRef.SystemDesign)]
2321
[ToolboxItemFilter("System.Windows.Forms")]
2422
[SRDescription(nameof(SR.DescriptionNotifyIcon))]
25-
public sealed class NotifyIcon : Component
23+
public sealed partial class NotifyIcon : Component
2624
{
2725
internal const int MaxTextSize = 127;
2826
private static readonly object EVENT_MOUSEDOWN = new object();
@@ -817,68 +815,5 @@ private void WndProc(ref Message msg)
817815
break;
818816
}
819817
}
820-
821-
/// <summary>
822-
/// Defines a placeholder window that the NotifyIcon is attached to.
823-
/// </summary>
824-
private class NotifyIconNativeWindow : NativeWindow
825-
{
826-
internal NotifyIcon reference;
827-
private GCHandle rootRef; // We will root the control when we do not want to be elligible for garbage collection.
828-
829-
/// <summary>
830-
/// Create a new NotifyIcon, and bind the window to the NotifyIcon component.
831-
/// </summary>
832-
internal NotifyIconNativeWindow(NotifyIcon component)
833-
{
834-
reference = component;
835-
}
836-
837-
~NotifyIconNativeWindow()
838-
{
839-
// This same post is done in Control's Dispose method, so if you change
840-
// it, change it there too.
841-
//
842-
if (Handle != IntPtr.Zero)
843-
{
844-
User32.PostMessageW(this, User32.WM.CLOSE);
845-
}
846-
847-
// This releases the handle from our window proc, re-routing it back to
848-
// the system.
849-
}
850-
851-
public void LockReference(bool locked)
852-
{
853-
if (locked)
854-
{
855-
if (!rootRef.IsAllocated)
856-
{
857-
rootRef = GCHandle.Alloc(reference, GCHandleType.Normal);
858-
}
859-
}
860-
else
861-
{
862-
if (rootRef.IsAllocated)
863-
{
864-
rootRef.Free();
865-
}
866-
}
867-
}
868-
869-
protected override void OnThreadException(Exception e)
870-
{
871-
Application.OnThreadException(e);
872-
}
873-
874-
/// <summary>
875-
/// Pass messages on to the NotifyIcon object's wndproc handler.
876-
/// </summary>
877-
protected override void WndProc(ref Message m)
878-
{
879-
Debug.Assert(reference != null, "NotifyIcon was garbage collected while it was still visible. How did we let that happen?");
880-
reference.WndProc(ref m);
881-
}
882-
}
883818
}
884819
}

src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDownItem.cs

Lines changed: 0 additions & 211 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Diagnostics;
99
using System.Drawing;
1010
using System.Windows.Forms.Layout;
11-
using static Interop;
1211

1312
namespace System.Windows.Forms
1413
{
@@ -768,214 +767,4 @@ internal override void ToolStrip_RescaleConstants(int oldDpi, int newDpi)
768767
base.ToolStrip_RescaleConstants(oldDpi, newDpi);
769768
}
770769
}
771-
772-
public class ToolStripDropDownItemAccessibleObject : ToolStripItem.ToolStripItemAccessibleObject
773-
{
774-
private readonly ToolStripDropDownItem owner;
775-
public ToolStripDropDownItemAccessibleObject(ToolStripDropDownItem item) : base(item)
776-
{
777-
owner = item;
778-
}
779-
public override AccessibleRole Role
780-
{
781-
get
782-
{
783-
AccessibleRole role = Owner.AccessibleRole;
784-
if (role != AccessibleRole.Default)
785-
{
786-
return role;
787-
}
788-
return AccessibleRole.MenuItem;
789-
}
790-
}
791-
792-
public override void DoDefaultAction()
793-
{
794-
if (Owner is ToolStripDropDownItem item && item.HasDropDownItems)
795-
{
796-
item.ShowDropDown();
797-
}
798-
else
799-
{
800-
base.DoDefaultAction();
801-
}
802-
}
803-
804-
internal override bool IsIAccessibleExSupported()
805-
{
806-
if (owner != null)
807-
{
808-
return true;
809-
}
810-
else
811-
{
812-
return base.IsIAccessibleExSupported();
813-
}
814-
}
815-
816-
internal override bool IsPatternSupported(UiaCore.UIA patternId)
817-
{
818-
if (patternId == UiaCore.UIA.ExpandCollapsePatternId && owner.HasDropDownItems)
819-
{
820-
return true;
821-
}
822-
else
823-
{
824-
return base.IsPatternSupported(patternId);
825-
}
826-
}
827-
828-
internal override object GetPropertyValue(UiaCore.UIA propertyID)
829-
{
830-
if (propertyID == UiaCore.UIA.IsOffscreenPropertyId && owner != null && owner.Owner is ToolStripDropDown)
831-
{
832-
return !((ToolStripDropDown)owner.Owner).Visible;
833-
}
834-
835-
return base.GetPropertyValue(propertyID);
836-
}
837-
838-
internal override void Expand()
839-
=> DoDefaultAction();
840-
841-
internal override void Collapse()
842-
{
843-
if (owner != null && owner.DropDown != null && owner.DropDown.Visible)
844-
{
845-
owner.DropDown.Close();
846-
}
847-
}
848-
849-
internal override UiaCore.ExpandCollapseState ExpandCollapseState
850-
{
851-
get
852-
{
853-
return owner.DropDown.Visible ? UiaCore.ExpandCollapseState.Expanded : UiaCore.ExpandCollapseState.Collapsed;
854-
}
855-
}
856-
857-
public override AccessibleObject GetChild(int index)
858-
{
859-
if ((owner is null) || !owner.HasDropDownItems)
860-
{
861-
return null;
862-
}
863-
return owner.DropDown.AccessibilityObject.GetChild(index);
864-
}
865-
866-
public override int GetChildCount()
867-
{
868-
if ((owner is null) || !owner.HasDropDownItems)
869-
{
870-
return -1;
871-
}
872-
873-
// Do not expose child items when the submenu is collapsed to prevent Narrator from announcing
874-
// invisible menu items when Narrator is in item's mode (CAPSLOCK + Arrow Left/Right) or
875-
// in scan mode (CAPSLOCK + Space)
876-
if (ExpandCollapseState == UiaCore.ExpandCollapseState.Collapsed)
877-
{
878-
return 0;
879-
}
880-
881-
if (owner.DropDown.LayoutRequired)
882-
{
883-
LayoutTransaction.DoLayout(owner.DropDown, owner.DropDown, PropertyNames.Items);
884-
}
885-
return owner.DropDown.AccessibilityObject.GetChildCount();
886-
}
887-
888-
internal int GetChildFragmentIndex(ToolStripItem.ToolStripItemAccessibleObject child)
889-
{
890-
if ((owner is null) || (owner.DropDownItems is null))
891-
{
892-
return -1;
893-
}
894-
895-
for (int i = 0; i < owner.DropDownItems.Count; i++)
896-
{
897-
if (owner.DropDownItems[i].Available && child.Owner == owner.DropDownItems[i])
898-
{
899-
return i;
900-
}
901-
}
902-
903-
return -1;
904-
}
905-
906-
/// <summary>
907-
/// Gets the number of children belonging to an accessible object.
908-
/// </summary>
909-
/// <returns>The number of children.</returns>
910-
internal int GetChildFragmentCount()
911-
{
912-
if ((owner is null) || (owner.DropDownItems is null))
913-
{
914-
return -1;
915-
}
916-
917-
int count = 0;
918-
for (int i = 0; i < owner.DropDownItems.Count; i++)
919-
{
920-
if (owner.DropDownItems[i].Available)
921-
{
922-
count++;
923-
}
924-
}
925-
926-
return count;
927-
}
928-
929-
internal AccessibleObject GetChildFragment(int index)
930-
{
931-
if (owner.DropDown.AccessibilityObject is ToolStrip.ToolStripAccessibleObject toolStripAccessibleObject)
932-
{
933-
return toolStripAccessibleObject.GetChildFragment(index);
934-
}
935-
936-
return null;
937-
}
938-
939-
internal override UiaCore.IRawElementProviderFragment FragmentNavigate(UiaCore.NavigateDirection direction)
940-
{
941-
if (owner is null || owner.DropDown is null)
942-
{
943-
return null;
944-
}
945-
946-
switch (direction)
947-
{
948-
case UiaCore.NavigateDirection.NextSibling:
949-
case UiaCore.NavigateDirection.PreviousSibling:
950-
if (!(owner.Owner is ToolStripDropDown dropDown))
951-
{
952-
break;
953-
}
954-
int index = dropDown.Items.IndexOf(owner);
955-
956-
if (index == -1)
957-
{
958-
Debug.Fail("No item matched the index?");
959-
return null;
960-
}
961-
962-
index += direction == UiaCore.NavigateDirection.NextSibling ? 1 : -1;
963-
964-
if (index >= 0 && index < dropDown.Items.Count)
965-
{
966-
ToolStripItem item = dropDown.Items[index];
967-
if (item is ToolStripControlHost controlHostItem)
968-
{
969-
return controlHostItem.ControlAccessibilityObject;
970-
}
971-
972-
return item.AccessibilityObject;
973-
}
974-
975-
return null;
976-
}
977-
978-
return base.FragmentNavigate(direction);
979-
}
980-
}
981770
}

0 commit comments

Comments
 (0)