Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / WinForms / Managed / System / WinForms / ToolStripDropDown.cs / 5 / ToolStripDropDown.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Security; using System.Security.Permissions; using System.Windows.Forms; using System.Windows.Forms.Layout; using System.Runtime.InteropServices; using System.Collections.Specialized; using System.Collections.Generic; using System.Globalization; ////// /// Summary of ToolStripDropDown. /// [Designer("System.Windows.Forms.Design.ToolStripDropDownDesigner, " + AssemblyRef.SystemDesign)] [ComVisible(true)] [ClassInterface(ClassInterfaceType.AutoDispatch)] public class ToolStripDropDown : ToolStrip { private ToolStripItem ownerItem = null; private bool isAutoGenerated = false; private Point dropDownLocation = Point.Empty; private bool dropShadowEnabled = true; private bool autoClose = true; private bool autoSize = true; private int countDropDownItemsAssignedTo = 0; // the number of dropdown items using this as their dropdown.. private BitVector32 state = new BitVector32(); private Point displayLocation = new Point(0,0); private ToolStripDropDownDirection childDropDownDirection = ToolStripDropDownDirection.Default; private ToolStripDropDownCloseReason closeReason = ToolStripDropDownCloseReason.AppFocusChange; private static readonly int PropOpacity = PropertyStore.CreateKey(); private static readonly int PropDDRightToLeft = PropertyStore.CreateKey(); private static readonly int PropSourceControl = PropertyStore.CreateKey(); private static readonly object EventOpening = new object(); private static readonly object EventOpened = new object(); private static readonly object EventClosed = new object(); private static readonly object EventClosing = new object(); private static readonly object ToolStripParkingWindowKey = new object(); #if DEBUG internal static TraceSwitch DropDownActivateDebug = new TraceSwitch("DropDownActivateDebug", "Debug activation code for dropDown controls"); internal static TraceSwitch DropDownDebugBounds = new TraceSwitch("DropDownDebugBounds", "Debug GetDropDownBounds"); static readonly BooleanSwitch AlwaysRestrictWindows = new BooleanSwitch("AlwaysRestrictWindows", "Always make Form classes behave as though they are restricted"); #else internal static TraceSwitch DropDownActivateDebug; internal static TraceSwitch DropDownDebugBounds; #endif private static readonly int stateLayered = BitVector32.CreateMask(); private static readonly int stateAllowTransparency = BitVector32.CreateMask(stateLayered); private static readonly int stateIsRestrictedWindow = BitVector32.CreateMask(stateAllowTransparency); private static readonly int stateIsRestrictedWindowChecked = BitVector32.CreateMask(stateIsRestrictedWindow); private static readonly int stateNotWorkingAreaConstrained = BitVector32.CreateMask(stateIsRestrictedWindowChecked); private static readonly int stateInSetVisibleCore = BitVector32.CreateMask(stateNotWorkingAreaConstrained); /// SECREVIEW /// ToolStripDropDown security notes /// Key ideas: /// AllWindowsPermission is required to get keystrokes, obscure the taskbar, prevent the dropdown from closing. /// /// A. Disallow ControlHost items, both shipped and user created via UiPermission.AWP. We'd simply not display these items in the internet / dropdown case. /// B. Disallow AutoClose == false and ignore cancelable closing event param. This makes it impossible to enter more than one keystroke and not cause dropdown dismissal. /// C. Restrict keystroke handling events. We would route WM_KKEY* to DefWndProc, and because Control.WndProc would be skipped, the following events would not be raised: /// On/KeyUp/On/KeyDown/On/KeyPress /// D. Ensure proper link and inheritancedemands on /// ProcessKeyPreview/ProcessDialogKey/ProcessCmdKey/ProcessKeyMessage/PreProcessMessage/WndProc /// E. Ensure proper inheritance demands on /// IsInputKey/IsInputChar /// F. Prevent double mnemonic evaluation on DropDowns (another way of getting keyboard input by having hidden items) /// Protect ProcessMnemonic. ////// /// Summary of ToolStripDropDown. /// public ToolStripDropDown() { // SECURITY NOTE: The IsRestrictedWindow check is done once and cached. We force it to happen here // since we want to ensure the check is done on the code that constructs the ToolStripDropDown. bool temp = IsRestrictedWindow; this.SuspendLayout(); Initialize(); this.ResumeLayout(false); } ////// /// Summary of ToolStripDropDown. /// /// internal ToolStripDropDown(ToolStripItem ownerItem): this() { this.ownerItem = ownerItem; } internal ToolStripDropDown(ToolStripItem ownerItem, bool isAutoGenerated) : this(ownerItem) { this.isAutoGenerated = isAutoGenerated; } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool AllowItemReorder { get { return base.AllowItemReorder; } set { base.AllowItemReorder = value; } } ////// /// /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlAllowTransparencyDescr) ] public bool AllowTransparency { get { return state[stateAllowTransparency]; } set { if (value != (state[stateAllowTransparency]) && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { state[stateAllowTransparency] = value; state[stateLayered] = state[stateAllowTransparency]; UpdateStyles(); if (!value) { if (Properties.ContainsObject(PropOpacity)) { Properties.SetObject(PropOpacity, (object)1.0f); } UpdateLayered(); } } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override AnchorStyles Anchor { get { return base.Anchor; } set { base.Anchor = value; } } ////// Gets or sets /// a value indicating whether the opacity of the form can be /// adjusted. ///[DefaultValue(true)] public override bool AutoSize { get { return autoSize; } set { if (autoSize != value) { autoSize = value; // we shadow CommonProperties LayoutTransaction.DoLayout(this,this,PropertyNames.AutoSize); OnAutoSizeChanged(EventArgs.Empty); } } } /// /// /// specifies whether the dropdown should automatically close when the dropdown has lost /// activation. If you want a dropdown that always stays open, specify AutoClose = false; /// [ DefaultValue(true), SRCategory(SR.CatBehavior), SRDescription(SR.ToolStripDropDownAutoCloseDescr) ] public bool AutoClose { get { return autoClose; } set { // SECREVIEW - to be honored, you must have AllWindowsPermission. See SetVisibleCore if (autoClose != value) { autoClose = value; ApplyTopMost(/*topMost=*/!autoClose); } } } [Browsable(false)] public new event EventHandler BackgroundImageChanged { add { base.BackgroundImageChanged += value; } remove { base.BackgroundImageChanged -= value; } } [Browsable(false)] public new event EventHandler BackgroundImageLayoutChanged { add { base.BackgroundImageLayoutChanged += value; } remove { base.BackgroundImageLayoutChanged -= value; } } [Browsable(false)] public new event EventHandler BindingContextChanged { add { base.BindingContextChanged += value; } remove { base.BindingContextChanged -= value; } } ///[DefaultValue(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool CanOverflow { get { return base.CanOverflow; } set { base.CanOverflow = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event UICuesEventHandler ChangeUICues { add { base.ChangeUICues += value; } remove { base.ChangeUICues -= value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new ContextMenu ContextMenu { get { return base.ContextMenu; } set { base.ContextMenu = value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler ContextMenuChanged { add { base.ContextMenuChanged += value; } remove { base.ContextMenuChanged -= value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new ContextMenuStrip ContextMenuStrip { get { return base.ContextMenuStrip; } set { base.ContextMenuStrip = value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler ContextMenuStripChanged { add { base.ContextMenuStripChanged += value; } remove { base.ContextMenuStripChanged -= value; } } /// /// /// /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] get { CreateParams cp = base.CreateParams; // If we're using themes then go ahead if (DropShadowEnabled) { cp.ClassStyle |= NativeMethods.CS_DROPSHADOW; } // we're a borderless menuless control with no min/max boxes // we dont want to show in the taskbar either //Q205158 HOWTO: Prevent a Window from Appearing on the Taskbar //Give the window the WS_EX_TOOLWINDOW extended style, and remove the WS_EX_APPWINDOW style. As a side effect, the window will have a smaller caption than a normal window. //Give the window the WS_POPUP style and make it owned by a hidden window. (Form) cp.Style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_CLIPSIBLINGS); /* no caption, no siblings */ cp.ExStyle &= ~(NativeMethods.WS_EX_APPWINDOW); /* show in taskbar = false */ // | NativeMethods.WS_EX_TOOLWINDOW cp.Style |= (TopLevel) ? NativeMethods.WS_POPUP : NativeMethods.WS_CHILD; cp.ExStyle |= (NativeMethods.WS_EX_CONTROLPARENT); /* show in taskbar = false */ bool topLevel = TopLevel; // opacity if (topLevel && (state[stateLayered])) { cp.ExStyle |= NativeMethods.WS_EX_LAYERED; } else if (topLevel) { //From MSDN: Menus, dialog boxes, and combo list boxes have the CS_SAVEBITS style. When you use this style for a window, //Windows saves a bitmap copy of the screen image that the window obscures. First, Windows asks the display driver to save the bits. //If the display driver has enough memory, it saves the bits for Windows. If the display driver does not have enough memory, Window //saves the bits itself as a bitmap in global memory and also uses some of User's local heap for housekeeping structures for each window. //When the application removes the window, Windows can restore the screen image quickly by using the stored bits. cp.ClassStyle |= NativeMethods.CS_SAVEBITS; } else if (!topLevel) { cp.Style |= NativeMethods.WS_CLIPSIBLINGS; } // We're turning off CLIPSIBLINGS because in the designer the elements of the form beneath // are actually sibling controls. We want to paint right over them as if we were a toplevel window. return cp; } } ////// This is called when creating a window. Inheriting classes can overide /// this to add extra functionality, but should not forget to first call /// base.CreateParams() to make sure the control continues to work /// correctly. /// ///protected override Padding DefaultPadding { get { return new Padding(1, 2, 1, 2); } } /// We want this to default to true... This way tooltips on overflows and custom dropdowns will show. /// Since menu items don't show tooltips by default we can savely leave it on protected override bool DefaultShowItemToolTips { get { return true; } } protected override DockStyle DefaultDock { get { return DockStyle.None; } } public override ToolStripDropDownDirection DefaultDropDownDirection { get { if (childDropDownDirection == ToolStripDropDownDirection.Default) { return (RightToLeft == RightToLeft.Yes)? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; } return childDropDownDirection; } set { childDropDownDirection = value; base.DefaultDropDownDirection = value; } } ///[ DefaultValue(DockStyle.None), Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public override DockStyle Dock { get { return base.Dock; } set{ base.Dock = value; } } /// changed the browsable attribute [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler DockChanged { add { base.DockChanged += value; } remove { base.DockChanged -= value; } } /// /// Returns an owner window that can be used to /// own a drop down. /// internal override NativeWindow DropDownOwnerWindow { get { // Re-use the drop down owner from our parenting // tool strip if we can. if (ownerItem != null && ownerItem.Owner != null) { return ownerItem.Owner.DropDownOwnerWindow; } return base.DropDownOwnerWindow; } } ///public bool DropShadowEnabled { get { // VSWhidbey 338272 - DropShadows are only supported on TopMost windows // due to the flakeyness of the way it's implemented in the OS. (Non toplevel // windows can have parts of the shadow disappear because another window can get // sandwiched between the SysShadow window and the dropdown.) return dropShadowEnabled && TopMost && DisplayInformation.IsDropShadowEnabled; } set { if (dropShadowEnabled != value) { dropShadowEnabled = value; if (IsHandleCreated && !DesignMode) { RecreateHandle(); } } } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosedDecr)] public event ToolStripDropDownClosedEventHandler Closed { add { Events.AddHandler(EventClosed, value); } remove { Events.RemoveHandler(EventClosed, value); } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosingDecr)] public event ToolStripDropDownClosingEventHandler Closing { add { Events.AddHandler(EventClosing, value); } remove { Events.RemoveHandler(EventClosing, value); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler Enter { add { base.Enter += value; } remove { base.Enter -= value; } } public override Font Font { get { if (this.IsFontSet()) { return base.Font; } // if the FONT isnt set, then return our owner item's font. if (IsAutoGenerated && OwnerItem != null) { return OwnerItem.Font; } return base.Font; } set { base.Font = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler FontChanged { add { base.FontChanged += value; } remove { base.FontChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler ForeColorChanged { add { base.ForeColorChanged += value; } remove { base.ForeColorChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event GiveFeedbackEventHandler GiveFeedback { add { base.GiveFeedback += value; } remove { base.GiveFeedback -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripGripDisplayStyle GripDisplayStyle { get { return base.GripDisplayStyle; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new Rectangle GripRectangle { get { return base.GripRectangle; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new Padding GripMargin{ get { return base.GripMargin; } set { base.GripMargin = value; } } /// [DefaultValue(ToolStripGripStyle.Hidden), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripGripStyle GripStyle { get { return base.GripStyle; } set { base.GripStyle = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] //Everett new public event HelpEventHandler HelpRequested { add { base.HelpRequested += value; } remove { base.HelpRequested -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler ImeModeChanged { add { base.ImeModeChanged += value; } remove { base.ImeModeChanged -= value; } } /// /// /// determines whether this dropdown was autogenerated. /// [Browsable(false)] public bool IsAutoGenerated { get { return isAutoGenerated; } } internal bool IsAssignedToDropDownItem { get { return IsAutoGenerated || (countDropDownItemsAssignedTo > 0); } } ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] internal bool IsRestrictedWindow { get { /// SECREVIEW: make sure to keep changes here in [....] with Form.IsRestrictedWindow if (!state[stateIsRestrictedWindowChecked]) { state[stateIsRestrictedWindowChecked] = true; state[stateIsRestrictedWindow] = false; Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Checking for restricted window..."); Debug.Indent(); #if DEBUG if (AlwaysRestrictWindows.Enabled) { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Always restricted switch is on..."); state[stateIsRestrictedWindow] = true; Debug.Unindent(); return true; } #endif try { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "WindowAdornmentModification Demanded"); IntSecurity.WindowAdornmentModification.Demand(); } catch { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Caught exception, we are restricted..."); state[stateIsRestrictedWindow] = true; } Debug.Unindent(); } return state[stateIsRestrictedWindow]; } } internal override Size ImageScalingSizeInternal { get { if (IsAutoGenerated && OwnerToolStrip != null) { return OwnerToolStrip.ImageScalingSizeInternal; } return base.ImageScalingSizeInternal; } set { base.ImageScalingSizeInternal = value; } } internal override bool KeyboardActive { get { // ripple up the chain until we get the topmost toolstrip (usually the main menu strip is the one we care about) ToolStrip ownerToolStrip = OwnerToolStrip; if (ownerToolStrip != null) { return ownerToolStrip.KeyboardActive; } return base.KeyboardActive; } set { base.KeyboardActive = value; // ripple up the chain until we get the topmost toolstrip (usually the main menu strip is the one we care about) ToolStrip ownerToolStrip = OwnerToolStrip; if (ownerToolStrip != null) { ownerToolStrip.KeyboardActive = value; } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyEventHandler KeyDown { add { base.KeyDown += value; } remove { base.KeyDown -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyPressEventHandler KeyPress { add { base.KeyPress += value; } remove { base.KeyPress -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyEventHandler KeyUp { add { base.KeyUp += value; } remove { base.KeyUp -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler Leave { add { base.Leave += value; } remove { base.Leave -= value; } } ///Determines if this form should display a warning banner /// when the form is displayed in an unsecure mode. ////// Override Location to make it hidden from the user in the designer /// [ EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false) ] public new Point Location { get { return base.Location; } set { base.Location = value; } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpeningDescr)] public event CancelEventHandler Opening { add { Events.AddHandler(EventOpening, value); } remove { Events.RemoveHandler(EventOpening, value); } } ////// /// [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpenedDescr)] public event EventHandler Opened { add { Events.AddHandler(EventOpened, value); } remove { Events.RemoveHandler(EventOpened, value); } } ///Occurs when the control is clicked. ///protected internal override Size MaxItemSize { get { return Screen.GetWorkingArea(this.Bounds).Size - this.Padding.Size; } } /// /// /// Determines the opacity of the form. This can only be set on top level /// controls. Opacity requires Windows 2000 or later, and is ignored on earlier /// operating systems. /// [ SRCategory(SR.CatWindowStyle), TypeConverterAttribute(typeof(OpacityConverter)), SRDescription(SR.FormOpacityDescr), DefaultValue(1.0), Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced) ] public double Opacity { get { object opacity = Properties.GetObject(PropOpacity); if (opacity != null) { return Convert.ToDouble(opacity, CultureInfo.InvariantCulture); } else { return 1.0f; } } set { if (IsRestrictedWindow) { value = Math.Max(value, .50f); } if (value > 1.0) { value = 1.0f; } else if (value < 0.0) { value = 0.0f; } Properties.SetObject(PropOpacity, value); bool oldLayered = (state[stateLayered]); if (OpacityAsByte < 255 && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { AllowTransparency = true; state[stateLayered] = true; } else { state[stateLayered] = false; } if (oldLayered != (state[stateLayered])) { UpdateStyles(); } UpdateLayered(); } } private byte OpacityAsByte { get { return (byte)(Opacity * 255.0f); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripOverflowButton OverflowButton { get { return base.OverflowButton; } } ////// /// Summary of OwnerItem. /// [DefaultValue(null), Browsable(false)] public ToolStripItem OwnerItem { get { return ownerItem; } set { if (ownerItem != value) { Font originalFont = this.Font; RightToLeft startRightToLeft = this.RightToLeft; ownerItem = value; // RESET ambient properties if (!originalFont.Equals(Font)) { OnOwnerItemFontChanged(EventArgs.Empty); } if (ownerItem != null && RightToLeftInherited && startRightToLeft != this.RightToLeft) { using (new LayoutTransaction(this,this,PropertyNames.RightToLeft)) { OnRightToLeftChanged(EventArgs.Empty); } } } } } internal ToolStripDropDownItem OwnerDropDownItem { get { return OwnerItem as ToolStripDropDownItem; } } internal ToolStrip OwnerToolStrip { get { if (ownerItem != null) { ToolStrip owner = ownerItem.ParentInternal; if (owner != null) { return owner; } // might not actually be placed on the overflow, just check for sure. if (ownerItem.Placement == ToolStripItemPlacement.Overflow && ownerItem.Owner != null) { return ownerItem.Owner.OverflowButton.DropDown; } if (owner == null) { return ownerItem.Owner; } } return null; } } ////// /// Hide the Region Property /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public Region Region { get { return base.Region; } set { base.Region = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler RegionChanged { add { base.RegionChanged += value; } remove { base.RegionChanged -= value; } } internal virtual bool RequiresScrollButtons { get { return false; } set { Debug.Fail("You can't set this except on ToolStripDropDownMenu"); } } [ SRCategory(SR.CatAppearance), Localizable(true), AmbientValue(RightToLeft.Inherit), SRDescription(SR.ControlRightToLeftDescr) ] public override RightToLeft RightToLeft { get { // our inheritance is from our owner item. if (RightToLeftInherited) { if (SourceControlInternal != null) { return SourceControlInternal.RightToLeft; } if (OwnerItem != null) { return OwnerItem.RightToLeft; } } return base.RightToLeft; } set { base.RightToLeft = value; } } private bool RightToLeftInherited { get { // fish out of control's property store whether or not RTL was set, if it's set to inherit. return !ShouldSerializeRightToLeft(); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event ScrollEventHandler Scroll { add { base.Scroll += value; } remove { base.Scroll -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool Stretch { get { return base.Stretch; } set { base.Stretch = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler StyleChanged { add { base.StyleChanged += value; } remove { base.StyleChanged -= value; } } internal Control SourceControlInternal { get { return Properties.GetObject(PropSourceControl) as Control; } set{ Properties.SetObject(PropSourceControl, value); } } internal override int ShowParams { get { return NativeMethods.SW_SHOWNOACTIVATE; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabStopChanged { add { base.TabStopChanged += value; } remove { base.TabStopChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TextChanged { add { base.TextChanged += value; } remove { base.TextChanged -= value; } } [ Browsable(false), DefaultValue(ToolStripTextDirection.Horizontal), SRDescription(SR.ToolStripTextDirectionDescr), SRCategory(SR.CatAppearance) ] public override ToolStripTextDirection TextDirection { get { return base.TextDirection; } set { base.TextDirection = value; } } //Consistency: match casing of Form.TopMost, which shipped in Everett, even though it's wrong [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly")] protected virtual bool TopMost { get { return true; } } ///[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool TopLevel { get { return GetTopLevel(); } set { // if (value != GetTopLevel()) { SetTopLevelInternal(value); SetTopLevelStyle(value); } } } // public Color TransparencyKey { // This property intentionally not available for ToolStripDropDown // it's not robust enough for our needs // } /// /// VSWhidbey 233498: override base TabIndex property in order to avoid serialization /// (since a dropdown shouldn't participate in the taborder...) [ EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false) ] public new int TabIndex { get { return base.TabIndex; } set { base.TabIndex = value; } } /// /// [ Browsable(false), EditorBrowsable(EditorBrowsableState.Never), SRCategory(SR.CatPropertyChanged), SRDescription(SR.ControlOnTabIndexChangedDescr) ] public new event EventHandler TabIndexChanged { add { base.TabIndexChanged += value; } remove { base.TabIndexChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler Validated { add { base.Validated += value; } remove { base.Validated -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event CancelEventHandler Validating { add { base.Validating += value; } remove { base.Validating -= value; } } ///[To be supplied.] ////// VSWhidbey 233498: override base Visible property in order to control serialization by setting default value [ SRCategory(SR.CatBehavior), Localizable(true), SRDescription(SR.ControlVisibleDescr), DefaultValue(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public new bool Visible { get { return base.Visible; } set { base.Visible = value; } } // internally we use not so we dont have to initialize it. internal bool WorkingAreaConstrained { get { if (state[stateNotWorkingAreaConstrained]) { // SECREVIEW: // We are constrained to the working area when we dont have AllWindows permission return IsRestrictedWindow; } return true; } set { bool notConstrained = !value; state[stateNotWorkingAreaConstrained] = notConstrained; } } internal void AssignToDropDownItem() { countDropDownItemsAssignedTo++; } internal void AdjustSize() { Size size = GetSuggestedSize(); if (size != this.Size) { this.Size = size; } } private void ApplyTopMost(bool topMost) { if (TopMost) { HandleRef topMostFlag = (topMost) ? NativeMethods.HWND_TOPMOST : NativeMethods.HWND_NOTOPMOST; SafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), topMostFlag, 0, 0, 0, 0, NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOACTIVATE); } } /// protected override void Dispose(bool disposing) { if (disposing) { SourceControlInternal = null; } base.Dispose(disposing); } private void CancelAutoExpand() { ToolStrip toplevelOwnerToolStrip = GetToplevelOwnerToolStrip(); if (toplevelOwnerToolStrip != null) { toplevelOwnerToolStrip.MenuAutoExpand = false; } } internal override bool CanProcessMnemonic() { // VSWhidbey 515812: Dont let mnemonics act as keyboard input in IE in the internet. if (IsRestrictedWindow && !Application.MessageLoop) { return false; } return base.CanProcessMnemonic(); } /// protected override AccessibleObject CreateAccessibilityInstance() { return new ToolStripDropDownAccessibleObject(this); } protected override LayoutSettings CreateLayoutSettings(ToolStripLayoutStyle style) { LayoutSettings layoutSettings = base.CreateLayoutSettings(style); if (style == ToolStripLayoutStyle.Flow) { FlowLayoutSettings flowLayoutSettings = layoutSettings as FlowLayoutSettings; flowLayoutSettings.FlowDirection = FlowDirection.TopDown; flowLayoutSettings.WrapContents = false; return flowLayoutSettings; } return layoutSettings; } protected override void CreateHandle() { base.CreateHandle(); if (TopLevel) { ReparentToDropDownOwnerWindow(); if (!AutoClose || !WorkingAreaConstrained) { ApplyTopMost(true); } } if (DesignMode) { SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, false); } } public void Close() { SetCloseReason(ToolStripDropDownCloseReason.CloseCalled); this.Visible = false; // we were the last one in the chain, roll out of menu mode. if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == null) { ToolStripManager.ModalMenuFilter.ExitMenuMode(); } } private void ResetCloseReason() { closeReason = ToolStripDropDownCloseReason.AppFocusChange; } internal void SetCloseReason(ToolStripDropDownCloseReason reason) { closeReason = reason; } public void Close(ToolStripDropDownCloseReason reason) { SetCloseReason(reason); this.Visible = false; } internal override Rectangle ApplyBoundsConstraints(int suggestedX, int suggestedY, int proposedWidth, int proposedHeight) { Rectangle adjustedBounds = base.ApplyBoundsConstraints(suggestedX, suggestedY, proposedWidth, proposedHeight); // SECREVIEW VSWhidbey 430541 - place security size restrictions in non public/protected function // to prevent custom IL from skipping restrictions in SetBoundsCore. if (IsRestrictedWindow && TopMost) { adjustedBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(adjustedBounds); } return adjustedBounds; } /// /// Summary of GetBaseDropDownBounds. /// // called by ToolStripDropDownMenu, internal Rectangle GetDropDownBounds(Rectangle suggestedBounds) { Rectangle dropDownBounds; if (TopLevel) { Point screenPoint = Point.Empty; if ((ownerItem != null) && (ownerItem is ToolStripDropDownItem)) { screenPoint = ((ToolStripDropDownItem)ownerItem).DropDownLocation; } else { screenPoint = suggestedBounds.Location; } Rectangle suggestedScreenBounds = new Rectangle(screenPoint, suggestedBounds.Size); if (WorkingAreaConstrained) { dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(suggestedScreenBounds); } else { dropDownBounds = WindowsFormsUtils.ConstrainToScreenBounds(suggestedScreenBounds); } } else { Point parentClientPoint = Point.Empty; if ((ownerItem != null) && (ownerItem is ToolStripDropDownItem) && (ParentInternal != null)) { parentClientPoint = ParentInternal.PointToClient(((ToolStripDropDownItem)ownerItem).DropDownLocation); } else { parentClientPoint = suggestedBounds.Location; } dropDownBounds = new Rectangle(parentClientPoint, suggestedBounds.Size); } Debug.WriteLineIf(DropDownDebugBounds.TraceVerbose, "DropDownBounds for " + suggestedBounds + "is" +dropDownBounds); return dropDownBounds; } internal Rectangle CalculateDropDownLocation(Point start, ToolStripDropDownDirection dropDownDirection) { Point offset = Point.Empty; if (!IsHandleCreated) { // PERF: // if the handle isnt created yet, then we likely havent performed layout // yet. force a layout here so that we get the correct size. LayoutTransaction.DoLayout(this, this, PropertyNames.PreferredSize); } Rectangle dropDownBounds = new Rectangle(Point.Empty, GetSuggestedSize()); // calculate the offset from the upper left hand corner of the item. switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: offset.X = - dropDownBounds.Width; offset.Y = - dropDownBounds.Height; break; case ToolStripDropDownDirection.AboveRight: offset.Y = - dropDownBounds.Height; break; case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Right: break; case ToolStripDropDownDirection.BelowLeft: case ToolStripDropDownDirection.Left: offset.X = - dropDownBounds.Width; break; } dropDownBounds.Location = new Point(start.X + offset.X, start.Y + offset.Y); if (WorkingAreaConstrained) { dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds); } return dropDownBounds; } internal Size GetSuggestedSize() { if (AutoSize) { return GetPreferredSize(Size.Empty); } return this.Size; } ////// Returns the ToolStrip from which all the dropdowns started from. This can be null. /// internal override ToolStrip GetToplevelOwnerToolStrip() { ToolStripDropDown topmost = GetFirstDropDown(); return (topmost.OwnerItem == null) ? null : topmost.OwnerToolStrip; } internal ToolStripItem GetToplevelOwnerItem() { ToolStripDropDown topmost = GetFirstDropDown(); return topmost.OwnerItem; } internal override void HandleItemClicked(ToolStripItem dismissingItem) { // post processing after the click has happened. SourceControlInternal = null; base.HandleItemClicked(dismissingItem); } ////// Set some common properties /// internal virtual void Initialize() { SetState(STATE_VISIBLE, false); SetTopLevelInternal(true); // VSWhidbey 82103 -- marking this as a modal form prevents it from being activated // by the IMsoComponentManager, which will break keyboard routing in VS. // SetState(STATE_MODAL, true); SetStyle(ControlStyles.ResizeRedraw, true); this.UpdateStyles(); this.GripStyle = ToolStripGripStyle.Hidden; this.CanOverflow = false; this.LayoutStyle = ToolStripLayoutStyle.Flow; this.MenuAutoExpand = true; this.AutoSize = true; } ////// /// Summary of OnLayout. /// /// protected virtual void OnClosed(ToolStripDropDownClosedEventArgs e){ if (IsHandleCreated) { if (ownerItem == null || !ownerItem.IsInDesignMode) { AccessibilityNotifyClients(AccessibleEvents.SystemMenuPopupEnd, -1); } } ToolStripDropDownClosedEventHandler handler = (ToolStripDropDownClosedEventHandler)Events[EventClosed]; if (handler != null) handler(this, e); } // SECREVIEW - for the "Cancel" to be honored, you must have AllWindowsPermission // i.e. ToolStripDropDown.IsRestrictedWindow MUST be false. // for more details see ToolStripDropDown.SetVisibleCore protected virtual void OnClosing(ToolStripDropDownClosingEventArgs e) { ToolStripDropDownClosingEventHandler handler = (ToolStripDropDownClosingEventHandler)Events[EventClosing]; if (handler != null) handler(this, e); } ////// /// When our handle is being created, suspend the deactivation /// portion of the WndProc, as we'll never be shown. /// protected override void OnHandleCreated(EventArgs e) { UpdateStyles(); // get rid of WS_CAPTION style base.OnHandleCreated(e); UpdateLayered(); // update transparency } protected override void OnItemClicked(ToolStripItemClickedEventArgs e) { try { base.OnItemClicked(e); } finally { ToolStripDropDownItem dismissingItem = e.ClickedItem as ToolStripDropDownItem; if (AutoClose) { if ((dismissingItem == null) // it's not a dropdownitem || (dismissingItem is ToolStripSplitButton && !dismissingItem.DropDown.Visible) // clicking on the split button button dismisses || !(dismissingItem.HasDropDownItems)) { // clicking on a item w/dropdown does not dismiss window Close(ToolStripDropDownCloseReason.ItemClicked); } } } } ///protected override void OnLayout(LayoutEventArgs e) { // VSWhidbey 480533 it's important to size the dropdown first, then layout so that // the layout engine and SetDisplayedItems know how big the container is. AdjustSize(); base.OnLayout(e); } protected virtual void OnOpening(CancelEventArgs e){ CancelEventHandler handler = (CancelEventHandler)Events[EventOpening]; if (handler != null) handler(this, e); } /// /// /// Summary of OnLayout. /// /// protected virtual void OnOpened(System.EventArgs e) { if (IsHandleCreated) { if (ownerItem == null || !ownerItem.IsInDesignMode) { AccessibilityNotifyClients(AccessibleEvents.SystemMenuPopupStart, -1); } } EventHandler handler = (EventHandler)Events[EventOpened]; if (handler != null) handler(this, e); } protected override void OnVisibleChanged(System.EventArgs e) { if (this.Location != this.displayLocation) { // If we adjusted the position from where the user wanted it, // see if we can put it in the right location now that they've changed // the items collection, and store where we actually have it. // Just because this is the case doesn't mean that we need to do another // another layout however. this.Location = this.displayLocation; this.displayLocation = this.Location; } if (AutoScroll || this.LayoutRequired) { // the base here forces a layout... we really only want to do this the first // time we pop the window... the subsequent times should be snappy. base.OnVisibleChanged(e); } else { this.SuspendLayout(); try { // scrollable control forces a layout here for scrollbar reasons only // since we toggle visibility a lot this is expensive. Let's be clever and // not do it. base.OnVisibleChanged(e); } finally { this.ResumeLayout(false); } } } ///protected override void OnParentChanged(System.EventArgs e) { base.OnParentChanged(e); Rectangle bounds = this.Bounds; SetBoundsCore(bounds.X, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.Location); } protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mea) { base.OnMouseUp(mea); Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.OnMouseUp] mouse up outside of the toolstrip - this should dismiss the entire chain"); //VSWhidbey 384068 Menus should dismiss when you drag off if (!ClientRectangle.Contains(mea.Location)) { bool dismiss = true; if (OwnerToolStrip != null && OwnerItem != null) { if (OwnerItem.Bounds.Contains(WindowsFormsUtils.TranslatePoint(mea.Location, this, OwnerToolStrip))) { dismiss = false; // dont dismiss if we clicked on our owner item } } if (dismiss) { DismissAll(); CancelAutoExpand(); } } } internal void OnOwnerItemFontChanged(EventArgs e) { if (this.IsAutoGenerated) { using (new LayoutTransaction(this, OwnerItem, PropertyNames.Font)) { OnFontChanged(e); } } } internal void SelectPreviousToolStrip() { // snap the owner item before calling hide as non-auto created dropdowns will // exit menu mode if there's no OwnerItem. ToolStripItem itemOnPreviousMenuToSelect = this.OwnerItem; this.Hide(); if (itemOnPreviousMenuToSelect != null) { itemOnPreviousMenuToSelect.Select(); if (OwnerToolStrip != null) { // make sure we send keyboard handling where we've just // sent selection if (!OwnerToolStrip.IsDropDown) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != OwnerToolStrip) { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(OwnerToolStrip); } // escape should cancel auto expansion OwnerToolStrip.MenuAutoExpand = false; } } } else { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.SelectPreviousToolStrip] No previous toolstrip to select - exiting menu mode."); ToolStripManager.ModalMenuFilter.ExitMenuMode(); } } /// /// this is where we handle navigation between the File,Edit,View dropdowns /// if you have one of these dropdowns showing and you hit the arrow key /// and it's not processed by the menu item /// internal override bool ProcessArrowKey(Keys keyCode) { Debug.WriteLineIf(ToolStrip.MenuAutoExpandDebug.TraceVerbose, "[ToolStripDropDown.ProcessArrowKey] MenuTimer.Cancel called"); ToolStripMenuItem.MenuTimer.Cancel(); if (keyCode == Keys.Left || keyCode == Keys.Right) { bool rightAligned = SystemInformation.RightAlignedMenus; bool forward = (keyCode == Keys.Left && rightAligned) || (keyCode == Keys.Right && !rightAligned); if (!IsFirstDropDown && !forward) { // this is the case where you've casecaded out to a second level dropdown and you hit the back arrow // key. In this case we want to just hide the current dropdown this.Visible = false; return true; } else { bool closeOnHorizontalKey = false; if (LayoutStyle == ToolStripLayoutStyle.Flow) { closeOnHorizontalKey = FlowLayout.GetFlowDirection(this) == FlowDirection.TopDown && !FlowLayout.GetWrapContents(this); } if (closeOnHorizontalKey) { ToolStrip toplevelToolStrip = GetToplevelOwnerToolStrip(); ToolStripItem rootItem = GetToplevelOwnerItem(); // This is the case where you need to open up the adjacent DropDown (File->Edit) menus because: // - this is the toplevel ToolStripDropDown and you hit left or right // - this is a non-toplevel ToolStripDropDown and you hit an arrow key in a direction // of the cascade AND the current item has no cascading menu associated with it. bool isOnOverflow = (OwnerItem != null && OwnerItem.IsOnOverflow); if (forward || !isOnOverflow) { DismissAll(); } else if (isOnOverflow) { // VSWhidbey 478068: going backwards should roll us up and our children but not the overflow. Visible = false; } if (toplevelToolStrip != null && rootItem != null) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != toplevelToolStrip) { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(toplevelToolStrip); } toplevelToolStrip.SelectNextToolStripItem(rootItem,forward); } return true; } } } // get base behavior like up/down navigation. return base.ProcessArrowKey(keyCode); } ///[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected override bool ProcessDialogKey(Keys keyData) { if (this.OwnerItem != null && this.OwnerItem.IsInDesignMode) { return false; } if (AutoClose && Visible) { if (ToolStripManager.IsMenuKey(keyData)) { SetCloseReason(ToolStripDropDownCloseReason.Keyboard); DismissAll(); ToolStrip toplevel = GetToplevelOwnerToolStrip(); if (toplevel != null) { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown ProcessDialogKey]: Got Menu Key, finding toplevel toolstrip, calling RestoreFocus."); toplevel.RestoreFocusInternal(); ToolStripManager.ModalMenuFilter.MenuKeyToggle = true; } ToolStripManager.ModalMenuFilter.ExitMenuMode(); return true; } else if ((keyData & Keys.KeyCode) == Keys.Escape) { SetCloseReason(ToolStripDropDownCloseReason.Keyboard); SelectPreviousToolStrip(); return true; } } return base.ProcessDialogKey(keyData); } [EditorBrowsable(EditorBrowsableState.Advanced)] [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected override bool ProcessDialogChar(char charCode) { #if DEBUG Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "ToolStripDropDown.ProcessDialogChar [" + charCode.ToString() + "]"); #endif // since we're toplevel and arent a container control, we've got to do our own mnemonic handling. // if ((OwnerItem == null || OwnerItem.Pressed) && charCode != ' ') { if (ProcessMnemonic(charCode)){ return true; } } return base.ProcessDialogChar(charCode); } [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected internal override bool ProcessMnemonic(char charCode) { if (!CanProcessMnemonic()) { return false; // here for security see CanProcessMnemonic. } return base.ProcessMnemonic(charCode); } internal override void ProcessDuplicateMnemonic(ToolStripItem item, char charCode) { if (!CanProcessMnemonic()) { return; // here for security see CanProcessMnemonic. } if (item != null) { // SECREVIEW // We want to make sure that Mnemonics arent another way of getting keyboard // input. Allowing double mnemonics to switch selection could effectively let you // figure out what someone was typing into the window by checking the selected state // of all of your items. Instead of switching selection, we'll just perform the click. // ===> Assumes ToolStripItem.ProcessMnemonic is protected by AWP if (IsRestrictedWindow) { item.ProcessMnemonic(charCode); // execute the first click } else { base.ProcessDuplicateMnemonic(item,charCode); } } } internal override void RecreateHandleCore() { // If we're visible, then we'll have set our parent hwnd to the active control. // That means that re-create handle will set it as our parent, but that's not what // we want, since that means that from now on we'll be displayed in that controls // client co-ordinates. To fix this, we first re-parent ourselves back to the // hidden window, do the re-create, then set the parent again. if (Visible) { ReparentToDropDownOwnerWindow(); } base.RecreateHandleCore(); if (Visible) { ReparentToActiveToolStripWindow(); } } private void ResetDropShadowEnabled() { DropShadowEnabled = true; } private void ReparentToActiveToolStripWindow() { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this); UnsafeNativeMethods.SetWindowLong(new HandleRef(this, Handle), NativeMethods.GWL_HWNDPARENT, ToolStripManager.ModalMenuFilter.ActiveHwnd); } private void ReparentToDropDownOwnerWindow() { // when we're toplevel we need to parent ourselves to a hidden window // this prevents a taskbar entry. NativeWindow ownerWindow = DropDownOwnerWindow; HandleRef ownerHandle = new HandleRef(ownerWindow, ownerWindow.Handle); UnsafeNativeMethods.SetWindowLong(new HandleRef(this, Handle), NativeMethods.GWL_HWNDPARENT, ownerHandle); } /// /// VERY similar to Form.ScaleCore /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void ScaleCore(float dx, float dy) { Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, GetType().Name + "::ScaleCore(" + dx + ", " + dy + ")"); SuspendLayout(); try { //Get size values in advance to prevent one change from affecting another. Size clientSize = ClientSize; Size minSize = MinimumSize; Size maxSize = MaximumSize; ClientSize = ScaleSize(clientSize, dx, dy); if (!MinimumSize.IsEmpty) { MinimumSize = ScaleSize(minSize, dx, dy); } if (!MaximumSize.IsEmpty) { MaximumSize = ScaleSize(maxSize, dx, dy); } ScaleDockPadding(dx, dy); foreach(Control control in Controls) { if (control != null) { #pragma warning disable 618 control.Scale(dx, dy); #pragma warning restore 618 } } } finally { ResumeLayout(); } } ////// /// Scale this form. Form overrides this to enforce a maximum / minimum size. /// protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); Size minSize = MinimumSize; Size maxSize = MaximumSize; if (!MinimumSize.IsEmpty) { MinimumSize = ScaleSize(minSize, factor.Width, factor.Height); } if (!MaximumSize.IsEmpty) { MaximumSize = ScaleSize(maxSize, factor.Width, factor.Height); } } ////// This is called when the ToolStripDropDownItem sets the DropDown property using CreateDefaultDropDown. /// In this case, the IsAutoGenerated should return true. /// internal void SetAutoGeneratedInternal(bool autoGenerated) { this.isAutoGenerated = autoGenerated; } ////// /// [....] sizes with the ToolStripDropDown /// protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) { Rectangle bounds = new Rectangle(x, y, width, height); bounds = GetDropDownBounds(bounds); base.SetBoundsCore(bounds.X, bounds.Y, bounds.Width, bounds.Height, specified); } private void SetTopLevelStyle(bool value) { if (IsHandleCreated) { // We need to swap they style bits on the window handle // we could recreate the handle, but that seems rather expensive. int styleFlags = WindowStyle; if (value) { // setting toplevel = true styleFlags &= ~NativeMethods.WS_CHILD; styleFlags |= NativeMethods.WS_POPUP; } else { // this is a child window styleFlags &= ~NativeMethods.WS_POPUP; styleFlags |= NativeMethods.WS_CHILD; } WindowStyle = styleFlags; } } ////// /// Summary of SetVisibleCore. /// /// protected override void SetVisibleCore(bool visible) { if (state[stateInSetVisibleCore]) { return; } state[stateInSetVisibleCore] = true; try { if (visible) { if (LayoutRequired) { LayoutTransaction.DoLayout(this, this, PropertyNames.Visible); } bool openingEventCancelled = true; // assume that it's been cancelled so that if we throw we do nothing. try { // VSWhidbey 313920 - add opening event. // Snap the foreground window BEFORE calling any user events so they dont have a // chance to activate something else. This covers the case where someone handles the // opening event and throws up a messagebox. IntPtr foregroundWindow = UnsafeNativeMethods.GetForegroundWindow(); // Fire Opening event // Cancellable event in which default value of e.Cancel depends on the number of displayed items >0. // CancelEventArgs openEventArgs = new CancelEventArgs(/*cancel=*/(DisplayedItems.Count == 0)); OnOpening(openEventArgs); openingEventCancelled = openEventArgs.Cancel; if (!openingEventCancelled) { // do the actual work to open the window. if (TopLevel) { ReparentToActiveToolStripWindow(); } // review: what is this used for? if (OwnerToolStrip != null) { OwnerToolStrip.ActiveDropDowns.Add(this); // the act of showing this window can cause a spurious mouse move // in the parent, make sure it retains where the mouse really was. OwnerToolStrip.SnapMouseLocation(); // VSWhidbey 458967: make sure that mouse capture // transitions between the owner and dropdown. if (OwnerToolStrip.CaptureInternal) { CaptureInternal = true; } } base.SetVisibleCore(visible); if (TopLevel){ ApplyTopMost(true); } else if (IsHandleCreated && SafeNativeMethods.IsWindowEnabled(new HandleRef(this, Handle))) { SafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOACTIVATE); } } } finally { // Fire Opened event // fire the opened event only if we actually opened the control. // if (!openingEventCancelled) { OnOpened(new EventArgs()); } } } else { if (GetVisibleCore()) { ToolStripDropDownCloseReason reason = closeReason; ResetCloseReason(); ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs(reason); // Fire Closing Event // Cancel is prepopulated based on AutoClose feature. // if (e.CloseReason != ToolStripDropDownCloseReason.CloseCalled) { e.Cancel = !AutoClose; } else { e.Cancel = false; } try { OnClosing(e); } finally { // SECREVIEW - When IsRestrictedWindow is true, you cannot cancel the closing of the ToolStripDropDown. // You can set AutoClose = false and OnClosing(e.Cancel=true), but we will ignore it. if (!e.Cancel || IsRestrictedWindow /*delay evaluate only in the case we need it*/) { // setting to not visible. Dismiss our child drop downs, reset, set ourselves visible false. DismissActiveDropDowns(); // if this came through via a click event we should actually // dismiss everyone in the chain. Other windows will recieve a // close, closing event with reason AppFocusChange. This is by // design since the item wasnt clicked on that window. if (reason == ToolStripDropDownCloseReason.ItemClicked) { DismissAll(); // make sure that when we roll up, our owner item's selection is cleared. ToolStripItem rootOwnerItem = GetToplevelOwnerItem(); if (rootOwnerItem != null) { rootOwnerItem.Unselect(); } // VSWhidbey 480392: make sure we cancel auto expansion on the root CancelAutoExpand(); ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose,"[ToolStripDropDown.SetVisibleCore] Exiting menu mode because item clicked"); ToolStripManager.ModalMenuFilter.ExitMenuMode(); } else { ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); } // snap our bounds, we'll need it for some invalidation later. Rectangle bounds = this.Bounds; try { base.SetVisibleCore(visible); } finally { // remove ourselves from the active dropdown list. if (OwnerToolStrip != null) { OwnerToolStrip.ActiveDropDowns.Remove(this); } ActiveDropDowns.Clear(); // VSWhidbey 389244: if the user traps the click event and starts // pumping their own messages by calling Application.DoEvents, we // should release mouse capture. if (CaptureInternal) { CaptureInternal = false; } } // Fire OnClosed. // if you make VisibleChanged throw you dont get closed. Sorry. ToolStripDropDownClosedEventArgs closedEventArgs = new ToolStripDropDownClosedEventArgs(reason); OnClosed(closedEventArgs); if (TopLevel && (!IsDisposed || !Disposing)) { // Parent back up to our DropDownOwnerWindow. ReparentToDropDownOwnerWindow(); } if (reason != ToolStripDropDownCloseReason.ItemClicked) { // VSWhidbey 475650: If we're not about to fire a Click event, reset SourceControl. SourceControlInternal = null; } // Making ourselves look presentable: // We may be about to invoke a click event here... // if we're the topmost dropdown then invalidate our // intersection with the toplevel toolstrip if (!DesignMode && IsFirstDropDown && OwnerItem != null && TopLevel) { ToolStrip toolStrip = GetToplevelOwnerToolStrip(); if (toolStrip != null && !(toolStrip.IsDisposed || toolStrip.Disposing)) { // translate the bounds (already in screen coords) to toolstrip. bounds.Location = toolStrip.PointToClient(bounds.Location); // find the intersection with the client and use that to invalidate bounds.Intersect(toolStrip.ClientRectangle); if (bounds.Width > 0 && bounds.Height >0) { toolStrip.Invalidate(bounds); toolStrip.Update(); } } } } } } else { ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); } } } finally { state[stateInSetVisibleCore] = false; } } private bool ShouldSerializeDefaultDropDownDirection() { return (childDropDownDirection != ToolStripDropDownDirection.Default); } ////// Updates the layered window attributes if the control /// is in layered mode. /// private void UpdateLayered() { if (state[stateLayered] && IsHandleCreated && TopLevel && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { bool result; result = UnsafeNativeMethods.SetLayeredWindowAttributes(new HandleRef(this, Handle), 0, OpacityAsByte, NativeMethods.LWA_ALPHA); if (!result) { throw new Win32Exception(); } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new void Show() { // don't set displayLocation here, since all the other Show methods call this. base.Show(); } ////// show relative to control coordinates public void Show(Control control, Point position) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; // VSWhidbey 310328 - when we have no owner item and we're set to RTL.Inherit, translate the coordinates // so that the menu looks like it's swooping from the other side if (this.OwnerItem == null && control.RightToLeft == RightToLeft.Yes) { AdjustSize(); position.Offset(control.IsMirrored ? Width : -Width, 0); } this.displayLocation = control.PointToScreen(position); this.Location = this.displayLocation; ShowCore(); } public void Show(Control control, Point position, ToolStripDropDownDirection direction) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; this.displayLocation = CalculateDropDownLocation(control.PointToScreen(position), direction).Location; this.Location = this.displayLocation; ShowCore(); } ////// show relative to control coordinates public void Show(Control control, int x, int y) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; Show(control, new Point(x,y)); } ////// show relative to screen coordinates public void Show(Point screenLocation) { this.displayLocation = screenLocation; this.Location = this.displayLocation; ShowCore(); } public void Show(Point position, ToolStripDropDownDirection direction) { this.displayLocation = CalculateDropDownLocation(position, direction).Location; this.Location = this.displayLocation; ShowCore(); } ////// show relative to screen coordinates public void Show(int x, int y) { this.displayLocation = new Point(x,y); this.Location = this.displayLocation; ShowCore(); } private void ShowCore() { Show(); } private bool ShouldSerializeDropShadowEnabled() { return dropShadowEnabled == false; } internal override bool ShouldSerializeLayoutStyle() { return LayoutStyle != ToolStripLayoutStyle.VerticalStackWithOverflow; } internal void UnassignDropDownItem() { Debug.Assert(countDropDownItemsAssignedTo > 0, "dropdown assignment underflow"); countDropDownItemsAssignedTo = Math.Max(--countDropDownItemsAssignedTo, 0); } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref Message m) { if (m.Msg >= NativeMethods.WM_KEYFIRST && m.Msg <= NativeMethods.WM_KEYLAST && IsRestrictedWindow) { // SECREVIEW: // To Receive a OnKey* event, the ToolStripDropDown must have AllWindows permission // directly calling DefWndProc will prevent these events from executing. // All PreProcess keyboard messages are protected by link demands. // NOTE the same kind of fix needs to go into ToolStripScrollButton.StickyLabel (the only alloewed ControlHost) DefWndProc(ref m); return; } switch (m.Msg) { case NativeMethods.WM_NCACTIVATE: // if someone clicks on a child control of the toolstrip dropdown, we want // the title bar to continue appearing active. Normally we just show without // taking window activation (ShowWindow(SHOWNOACTIVATE)) but we cant stop // child controls from taking focus. WmNCActivate(ref m); return; case NativeMethods.WM_ACTIVATE: // This is the Chrome Panel collection editor scenario // we had focus, then the Chrome panel was activated and we never went away // when we get focus again, we should reactivate our message filter. Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.WndProc] got a WM_ACTIVATE " + (((int)m.WParam == NativeMethods.WA_ACTIVE) ? "WA_ACTIVE" : "WA_INACTIVE") + " - checkin if we need to set the active toolstrip"); if((int)m.WParam == NativeMethods.WA_ACTIVE) { if (this.Visible) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != this) { // if we were inactive and now we are, we should enter menu mode ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this); } } else { Debug.Fail("Why are we being activated when we're not visible? Deactivating thingee is " + WindowsFormsUtils.GetControlInformation(m.LParam)); } } else { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.WndProc] activating thingee is " + WindowsFormsUtils.GetControlInformation(m.LParam)); } base.WndProc(ref m); return; /* case NativeMethods.WM_SYSKEYUP: Keys keyData = (Keys)(int)m.WParam; base.WndProc(ref m); // VSW 423760: handle the case where the ALT key has been pressed down while a dropdown // was open. We need to clear off the MenuKeyToggle so the next ALT will activate // the menu. if (IsMenuKey(keyData)) { ToolStrip toplevel = GetToplevelOwnerToolStrip(); if (toplevel != null && toplevel.MenuKeyToggle) { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown WM_SYSKEYUP]: Got Menu Key, restoring MenuKeyToggle."); toplevel.MenuKeyToggle = false; } } return;*/ default: base.WndProc(ref m); return; } } #region DropDownSpecific internal void DismissAll() { ToolStripDropDown toplevel = this.GetFirstDropDown(); toplevel.DismissActiveDropDowns(); toplevel.Visible = false; } private void DismissActiveDropDowns() { Debug.WriteLineIf((DropDownActivateDebug.TraceVerbose && ActiveDropDowns.Count > 0), "Dismiss children called - COUNT " + ActiveDropDowns.Count + " \r\n" + new StackTrace().ToString()); int count = ActiveDropDowns.Count; if (count == 1) { // this is the most common case ToolStripDropDown dropDown = ActiveDropDowns[0] as ToolStripDropDown; if (dropDown != null) { dropDown.Visible = false; } } else { ArrayList dropDowns = ActiveDropDowns.Clone() as ArrayList; // We cant iterate through the active dropdown collection // here as changing visibility changes the collection. for (int i = 0; i < dropDowns.Count; i++) { ToolStripDropDown dropDown = dropDowns[i] as ToolStripDropDown; if (dropDown != null) { dropDown.Visible = false; } } } } #region WMNCACTIVATE private bool sendingActivateMessage = false; // WmNcActivate // if someone clicks on a child control of the toolstrip dropdown, we want // the title bar to continue appearing active. Normally we just show without // taking window activation (ShowWindow(SHOWNOACTIVATE)) but we cant stop // child controls from taking focus. private void WmNCActivate(ref Message m) { if (m.WParam != IntPtr.Zero /*activating*/) { if (!sendingActivateMessage) { sendingActivateMessage = true; try { Debug.WriteLineIf(DropDownActivateDebug.TraceVerbose, "Sending WM_NCACTIVATE to toplevel hwnd" + ToolStripManager.ModalMenuFilter.ActiveHwnd); // we're activating - notify the previous guy that we're activating. HandleRef activeHwndHandleRef = ToolStripManager.ModalMenuFilter.ActiveHwnd; UnsafeNativeMethods.SendMessage(activeHwndHandleRef, NativeMethods.WM_NCACTIVATE, (IntPtr)1, NativeMethods.InvalidIntPtr); SafeNativeMethods.RedrawWindow(activeHwndHandleRef, null, NativeMethods.NullHandleRef, NativeMethods.RDW_FRAME | NativeMethods.RDW_INVALIDATE); m.WParam = (IntPtr)1; } finally { sendingActivateMessage = false; } } DefWndProc(ref m); return; } else { base.WndProc(ref m); } } #endregion ////// Determines if this is the first dropDown in the dropDown chain /// internal bool IsFirstDropDown { get { return ((OwnerToolStrip as ToolStripDropDown) == null); } } ////// returns the root dropdown in the chain. /// internal ToolStripDropDown GetFirstDropDown() { ToolStripDropDown topmost = this; // walk back up the chain of windows to get the topmost ToolStripDropDown ownerDropDown = topmost.OwnerToolStrip as ToolStripDropDown; while (ownerDropDown != null) { topmost = ownerDropDown; ownerDropDown = topmost.OwnerToolStrip as ToolStripDropDown; } return topmost; } internal static ToolStripDropDown GetFirstDropDown(ToolStrip start) { Debug.Assert(start != null, "Who is passing null to GetFirstDropDown?"); if ((start == null) || (!start.IsDropDown)) { return null; } ToolStripDropDown startDropDown = (start as ToolStripDropDown); return startDropDown.GetFirstDropDown(); } #endregion DropDownSpecific ///[System.Runtime.InteropServices.ComVisible(true)] public class ToolStripDropDownAccessibleObject : ToolStripAccessibleObject { private ToolStripDropDown owner; /// public ToolStripDropDownAccessibleObject(ToolStripDropDown owner) : base(owner) { this.owner = owner; } public override string Name { get { // Special case: If an explicit name has been set in the AccessibleName property, use that. // Note: Any non-null value in AccessibleName overrides the default accessible name logic, // even an empty string (this is the only way to *force* the accessible name to be blank). string name = owner.AccessibleName; if (name != null) { return name; } // NOT localized for testing purposes. Localizers can use AccessibleName. name = "DropDown"; if (owner.OwnerItem != null && owner.OwnerItem.AccessibilityObject.Name != null) { name = owner.OwnerItem.AccessibilityObject.Name + name; } return name; } set { // If anyone tries to set the accessible name, just cache the value in the control's // AccessibleName property. This value will then end up overriding the normal accessible // name logic, until such time as AccessibleName is set back to null. owner.AccessibleName = value; } } public override AccessibleRole Role { get { AccessibleRole role = Owner.AccessibleRole; if (role != AccessibleRole.Default) { return role; } return AccessibleRole.MenuPopup; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Security; using System.Security.Permissions; using System.Windows.Forms; using System.Windows.Forms.Layout; using System.Runtime.InteropServices; using System.Collections.Specialized; using System.Collections.Generic; using System.Globalization; ////// /// Summary of ToolStripDropDown. /// [Designer("System.Windows.Forms.Design.ToolStripDropDownDesigner, " + AssemblyRef.SystemDesign)] [ComVisible(true)] [ClassInterface(ClassInterfaceType.AutoDispatch)] public class ToolStripDropDown : ToolStrip { private ToolStripItem ownerItem = null; private bool isAutoGenerated = false; private Point dropDownLocation = Point.Empty; private bool dropShadowEnabled = true; private bool autoClose = true; private bool autoSize = true; private int countDropDownItemsAssignedTo = 0; // the number of dropdown items using this as their dropdown.. private BitVector32 state = new BitVector32(); private Point displayLocation = new Point(0,0); private ToolStripDropDownDirection childDropDownDirection = ToolStripDropDownDirection.Default; private ToolStripDropDownCloseReason closeReason = ToolStripDropDownCloseReason.AppFocusChange; private static readonly int PropOpacity = PropertyStore.CreateKey(); private static readonly int PropDDRightToLeft = PropertyStore.CreateKey(); private static readonly int PropSourceControl = PropertyStore.CreateKey(); private static readonly object EventOpening = new object(); private static readonly object EventOpened = new object(); private static readonly object EventClosed = new object(); private static readonly object EventClosing = new object(); private static readonly object ToolStripParkingWindowKey = new object(); #if DEBUG internal static TraceSwitch DropDownActivateDebug = new TraceSwitch("DropDownActivateDebug", "Debug activation code for dropDown controls"); internal static TraceSwitch DropDownDebugBounds = new TraceSwitch("DropDownDebugBounds", "Debug GetDropDownBounds"); static readonly BooleanSwitch AlwaysRestrictWindows = new BooleanSwitch("AlwaysRestrictWindows", "Always make Form classes behave as though they are restricted"); #else internal static TraceSwitch DropDownActivateDebug; internal static TraceSwitch DropDownDebugBounds; #endif private static readonly int stateLayered = BitVector32.CreateMask(); private static readonly int stateAllowTransparency = BitVector32.CreateMask(stateLayered); private static readonly int stateIsRestrictedWindow = BitVector32.CreateMask(stateAllowTransparency); private static readonly int stateIsRestrictedWindowChecked = BitVector32.CreateMask(stateIsRestrictedWindow); private static readonly int stateNotWorkingAreaConstrained = BitVector32.CreateMask(stateIsRestrictedWindowChecked); private static readonly int stateInSetVisibleCore = BitVector32.CreateMask(stateNotWorkingAreaConstrained); /// SECREVIEW /// ToolStripDropDown security notes /// Key ideas: /// AllWindowsPermission is required to get keystrokes, obscure the taskbar, prevent the dropdown from closing. /// /// A. Disallow ControlHost items, both shipped and user created via UiPermission.AWP. We'd simply not display these items in the internet / dropdown case. /// B. Disallow AutoClose == false and ignore cancelable closing event param. This makes it impossible to enter more than one keystroke and not cause dropdown dismissal. /// C. Restrict keystroke handling events. We would route WM_KKEY* to DefWndProc, and because Control.WndProc would be skipped, the following events would not be raised: /// On/KeyUp/On/KeyDown/On/KeyPress /// D. Ensure proper link and inheritancedemands on /// ProcessKeyPreview/ProcessDialogKey/ProcessCmdKey/ProcessKeyMessage/PreProcessMessage/WndProc /// E. Ensure proper inheritance demands on /// IsInputKey/IsInputChar /// F. Prevent double mnemonic evaluation on DropDowns (another way of getting keyboard input by having hidden items) /// Protect ProcessMnemonic. ////// /// Summary of ToolStripDropDown. /// public ToolStripDropDown() { // SECURITY NOTE: The IsRestrictedWindow check is done once and cached. We force it to happen here // since we want to ensure the check is done on the code that constructs the ToolStripDropDown. bool temp = IsRestrictedWindow; this.SuspendLayout(); Initialize(); this.ResumeLayout(false); } ////// /// Summary of ToolStripDropDown. /// /// internal ToolStripDropDown(ToolStripItem ownerItem): this() { this.ownerItem = ownerItem; } internal ToolStripDropDown(ToolStripItem ownerItem, bool isAutoGenerated) : this(ownerItem) { this.isAutoGenerated = isAutoGenerated; } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool AllowItemReorder { get { return base.AllowItemReorder; } set { base.AllowItemReorder = value; } } ////// /// /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.ControlAllowTransparencyDescr) ] public bool AllowTransparency { get { return state[stateAllowTransparency]; } set { if (value != (state[stateAllowTransparency]) && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { state[stateAllowTransparency] = value; state[stateLayered] = state[stateAllowTransparency]; UpdateStyles(); if (!value) { if (Properties.ContainsObject(PropOpacity)) { Properties.SetObject(PropOpacity, (object)1.0f); } UpdateLayered(); } } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override AnchorStyles Anchor { get { return base.Anchor; } set { base.Anchor = value; } } ////// Gets or sets /// a value indicating whether the opacity of the form can be /// adjusted. ///[DefaultValue(true)] public override bool AutoSize { get { return autoSize; } set { if (autoSize != value) { autoSize = value; // we shadow CommonProperties LayoutTransaction.DoLayout(this,this,PropertyNames.AutoSize); OnAutoSizeChanged(EventArgs.Empty); } } } /// /// /// specifies whether the dropdown should automatically close when the dropdown has lost /// activation. If you want a dropdown that always stays open, specify AutoClose = false; /// [ DefaultValue(true), SRCategory(SR.CatBehavior), SRDescription(SR.ToolStripDropDownAutoCloseDescr) ] public bool AutoClose { get { return autoClose; } set { // SECREVIEW - to be honored, you must have AllWindowsPermission. See SetVisibleCore if (autoClose != value) { autoClose = value; ApplyTopMost(/*topMost=*/!autoClose); } } } [Browsable(false)] public new event EventHandler BackgroundImageChanged { add { base.BackgroundImageChanged += value; } remove { base.BackgroundImageChanged -= value; } } [Browsable(false)] public new event EventHandler BackgroundImageLayoutChanged { add { base.BackgroundImageLayoutChanged += value; } remove { base.BackgroundImageLayoutChanged -= value; } } [Browsable(false)] public new event EventHandler BindingContextChanged { add { base.BindingContextChanged += value; } remove { base.BindingContextChanged -= value; } } ///[DefaultValue(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool CanOverflow { get { return base.CanOverflow; } set { base.CanOverflow = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event UICuesEventHandler ChangeUICues { add { base.ChangeUICues += value; } remove { base.ChangeUICues -= value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new ContextMenu ContextMenu { get { return base.ContextMenu; } set { base.ContextMenu = value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new event EventHandler ContextMenuChanged { add { base.ContextMenuChanged += value; } remove { base.ContextMenuChanged -= value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public new ContextMenuStrip ContextMenuStrip { get { return base.ContextMenuStrip; } set { base.ContextMenuStrip = value; } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler ContextMenuStripChanged { add { base.ContextMenuStripChanged += value; } remove { base.ContextMenuStripChanged -= value; } } /// /// /// /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] get { CreateParams cp = base.CreateParams; // If we're using themes then go ahead if (DropShadowEnabled) { cp.ClassStyle |= NativeMethods.CS_DROPSHADOW; } // we're a borderless menuless control with no min/max boxes // we dont want to show in the taskbar either //Q205158 HOWTO: Prevent a Window from Appearing on the Taskbar //Give the window the WS_EX_TOOLWINDOW extended style, and remove the WS_EX_APPWINDOW style. As a side effect, the window will have a smaller caption than a normal window. //Give the window the WS_POPUP style and make it owned by a hidden window. (Form) cp.Style &= ~(NativeMethods.WS_CAPTION | NativeMethods.WS_CLIPSIBLINGS); /* no caption, no siblings */ cp.ExStyle &= ~(NativeMethods.WS_EX_APPWINDOW); /* show in taskbar = false */ // | NativeMethods.WS_EX_TOOLWINDOW cp.Style |= (TopLevel) ? NativeMethods.WS_POPUP : NativeMethods.WS_CHILD; cp.ExStyle |= (NativeMethods.WS_EX_CONTROLPARENT); /* show in taskbar = false */ bool topLevel = TopLevel; // opacity if (topLevel && (state[stateLayered])) { cp.ExStyle |= NativeMethods.WS_EX_LAYERED; } else if (topLevel) { //From MSDN: Menus, dialog boxes, and combo list boxes have the CS_SAVEBITS style. When you use this style for a window, //Windows saves a bitmap copy of the screen image that the window obscures. First, Windows asks the display driver to save the bits. //If the display driver has enough memory, it saves the bits for Windows. If the display driver does not have enough memory, Window //saves the bits itself as a bitmap in global memory and also uses some of User's local heap for housekeeping structures for each window. //When the application removes the window, Windows can restore the screen image quickly by using the stored bits. cp.ClassStyle |= NativeMethods.CS_SAVEBITS; } else if (!topLevel) { cp.Style |= NativeMethods.WS_CLIPSIBLINGS; } // We're turning off CLIPSIBLINGS because in the designer the elements of the form beneath // are actually sibling controls. We want to paint right over them as if we were a toplevel window. return cp; } } ////// This is called when creating a window. Inheriting classes can overide /// this to add extra functionality, but should not forget to first call /// base.CreateParams() to make sure the control continues to work /// correctly. /// ///protected override Padding DefaultPadding { get { return new Padding(1, 2, 1, 2); } } /// We want this to default to true... This way tooltips on overflows and custom dropdowns will show. /// Since menu items don't show tooltips by default we can savely leave it on protected override bool DefaultShowItemToolTips { get { return true; } } protected override DockStyle DefaultDock { get { return DockStyle.None; } } public override ToolStripDropDownDirection DefaultDropDownDirection { get { if (childDropDownDirection == ToolStripDropDownDirection.Default) { return (RightToLeft == RightToLeft.Yes)? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; } return childDropDownDirection; } set { childDropDownDirection = value; base.DefaultDropDownDirection = value; } } ///[ DefaultValue(DockStyle.None), Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public override DockStyle Dock { get { return base.Dock; } set{ base.Dock = value; } } /// changed the browsable attribute [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler DockChanged { add { base.DockChanged += value; } remove { base.DockChanged -= value; } } /// /// Returns an owner window that can be used to /// own a drop down. /// internal override NativeWindow DropDownOwnerWindow { get { // Re-use the drop down owner from our parenting // tool strip if we can. if (ownerItem != null && ownerItem.Owner != null) { return ownerItem.Owner.DropDownOwnerWindow; } return base.DropDownOwnerWindow; } } ///public bool DropShadowEnabled { get { // VSWhidbey 338272 - DropShadows are only supported on TopMost windows // due to the flakeyness of the way it's implemented in the OS. (Non toplevel // windows can have parts of the shadow disappear because another window can get // sandwiched between the SysShadow window and the dropdown.) return dropShadowEnabled && TopMost && DisplayInformation.IsDropShadowEnabled; } set { if (dropShadowEnabled != value) { dropShadowEnabled = value; if (IsHandleCreated && !DesignMode) { RecreateHandle(); } } } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosedDecr)] public event ToolStripDropDownClosedEventHandler Closed { add { Events.AddHandler(EventClosed, value); } remove { Events.RemoveHandler(EventClosed, value); } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownClosingDecr)] public event ToolStripDropDownClosingEventHandler Closing { add { Events.AddHandler(EventClosing, value); } remove { Events.RemoveHandler(EventClosing, value); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler Enter { add { base.Enter += value; } remove { base.Enter -= value; } } public override Font Font { get { if (this.IsFontSet()) { return base.Font; } // if the FONT isnt set, then return our owner item's font. if (IsAutoGenerated && OwnerItem != null) { return OwnerItem.Font; } return base.Font; } set { base.Font = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler FontChanged { add { base.FontChanged += value; } remove { base.FontChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler ForeColorChanged { add { base.ForeColorChanged += value; } remove { base.ForeColorChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event GiveFeedbackEventHandler GiveFeedback { add { base.GiveFeedback += value; } remove { base.GiveFeedback -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripGripDisplayStyle GripDisplayStyle { get { return base.GripDisplayStyle; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new Rectangle GripRectangle { get { return base.GripRectangle; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new Padding GripMargin{ get { return base.GripMargin; } set { base.GripMargin = value; } } /// [DefaultValue(ToolStripGripStyle.Hidden), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripGripStyle GripStyle { get { return base.GripStyle; } set { base.GripStyle = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] //Everett new public event HelpEventHandler HelpRequested { add { base.HelpRequested += value; } remove { base.HelpRequested -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler ImeModeChanged { add { base.ImeModeChanged += value; } remove { base.ImeModeChanged -= value; } } /// /// /// determines whether this dropdown was autogenerated. /// [Browsable(false)] public bool IsAutoGenerated { get { return isAutoGenerated; } } internal bool IsAssignedToDropDownItem { get { return IsAutoGenerated || (countDropDownItemsAssignedTo > 0); } } ////// /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] internal bool IsRestrictedWindow { get { /// SECREVIEW: make sure to keep changes here in [....] with Form.IsRestrictedWindow if (!state[stateIsRestrictedWindowChecked]) { state[stateIsRestrictedWindowChecked] = true; state[stateIsRestrictedWindow] = false; Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Checking for restricted window..."); Debug.Indent(); #if DEBUG if (AlwaysRestrictWindows.Enabled) { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Always restricted switch is on..."); state[stateIsRestrictedWindow] = true; Debug.Unindent(); return true; } #endif try { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "WindowAdornmentModification Demanded"); IntSecurity.WindowAdornmentModification.Demand(); } catch { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "Caught exception, we are restricted..."); state[stateIsRestrictedWindow] = true; } Debug.Unindent(); } return state[stateIsRestrictedWindow]; } } internal override Size ImageScalingSizeInternal { get { if (IsAutoGenerated && OwnerToolStrip != null) { return OwnerToolStrip.ImageScalingSizeInternal; } return base.ImageScalingSizeInternal; } set { base.ImageScalingSizeInternal = value; } } internal override bool KeyboardActive { get { // ripple up the chain until we get the topmost toolstrip (usually the main menu strip is the one we care about) ToolStrip ownerToolStrip = OwnerToolStrip; if (ownerToolStrip != null) { return ownerToolStrip.KeyboardActive; } return base.KeyboardActive; } set { base.KeyboardActive = value; // ripple up the chain until we get the topmost toolstrip (usually the main menu strip is the one we care about) ToolStrip ownerToolStrip = OwnerToolStrip; if (ownerToolStrip != null) { ownerToolStrip.KeyboardActive = value; } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyEventHandler KeyDown { add { base.KeyDown += value; } remove { base.KeyDown -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyPressEventHandler KeyPress { add { base.KeyPress += value; } remove { base.KeyPress -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event KeyEventHandler KeyUp { add { base.KeyUp += value; } remove { base.KeyUp -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler Leave { add { base.Leave += value; } remove { base.Leave -= value; } } ///Determines if this form should display a warning banner /// when the form is displayed in an unsecure mode. ////// Override Location to make it hidden from the user in the designer /// [ EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false) ] public new Point Location { get { return base.Location; } set { base.Location = value; } } [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpeningDescr)] public event CancelEventHandler Opening { add { Events.AddHandler(EventOpening, value); } remove { Events.RemoveHandler(EventOpening, value); } } ////// /// [SRCategory(SR.CatAction), SRDescription(SR.ToolStripDropDownOpenedDescr)] public event EventHandler Opened { add { Events.AddHandler(EventOpened, value); } remove { Events.RemoveHandler(EventOpened, value); } } ///Occurs when the control is clicked. ///protected internal override Size MaxItemSize { get { return Screen.GetWorkingArea(this.Bounds).Size - this.Padding.Size; } } /// /// /// Determines the opacity of the form. This can only be set on top level /// controls. Opacity requires Windows 2000 or later, and is ignored on earlier /// operating systems. /// [ SRCategory(SR.CatWindowStyle), TypeConverterAttribute(typeof(OpacityConverter)), SRDescription(SR.FormOpacityDescr), DefaultValue(1.0), Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced) ] public double Opacity { get { object opacity = Properties.GetObject(PropOpacity); if (opacity != null) { return Convert.ToDouble(opacity, CultureInfo.InvariantCulture); } else { return 1.0f; } } set { if (IsRestrictedWindow) { value = Math.Max(value, .50f); } if (value > 1.0) { value = 1.0f; } else if (value < 0.0) { value = 0.0f; } Properties.SetObject(PropOpacity, value); bool oldLayered = (state[stateLayered]); if (OpacityAsByte < 255 && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { AllowTransparency = true; state[stateLayered] = true; } else { state[stateLayered] = false; } if (oldLayered != (state[stateLayered])) { UpdateStyles(); } UpdateLayered(); } } private byte OpacityAsByte { get { return (byte)(Opacity * 255.0f); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new ToolStripOverflowButton OverflowButton { get { return base.OverflowButton; } } ////// /// Summary of OwnerItem. /// [DefaultValue(null), Browsable(false)] public ToolStripItem OwnerItem { get { return ownerItem; } set { if (ownerItem != value) { Font originalFont = this.Font; RightToLeft startRightToLeft = this.RightToLeft; ownerItem = value; // RESET ambient properties if (!originalFont.Equals(Font)) { OnOwnerItemFontChanged(EventArgs.Empty); } if (ownerItem != null && RightToLeftInherited && startRightToLeft != this.RightToLeft) { using (new LayoutTransaction(this,this,PropertyNames.RightToLeft)) { OnRightToLeftChanged(EventArgs.Empty); } } } } } internal ToolStripDropDownItem OwnerDropDownItem { get { return OwnerItem as ToolStripDropDownItem; } } internal ToolStrip OwnerToolStrip { get { if (ownerItem != null) { ToolStrip owner = ownerItem.ParentInternal; if (owner != null) { return owner; } // might not actually be placed on the overflow, just check for sure. if (ownerItem.Placement == ToolStripItemPlacement.Overflow && ownerItem.Owner != null) { return ownerItem.Owner.OverflowButton.DropDown; } if (owner == null) { return ownerItem.Owner; } } return null; } } ////// /// Hide the Region Property /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public Region Region { get { return base.Region; } set { base.Region = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler RegionChanged { add { base.RegionChanged += value; } remove { base.RegionChanged -= value; } } internal virtual bool RequiresScrollButtons { get { return false; } set { Debug.Fail("You can't set this except on ToolStripDropDownMenu"); } } [ SRCategory(SR.CatAppearance), Localizable(true), AmbientValue(RightToLeft.Inherit), SRDescription(SR.ControlRightToLeftDescr) ] public override RightToLeft RightToLeft { get { // our inheritance is from our owner item. if (RightToLeftInherited) { if (SourceControlInternal != null) { return SourceControlInternal.RightToLeft; } if (OwnerItem != null) { return OwnerItem.RightToLeft; } } return base.RightToLeft; } set { base.RightToLeft = value; } } private bool RightToLeftInherited { get { // fish out of control's property store whether or not RTL was set, if it's set to inherit. return !ShouldSerializeRightToLeft(); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event ScrollEventHandler Scroll { add { base.Scroll += value; } remove { base.Scroll -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new bool Stretch { get { return base.Stretch; } set { base.Stretch = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Always)] new public event EventHandler StyleChanged { add { base.StyleChanged += value; } remove { base.StyleChanged -= value; } } internal Control SourceControlInternal { get { return Properties.GetObject(PropSourceControl) as Control; } set{ Properties.SetObject(PropSourceControl, value); } } internal override int ShowParams { get { return NativeMethods.SW_SHOWNOACTIVATE; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TabStopChanged { add { base.TabStopChanged += value; } remove { base.TabStopChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler TextChanged { add { base.TextChanged += value; } remove { base.TextChanged -= value; } } [ Browsable(false), DefaultValue(ToolStripTextDirection.Horizontal), SRDescription(SR.ToolStripTextDirectionDescr), SRCategory(SR.CatAppearance) ] public override ToolStripTextDirection TextDirection { get { return base.TextDirection; } set { base.TextDirection = value; } } //Consistency: match casing of Form.TopMost, which shipped in Everett, even though it's wrong [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly")] protected virtual bool TopMost { get { return true; } } ///[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool TopLevel { get { return GetTopLevel(); } set { // if (value != GetTopLevel()) { SetTopLevelInternal(value); SetTopLevelStyle(value); } } } // public Color TransparencyKey { // This property intentionally not available for ToolStripDropDown // it's not robust enough for our needs // } /// /// VSWhidbey 233498: override base TabIndex property in order to avoid serialization /// (since a dropdown shouldn't participate in the taborder...) [ EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false) ] public new int TabIndex { get { return base.TabIndex; } set { base.TabIndex = value; } } /// /// [ Browsable(false), EditorBrowsable(EditorBrowsableState.Never), SRCategory(SR.CatPropertyChanged), SRDescription(SR.ControlOnTabIndexChangedDescr) ] public new event EventHandler TabIndexChanged { add { base.TabIndexChanged += value; } remove { base.TabIndexChanged -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler Validated { add { base.Validated += value; } remove { base.Validated -= value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event CancelEventHandler Validating { add { base.Validating += value; } remove { base.Validating -= value; } } ///[To be supplied.] ////// VSWhidbey 233498: override base Visible property in order to control serialization by setting default value [ SRCategory(SR.CatBehavior), Localizable(true), SRDescription(SR.ControlVisibleDescr), DefaultValue(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public new bool Visible { get { return base.Visible; } set { base.Visible = value; } } // internally we use not so we dont have to initialize it. internal bool WorkingAreaConstrained { get { if (state[stateNotWorkingAreaConstrained]) { // SECREVIEW: // We are constrained to the working area when we dont have AllWindows permission return IsRestrictedWindow; } return true; } set { bool notConstrained = !value; state[stateNotWorkingAreaConstrained] = notConstrained; } } internal void AssignToDropDownItem() { countDropDownItemsAssignedTo++; } internal void AdjustSize() { Size size = GetSuggestedSize(); if (size != this.Size) { this.Size = size; } } private void ApplyTopMost(bool topMost) { if (TopMost) { HandleRef topMostFlag = (topMost) ? NativeMethods.HWND_TOPMOST : NativeMethods.HWND_NOTOPMOST; SafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), topMostFlag, 0, 0, 0, 0, NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOACTIVATE); } } /// protected override void Dispose(bool disposing) { if (disposing) { SourceControlInternal = null; } base.Dispose(disposing); } private void CancelAutoExpand() { ToolStrip toplevelOwnerToolStrip = GetToplevelOwnerToolStrip(); if (toplevelOwnerToolStrip != null) { toplevelOwnerToolStrip.MenuAutoExpand = false; } } internal override bool CanProcessMnemonic() { // VSWhidbey 515812: Dont let mnemonics act as keyboard input in IE in the internet. if (IsRestrictedWindow && !Application.MessageLoop) { return false; } return base.CanProcessMnemonic(); } /// protected override AccessibleObject CreateAccessibilityInstance() { return new ToolStripDropDownAccessibleObject(this); } protected override LayoutSettings CreateLayoutSettings(ToolStripLayoutStyle style) { LayoutSettings layoutSettings = base.CreateLayoutSettings(style); if (style == ToolStripLayoutStyle.Flow) { FlowLayoutSettings flowLayoutSettings = layoutSettings as FlowLayoutSettings; flowLayoutSettings.FlowDirection = FlowDirection.TopDown; flowLayoutSettings.WrapContents = false; return flowLayoutSettings; } return layoutSettings; } protected override void CreateHandle() { base.CreateHandle(); if (TopLevel) { ReparentToDropDownOwnerWindow(); if (!AutoClose || !WorkingAreaConstrained) { ApplyTopMost(true); } } if (DesignMode) { SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, false); } } public void Close() { SetCloseReason(ToolStripDropDownCloseReason.CloseCalled); this.Visible = false; // we were the last one in the chain, roll out of menu mode. if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == null) { ToolStripManager.ModalMenuFilter.ExitMenuMode(); } } private void ResetCloseReason() { closeReason = ToolStripDropDownCloseReason.AppFocusChange; } internal void SetCloseReason(ToolStripDropDownCloseReason reason) { closeReason = reason; } public void Close(ToolStripDropDownCloseReason reason) { SetCloseReason(reason); this.Visible = false; } internal override Rectangle ApplyBoundsConstraints(int suggestedX, int suggestedY, int proposedWidth, int proposedHeight) { Rectangle adjustedBounds = base.ApplyBoundsConstraints(suggestedX, suggestedY, proposedWidth, proposedHeight); // SECREVIEW VSWhidbey 430541 - place security size restrictions in non public/protected function // to prevent custom IL from skipping restrictions in SetBoundsCore. if (IsRestrictedWindow && TopMost) { adjustedBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(adjustedBounds); } return adjustedBounds; } /// /// Summary of GetBaseDropDownBounds. /// // called by ToolStripDropDownMenu, internal Rectangle GetDropDownBounds(Rectangle suggestedBounds) { Rectangle dropDownBounds; if (TopLevel) { Point screenPoint = Point.Empty; if ((ownerItem != null) && (ownerItem is ToolStripDropDownItem)) { screenPoint = ((ToolStripDropDownItem)ownerItem).DropDownLocation; } else { screenPoint = suggestedBounds.Location; } Rectangle suggestedScreenBounds = new Rectangle(screenPoint, suggestedBounds.Size); if (WorkingAreaConstrained) { dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(suggestedScreenBounds); } else { dropDownBounds = WindowsFormsUtils.ConstrainToScreenBounds(suggestedScreenBounds); } } else { Point parentClientPoint = Point.Empty; if ((ownerItem != null) && (ownerItem is ToolStripDropDownItem) && (ParentInternal != null)) { parentClientPoint = ParentInternal.PointToClient(((ToolStripDropDownItem)ownerItem).DropDownLocation); } else { parentClientPoint = suggestedBounds.Location; } dropDownBounds = new Rectangle(parentClientPoint, suggestedBounds.Size); } Debug.WriteLineIf(DropDownDebugBounds.TraceVerbose, "DropDownBounds for " + suggestedBounds + "is" +dropDownBounds); return dropDownBounds; } internal Rectangle CalculateDropDownLocation(Point start, ToolStripDropDownDirection dropDownDirection) { Point offset = Point.Empty; if (!IsHandleCreated) { // PERF: // if the handle isnt created yet, then we likely havent performed layout // yet. force a layout here so that we get the correct size. LayoutTransaction.DoLayout(this, this, PropertyNames.PreferredSize); } Rectangle dropDownBounds = new Rectangle(Point.Empty, GetSuggestedSize()); // calculate the offset from the upper left hand corner of the item. switch (dropDownDirection) { case ToolStripDropDownDirection.AboveLeft: offset.X = - dropDownBounds.Width; offset.Y = - dropDownBounds.Height; break; case ToolStripDropDownDirection.AboveRight: offset.Y = - dropDownBounds.Height; break; case ToolStripDropDownDirection.BelowRight: case ToolStripDropDownDirection.Right: break; case ToolStripDropDownDirection.BelowLeft: case ToolStripDropDownDirection.Left: offset.X = - dropDownBounds.Width; break; } dropDownBounds.Location = new Point(start.X + offset.X, start.Y + offset.Y); if (WorkingAreaConstrained) { dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds); } return dropDownBounds; } internal Size GetSuggestedSize() { if (AutoSize) { return GetPreferredSize(Size.Empty); } return this.Size; } ////// Returns the ToolStrip from which all the dropdowns started from. This can be null. /// internal override ToolStrip GetToplevelOwnerToolStrip() { ToolStripDropDown topmost = GetFirstDropDown(); return (topmost.OwnerItem == null) ? null : topmost.OwnerToolStrip; } internal ToolStripItem GetToplevelOwnerItem() { ToolStripDropDown topmost = GetFirstDropDown(); return topmost.OwnerItem; } internal override void HandleItemClicked(ToolStripItem dismissingItem) { // post processing after the click has happened. SourceControlInternal = null; base.HandleItemClicked(dismissingItem); } ////// Set some common properties /// internal virtual void Initialize() { SetState(STATE_VISIBLE, false); SetTopLevelInternal(true); // VSWhidbey 82103 -- marking this as a modal form prevents it from being activated // by the IMsoComponentManager, which will break keyboard routing in VS. // SetState(STATE_MODAL, true); SetStyle(ControlStyles.ResizeRedraw, true); this.UpdateStyles(); this.GripStyle = ToolStripGripStyle.Hidden; this.CanOverflow = false; this.LayoutStyle = ToolStripLayoutStyle.Flow; this.MenuAutoExpand = true; this.AutoSize = true; } ////// /// Summary of OnLayout. /// /// protected virtual void OnClosed(ToolStripDropDownClosedEventArgs e){ if (IsHandleCreated) { if (ownerItem == null || !ownerItem.IsInDesignMode) { AccessibilityNotifyClients(AccessibleEvents.SystemMenuPopupEnd, -1); } } ToolStripDropDownClosedEventHandler handler = (ToolStripDropDownClosedEventHandler)Events[EventClosed]; if (handler != null) handler(this, e); } // SECREVIEW - for the "Cancel" to be honored, you must have AllWindowsPermission // i.e. ToolStripDropDown.IsRestrictedWindow MUST be false. // for more details see ToolStripDropDown.SetVisibleCore protected virtual void OnClosing(ToolStripDropDownClosingEventArgs e) { ToolStripDropDownClosingEventHandler handler = (ToolStripDropDownClosingEventHandler)Events[EventClosing]; if (handler != null) handler(this, e); } ////// /// When our handle is being created, suspend the deactivation /// portion of the WndProc, as we'll never be shown. /// protected override void OnHandleCreated(EventArgs e) { UpdateStyles(); // get rid of WS_CAPTION style base.OnHandleCreated(e); UpdateLayered(); // update transparency } protected override void OnItemClicked(ToolStripItemClickedEventArgs e) { try { base.OnItemClicked(e); } finally { ToolStripDropDownItem dismissingItem = e.ClickedItem as ToolStripDropDownItem; if (AutoClose) { if ((dismissingItem == null) // it's not a dropdownitem || (dismissingItem is ToolStripSplitButton && !dismissingItem.DropDown.Visible) // clicking on the split button button dismisses || !(dismissingItem.HasDropDownItems)) { // clicking on a item w/dropdown does not dismiss window Close(ToolStripDropDownCloseReason.ItemClicked); } } } } ///protected override void OnLayout(LayoutEventArgs e) { // VSWhidbey 480533 it's important to size the dropdown first, then layout so that // the layout engine and SetDisplayedItems know how big the container is. AdjustSize(); base.OnLayout(e); } protected virtual void OnOpening(CancelEventArgs e){ CancelEventHandler handler = (CancelEventHandler)Events[EventOpening]; if (handler != null) handler(this, e); } /// /// /// Summary of OnLayout. /// /// protected virtual void OnOpened(System.EventArgs e) { if (IsHandleCreated) { if (ownerItem == null || !ownerItem.IsInDesignMode) { AccessibilityNotifyClients(AccessibleEvents.SystemMenuPopupStart, -1); } } EventHandler handler = (EventHandler)Events[EventOpened]; if (handler != null) handler(this, e); } protected override void OnVisibleChanged(System.EventArgs e) { if (this.Location != this.displayLocation) { // If we adjusted the position from where the user wanted it, // see if we can put it in the right location now that they've changed // the items collection, and store where we actually have it. // Just because this is the case doesn't mean that we need to do another // another layout however. this.Location = this.displayLocation; this.displayLocation = this.Location; } if (AutoScroll || this.LayoutRequired) { // the base here forces a layout... we really only want to do this the first // time we pop the window... the subsequent times should be snappy. base.OnVisibleChanged(e); } else { this.SuspendLayout(); try { // scrollable control forces a layout here for scrollbar reasons only // since we toggle visibility a lot this is expensive. Let's be clever and // not do it. base.OnVisibleChanged(e); } finally { this.ResumeLayout(false); } } } ///protected override void OnParentChanged(System.EventArgs e) { base.OnParentChanged(e); Rectangle bounds = this.Bounds; SetBoundsCore(bounds.X, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.Location); } protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mea) { base.OnMouseUp(mea); Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.OnMouseUp] mouse up outside of the toolstrip - this should dismiss the entire chain"); //VSWhidbey 384068 Menus should dismiss when you drag off if (!ClientRectangle.Contains(mea.Location)) { bool dismiss = true; if (OwnerToolStrip != null && OwnerItem != null) { if (OwnerItem.Bounds.Contains(WindowsFormsUtils.TranslatePoint(mea.Location, this, OwnerToolStrip))) { dismiss = false; // dont dismiss if we clicked on our owner item } } if (dismiss) { DismissAll(); CancelAutoExpand(); } } } internal void OnOwnerItemFontChanged(EventArgs e) { if (this.IsAutoGenerated) { using (new LayoutTransaction(this, OwnerItem, PropertyNames.Font)) { OnFontChanged(e); } } } internal void SelectPreviousToolStrip() { // snap the owner item before calling hide as non-auto created dropdowns will // exit menu mode if there's no OwnerItem. ToolStripItem itemOnPreviousMenuToSelect = this.OwnerItem; this.Hide(); if (itemOnPreviousMenuToSelect != null) { itemOnPreviousMenuToSelect.Select(); if (OwnerToolStrip != null) { // make sure we send keyboard handling where we've just // sent selection if (!OwnerToolStrip.IsDropDown) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != OwnerToolStrip) { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(OwnerToolStrip); } // escape should cancel auto expansion OwnerToolStrip.MenuAutoExpand = false; } } } else { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.SelectPreviousToolStrip] No previous toolstrip to select - exiting menu mode."); ToolStripManager.ModalMenuFilter.ExitMenuMode(); } } /// /// this is where we handle navigation between the File,Edit,View dropdowns /// if you have one of these dropdowns showing and you hit the arrow key /// and it's not processed by the menu item /// internal override bool ProcessArrowKey(Keys keyCode) { Debug.WriteLineIf(ToolStrip.MenuAutoExpandDebug.TraceVerbose, "[ToolStripDropDown.ProcessArrowKey] MenuTimer.Cancel called"); ToolStripMenuItem.MenuTimer.Cancel(); if (keyCode == Keys.Left || keyCode == Keys.Right) { bool rightAligned = SystemInformation.RightAlignedMenus; bool forward = (keyCode == Keys.Left && rightAligned) || (keyCode == Keys.Right && !rightAligned); if (!IsFirstDropDown && !forward) { // this is the case where you've casecaded out to a second level dropdown and you hit the back arrow // key. In this case we want to just hide the current dropdown this.Visible = false; return true; } else { bool closeOnHorizontalKey = false; if (LayoutStyle == ToolStripLayoutStyle.Flow) { closeOnHorizontalKey = FlowLayout.GetFlowDirection(this) == FlowDirection.TopDown && !FlowLayout.GetWrapContents(this); } if (closeOnHorizontalKey) { ToolStrip toplevelToolStrip = GetToplevelOwnerToolStrip(); ToolStripItem rootItem = GetToplevelOwnerItem(); // This is the case where you need to open up the adjacent DropDown (File->Edit) menus because: // - this is the toplevel ToolStripDropDown and you hit left or right // - this is a non-toplevel ToolStripDropDown and you hit an arrow key in a direction // of the cascade AND the current item has no cascading menu associated with it. bool isOnOverflow = (OwnerItem != null && OwnerItem.IsOnOverflow); if (forward || !isOnOverflow) { DismissAll(); } else if (isOnOverflow) { // VSWhidbey 478068: going backwards should roll us up and our children but not the overflow. Visible = false; } if (toplevelToolStrip != null && rootItem != null) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != toplevelToolStrip) { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(toplevelToolStrip); } toplevelToolStrip.SelectNextToolStripItem(rootItem,forward); } return true; } } } // get base behavior like up/down navigation. return base.ProcessArrowKey(keyCode); } ///[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected override bool ProcessDialogKey(Keys keyData) { if (this.OwnerItem != null && this.OwnerItem.IsInDesignMode) { return false; } if (AutoClose && Visible) { if (ToolStripManager.IsMenuKey(keyData)) { SetCloseReason(ToolStripDropDownCloseReason.Keyboard); DismissAll(); ToolStrip toplevel = GetToplevelOwnerToolStrip(); if (toplevel != null) { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown ProcessDialogKey]: Got Menu Key, finding toplevel toolstrip, calling RestoreFocus."); toplevel.RestoreFocusInternal(); ToolStripManager.ModalMenuFilter.MenuKeyToggle = true; } ToolStripManager.ModalMenuFilter.ExitMenuMode(); return true; } else if ((keyData & Keys.KeyCode) == Keys.Escape) { SetCloseReason(ToolStripDropDownCloseReason.Keyboard); SelectPreviousToolStrip(); return true; } } return base.ProcessDialogKey(keyData); } [EditorBrowsable(EditorBrowsableState.Advanced)] [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected override bool ProcessDialogChar(char charCode) { #if DEBUG Debug.WriteLineIf(ControlKeyboardRouting.TraceVerbose, "ToolStripDropDown.ProcessDialogChar [" + charCode.ToString() + "]"); #endif // since we're toplevel and arent a container control, we've got to do our own mnemonic handling. // if ((OwnerItem == null || OwnerItem.Pressed) && charCode != ' ') { if (ProcessMnemonic(charCode)){ return true; } } return base.ProcessDialogChar(charCode); } [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] protected internal override bool ProcessMnemonic(char charCode) { if (!CanProcessMnemonic()) { return false; // here for security see CanProcessMnemonic. } return base.ProcessMnemonic(charCode); } internal override void ProcessDuplicateMnemonic(ToolStripItem item, char charCode) { if (!CanProcessMnemonic()) { return; // here for security see CanProcessMnemonic. } if (item != null) { // SECREVIEW // We want to make sure that Mnemonics arent another way of getting keyboard // input. Allowing double mnemonics to switch selection could effectively let you // figure out what someone was typing into the window by checking the selected state // of all of your items. Instead of switching selection, we'll just perform the click. // ===> Assumes ToolStripItem.ProcessMnemonic is protected by AWP if (IsRestrictedWindow) { item.ProcessMnemonic(charCode); // execute the first click } else { base.ProcessDuplicateMnemonic(item,charCode); } } } internal override void RecreateHandleCore() { // If we're visible, then we'll have set our parent hwnd to the active control. // That means that re-create handle will set it as our parent, but that's not what // we want, since that means that from now on we'll be displayed in that controls // client co-ordinates. To fix this, we first re-parent ourselves back to the // hidden window, do the re-create, then set the parent again. if (Visible) { ReparentToDropDownOwnerWindow(); } base.RecreateHandleCore(); if (Visible) { ReparentToActiveToolStripWindow(); } } private void ResetDropShadowEnabled() { DropShadowEnabled = true; } private void ReparentToActiveToolStripWindow() { ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this); UnsafeNativeMethods.SetWindowLong(new HandleRef(this, Handle), NativeMethods.GWL_HWNDPARENT, ToolStripManager.ModalMenuFilter.ActiveHwnd); } private void ReparentToDropDownOwnerWindow() { // when we're toplevel we need to parent ourselves to a hidden window // this prevents a taskbar entry. NativeWindow ownerWindow = DropDownOwnerWindow; HandleRef ownerHandle = new HandleRef(ownerWindow, ownerWindow.Handle); UnsafeNativeMethods.SetWindowLong(new HandleRef(this, Handle), NativeMethods.GWL_HWNDPARENT, ownerHandle); } /// /// VERY similar to Form.ScaleCore /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void ScaleCore(float dx, float dy) { Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, GetType().Name + "::ScaleCore(" + dx + ", " + dy + ")"); SuspendLayout(); try { //Get size values in advance to prevent one change from affecting another. Size clientSize = ClientSize; Size minSize = MinimumSize; Size maxSize = MaximumSize; ClientSize = ScaleSize(clientSize, dx, dy); if (!MinimumSize.IsEmpty) { MinimumSize = ScaleSize(minSize, dx, dy); } if (!MaximumSize.IsEmpty) { MaximumSize = ScaleSize(maxSize, dx, dy); } ScaleDockPadding(dx, dy); foreach(Control control in Controls) { if (control != null) { #pragma warning disable 618 control.Scale(dx, dy); #pragma warning restore 618 } } } finally { ResumeLayout(); } } ////// /// Scale this form. Form overrides this to enforce a maximum / minimum size. /// protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); Size minSize = MinimumSize; Size maxSize = MaximumSize; if (!MinimumSize.IsEmpty) { MinimumSize = ScaleSize(minSize, factor.Width, factor.Height); } if (!MaximumSize.IsEmpty) { MaximumSize = ScaleSize(maxSize, factor.Width, factor.Height); } } ////// This is called when the ToolStripDropDownItem sets the DropDown property using CreateDefaultDropDown. /// In this case, the IsAutoGenerated should return true. /// internal void SetAutoGeneratedInternal(bool autoGenerated) { this.isAutoGenerated = autoGenerated; } ////// /// [....] sizes with the ToolStripDropDown /// protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) { Rectangle bounds = new Rectangle(x, y, width, height); bounds = GetDropDownBounds(bounds); base.SetBoundsCore(bounds.X, bounds.Y, bounds.Width, bounds.Height, specified); } private void SetTopLevelStyle(bool value) { if (IsHandleCreated) { // We need to swap they style bits on the window handle // we could recreate the handle, but that seems rather expensive. int styleFlags = WindowStyle; if (value) { // setting toplevel = true styleFlags &= ~NativeMethods.WS_CHILD; styleFlags |= NativeMethods.WS_POPUP; } else { // this is a child window styleFlags &= ~NativeMethods.WS_POPUP; styleFlags |= NativeMethods.WS_CHILD; } WindowStyle = styleFlags; } } ////// /// Summary of SetVisibleCore. /// /// protected override void SetVisibleCore(bool visible) { if (state[stateInSetVisibleCore]) { return; } state[stateInSetVisibleCore] = true; try { if (visible) { if (LayoutRequired) { LayoutTransaction.DoLayout(this, this, PropertyNames.Visible); } bool openingEventCancelled = true; // assume that it's been cancelled so that if we throw we do nothing. try { // VSWhidbey 313920 - add opening event. // Snap the foreground window BEFORE calling any user events so they dont have a // chance to activate something else. This covers the case where someone handles the // opening event and throws up a messagebox. IntPtr foregroundWindow = UnsafeNativeMethods.GetForegroundWindow(); // Fire Opening event // Cancellable event in which default value of e.Cancel depends on the number of displayed items >0. // CancelEventArgs openEventArgs = new CancelEventArgs(/*cancel=*/(DisplayedItems.Count == 0)); OnOpening(openEventArgs); openingEventCancelled = openEventArgs.Cancel; if (!openingEventCancelled) { // do the actual work to open the window. if (TopLevel) { ReparentToActiveToolStripWindow(); } // review: what is this used for? if (OwnerToolStrip != null) { OwnerToolStrip.ActiveDropDowns.Add(this); // the act of showing this window can cause a spurious mouse move // in the parent, make sure it retains where the mouse really was. OwnerToolStrip.SnapMouseLocation(); // VSWhidbey 458967: make sure that mouse capture // transitions between the owner and dropdown. if (OwnerToolStrip.CaptureInternal) { CaptureInternal = true; } } base.SetVisibleCore(visible); if (TopLevel){ ApplyTopMost(true); } else if (IsHandleCreated && SafeNativeMethods.IsWindowEnabled(new HandleRef(this, Handle))) { SafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOACTIVATE); } } } finally { // Fire Opened event // fire the opened event only if we actually opened the control. // if (!openingEventCancelled) { OnOpened(new EventArgs()); } } } else { if (GetVisibleCore()) { ToolStripDropDownCloseReason reason = closeReason; ResetCloseReason(); ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs(reason); // Fire Closing Event // Cancel is prepopulated based on AutoClose feature. // if (e.CloseReason != ToolStripDropDownCloseReason.CloseCalled) { e.Cancel = !AutoClose; } else { e.Cancel = false; } try { OnClosing(e); } finally { // SECREVIEW - When IsRestrictedWindow is true, you cannot cancel the closing of the ToolStripDropDown. // You can set AutoClose = false and OnClosing(e.Cancel=true), but we will ignore it. if (!e.Cancel || IsRestrictedWindow /*delay evaluate only in the case we need it*/) { // setting to not visible. Dismiss our child drop downs, reset, set ourselves visible false. DismissActiveDropDowns(); // if this came through via a click event we should actually // dismiss everyone in the chain. Other windows will recieve a // close, closing event with reason AppFocusChange. This is by // design since the item wasnt clicked on that window. if (reason == ToolStripDropDownCloseReason.ItemClicked) { DismissAll(); // make sure that when we roll up, our owner item's selection is cleared. ToolStripItem rootOwnerItem = GetToplevelOwnerItem(); if (rootOwnerItem != null) { rootOwnerItem.Unselect(); } // VSWhidbey 480392: make sure we cancel auto expansion on the root CancelAutoExpand(); ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose,"[ToolStripDropDown.SetVisibleCore] Exiting menu mode because item clicked"); ToolStripManager.ModalMenuFilter.ExitMenuMode(); } else { ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); } // snap our bounds, we'll need it for some invalidation later. Rectangle bounds = this.Bounds; try { base.SetVisibleCore(visible); } finally { // remove ourselves from the active dropdown list. if (OwnerToolStrip != null) { OwnerToolStrip.ActiveDropDowns.Remove(this); } ActiveDropDowns.Clear(); // VSWhidbey 389244: if the user traps the click event and starts // pumping their own messages by calling Application.DoEvents, we // should release mouse capture. if (CaptureInternal) { CaptureInternal = false; } } // Fire OnClosed. // if you make VisibleChanged throw you dont get closed. Sorry. ToolStripDropDownClosedEventArgs closedEventArgs = new ToolStripDropDownClosedEventArgs(reason); OnClosed(closedEventArgs); if (TopLevel && (!IsDisposed || !Disposing)) { // Parent back up to our DropDownOwnerWindow. ReparentToDropDownOwnerWindow(); } if (reason != ToolStripDropDownCloseReason.ItemClicked) { // VSWhidbey 475650: If we're not about to fire a Click event, reset SourceControl. SourceControlInternal = null; } // Making ourselves look presentable: // We may be about to invoke a click event here... // if we're the topmost dropdown then invalidate our // intersection with the toplevel toolstrip if (!DesignMode && IsFirstDropDown && OwnerItem != null && TopLevel) { ToolStrip toolStrip = GetToplevelOwnerToolStrip(); if (toolStrip != null && !(toolStrip.IsDisposed || toolStrip.Disposing)) { // translate the bounds (already in screen coords) to toolstrip. bounds.Location = toolStrip.PointToClient(bounds.Location); // find the intersection with the client and use that to invalidate bounds.Intersect(toolStrip.ClientRectangle); if (bounds.Width > 0 && bounds.Height >0) { toolStrip.Invalidate(bounds); toolStrip.Update(); } } } } } } else { ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this); } } } finally { state[stateInSetVisibleCore] = false; } } private bool ShouldSerializeDefaultDropDownDirection() { return (childDropDownDirection != ToolStripDropDownDirection.Default); } ////// Updates the layered window attributes if the control /// is in layered mode. /// private void UpdateLayered() { if (state[stateLayered] && IsHandleCreated && TopLevel && OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) { bool result; result = UnsafeNativeMethods.SetLayeredWindowAttributes(new HandleRef(this, Handle), 0, OpacityAsByte, NativeMethods.LWA_ALPHA); if (!result) { throw new Win32Exception(); } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new void Show() { // don't set displayLocation here, since all the other Show methods call this. base.Show(); } ////// show relative to control coordinates public void Show(Control control, Point position) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; // VSWhidbey 310328 - when we have no owner item and we're set to RTL.Inherit, translate the coordinates // so that the menu looks like it's swooping from the other side if (this.OwnerItem == null && control.RightToLeft == RightToLeft.Yes) { AdjustSize(); position.Offset(control.IsMirrored ? Width : -Width, 0); } this.displayLocation = control.PointToScreen(position); this.Location = this.displayLocation; ShowCore(); } public void Show(Control control, Point position, ToolStripDropDownDirection direction) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; this.displayLocation = CalculateDropDownLocation(control.PointToScreen(position), direction).Location; this.Location = this.displayLocation; ShowCore(); } ////// show relative to control coordinates public void Show(Control control, int x, int y) { if (control == null) { throw new ArgumentNullException("control"); } SourceControlInternal = control; Show(control, new Point(x,y)); } ////// show relative to screen coordinates public void Show(Point screenLocation) { this.displayLocation = screenLocation; this.Location = this.displayLocation; ShowCore(); } public void Show(Point position, ToolStripDropDownDirection direction) { this.displayLocation = CalculateDropDownLocation(position, direction).Location; this.Location = this.displayLocation; ShowCore(); } ////// show relative to screen coordinates public void Show(int x, int y) { this.displayLocation = new Point(x,y); this.Location = this.displayLocation; ShowCore(); } private void ShowCore() { Show(); } private bool ShouldSerializeDropShadowEnabled() { return dropShadowEnabled == false; } internal override bool ShouldSerializeLayoutStyle() { return LayoutStyle != ToolStripLayoutStyle.VerticalStackWithOverflow; } internal void UnassignDropDownItem() { Debug.Assert(countDropDownItemsAssignedTo > 0, "dropdown assignment underflow"); countDropDownItemsAssignedTo = Math.Max(--countDropDownItemsAssignedTo, 0); } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref Message m) { if (m.Msg >= NativeMethods.WM_KEYFIRST && m.Msg <= NativeMethods.WM_KEYLAST && IsRestrictedWindow) { // SECREVIEW: // To Receive a OnKey* event, the ToolStripDropDown must have AllWindows permission // directly calling DefWndProc will prevent these events from executing. // All PreProcess keyboard messages are protected by link demands. // NOTE the same kind of fix needs to go into ToolStripScrollButton.StickyLabel (the only alloewed ControlHost) DefWndProc(ref m); return; } switch (m.Msg) { case NativeMethods.WM_NCACTIVATE: // if someone clicks on a child control of the toolstrip dropdown, we want // the title bar to continue appearing active. Normally we just show without // taking window activation (ShowWindow(SHOWNOACTIVATE)) but we cant stop // child controls from taking focus. WmNCActivate(ref m); return; case NativeMethods.WM_ACTIVATE: // This is the Chrome Panel collection editor scenario // we had focus, then the Chrome panel was activated and we never went away // when we get focus again, we should reactivate our message filter. Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.WndProc] got a WM_ACTIVATE " + (((int)m.WParam == NativeMethods.WA_ACTIVE) ? "WA_ACTIVE" : "WA_INACTIVE") + " - checkin if we need to set the active toolstrip"); if((int)m.WParam == NativeMethods.WA_ACTIVE) { if (this.Visible) { if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() != this) { // if we were inactive and now we are, we should enter menu mode ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this); } } else { Debug.Fail("Why are we being activated when we're not visible? Deactivating thingee is " + WindowsFormsUtils.GetControlInformation(m.LParam)); } } else { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown.WndProc] activating thingee is " + WindowsFormsUtils.GetControlInformation(m.LParam)); } base.WndProc(ref m); return; /* case NativeMethods.WM_SYSKEYUP: Keys keyData = (Keys)(int)m.WParam; base.WndProc(ref m); // VSW 423760: handle the case where the ALT key has been pressed down while a dropdown // was open. We need to clear off the MenuKeyToggle so the next ALT will activate // the menu. if (IsMenuKey(keyData)) { ToolStrip toplevel = GetToplevelOwnerToolStrip(); if (toplevel != null && toplevel.MenuKeyToggle) { Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "[ToolStripDropDown WM_SYSKEYUP]: Got Menu Key, restoring MenuKeyToggle."); toplevel.MenuKeyToggle = false; } } return;*/ default: base.WndProc(ref m); return; } } #region DropDownSpecific internal void DismissAll() { ToolStripDropDown toplevel = this.GetFirstDropDown(); toplevel.DismissActiveDropDowns(); toplevel.Visible = false; } private void DismissActiveDropDowns() { Debug.WriteLineIf((DropDownActivateDebug.TraceVerbose && ActiveDropDowns.Count > 0), "Dismiss children called - COUNT " + ActiveDropDowns.Count + " \r\n" + new StackTrace().ToString()); int count = ActiveDropDowns.Count; if (count == 1) { // this is the most common case ToolStripDropDown dropDown = ActiveDropDowns[0] as ToolStripDropDown; if (dropDown != null) { dropDown.Visible = false; } } else { ArrayList dropDowns = ActiveDropDowns.Clone() as ArrayList; // We cant iterate through the active dropdown collection // here as changing visibility changes the collection. for (int i = 0; i < dropDowns.Count; i++) { ToolStripDropDown dropDown = dropDowns[i] as ToolStripDropDown; if (dropDown != null) { dropDown.Visible = false; } } } } #region WMNCACTIVATE private bool sendingActivateMessage = false; // WmNcActivate // if someone clicks on a child control of the toolstrip dropdown, we want // the title bar to continue appearing active. Normally we just show without // taking window activation (ShowWindow(SHOWNOACTIVATE)) but we cant stop // child controls from taking focus. private void WmNCActivate(ref Message m) { if (m.WParam != IntPtr.Zero /*activating*/) { if (!sendingActivateMessage) { sendingActivateMessage = true; try { Debug.WriteLineIf(DropDownActivateDebug.TraceVerbose, "Sending WM_NCACTIVATE to toplevel hwnd" + ToolStripManager.ModalMenuFilter.ActiveHwnd); // we're activating - notify the previous guy that we're activating. HandleRef activeHwndHandleRef = ToolStripManager.ModalMenuFilter.ActiveHwnd; UnsafeNativeMethods.SendMessage(activeHwndHandleRef, NativeMethods.WM_NCACTIVATE, (IntPtr)1, NativeMethods.InvalidIntPtr); SafeNativeMethods.RedrawWindow(activeHwndHandleRef, null, NativeMethods.NullHandleRef, NativeMethods.RDW_FRAME | NativeMethods.RDW_INVALIDATE); m.WParam = (IntPtr)1; } finally { sendingActivateMessage = false; } } DefWndProc(ref m); return; } else { base.WndProc(ref m); } } #endregion ////// Determines if this is the first dropDown in the dropDown chain /// internal bool IsFirstDropDown { get { return ((OwnerToolStrip as ToolStripDropDown) == null); } } ////// returns the root dropdown in the chain. /// internal ToolStripDropDown GetFirstDropDown() { ToolStripDropDown topmost = this; // walk back up the chain of windows to get the topmost ToolStripDropDown ownerDropDown = topmost.OwnerToolStrip as ToolStripDropDown; while (ownerDropDown != null) { topmost = ownerDropDown; ownerDropDown = topmost.OwnerToolStrip as ToolStripDropDown; } return topmost; } internal static ToolStripDropDown GetFirstDropDown(ToolStrip start) { Debug.Assert(start != null, "Who is passing null to GetFirstDropDown?"); if ((start == null) || (!start.IsDropDown)) { return null; } ToolStripDropDown startDropDown = (start as ToolStripDropDown); return startDropDown.GetFirstDropDown(); } #endregion DropDownSpecific ///[System.Runtime.InteropServices.ComVisible(true)] public class ToolStripDropDownAccessibleObject : ToolStripAccessibleObject { private ToolStripDropDown owner; /// public ToolStripDropDownAccessibleObject(ToolStripDropDown owner) : base(owner) { this.owner = owner; } public override string Name { get { // Special case: If an explicit name has been set in the AccessibleName property, use that. // Note: Any non-null value in AccessibleName overrides the default accessible name logic, // even an empty string (this is the only way to *force* the accessible name to be blank). string name = owner.AccessibleName; if (name != null) { return name; } // NOT localized for testing purposes. Localizers can use AccessibleName. name = "DropDown"; if (owner.OwnerItem != null && owner.OwnerItem.AccessibilityObject.Name != null) { name = owner.OwnerItem.AccessibilityObject.Name + name; } return name; } set { // If anyone tries to set the accessible name, just cache the value in the control's // AccessibleName property. This value will then end up overriding the normal accessible // name logic, until such time as AccessibleName is set back to null. owner.AccessibleName = value; } } public override AccessibleRole Role { get { AccessibleRole role = Owner.AccessibleRole; if (role != AccessibleRole.Default) { return role; } return AccessibleRole.MenuPopup; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlBinaryReader.cs
- ContainerFilterService.cs
- Matrix.cs
- CreateUserWizardAutoFormat.cs
- AtlasWeb.Designer.cs
- AppDomainProtocolHandler.cs
- CaseStatement.cs
- wgx_sdk_version.cs
- ZipQueryOperator.cs
- DataServices.cs
- QilBinary.cs
- DictionaryMarkupSerializer.cs
- Camera.cs
- FormClosingEvent.cs
- DataGridViewCellParsingEventArgs.cs
- TextEditorThreadLocalStore.cs
- namescope.cs
- Label.cs
- ObjectDataSourceDisposingEventArgs.cs
- OleDbCommand.cs
- DoubleLinkListEnumerator.cs
- ThrowOnMultipleAssignment.cs
- LinearKeyFrames.cs
- LinkLabel.cs
- FeatureSupport.cs
- ApplicationServicesHostFactory.cs
- EndpointAddressMessageFilter.cs
- AttachmentService.cs
- StackSpiller.Bindings.cs
- Base64Encoder.cs
- Rfc4050KeyFormatter.cs
- LinearKeyFrames.cs
- ProxyElement.cs
- WebPartMinimizeVerb.cs
- ProfessionalColorTable.cs
- ValidationSummaryDesigner.cs
- IsolatedStorageFilePermission.cs
- GenericTypeParameterBuilder.cs
- GlyphRunDrawing.cs
- WpfWebRequestHelper.cs
- PageClientProxyGenerator.cs
- ConnectionStringsExpressionEditor.cs
- Adorner.cs
- Geometry.cs
- EndOfStreamException.cs
- QuadTree.cs
- ObjectDataSourceDisposingEventArgs.cs
- ProgressiveCrcCalculatingStream.cs
- ButtonFieldBase.cs
- ImpersonationContext.cs
- PageThemeParser.cs
- GestureRecognitionResult.cs
- DataGridItemCollection.cs
- CharUnicodeInfo.cs
- DisplayMemberTemplateSelector.cs
- IdentityModelStringsVersion1.cs
- DbConnectionPoolOptions.cs
- QueryContinueDragEvent.cs
- HwndSourceParameters.cs
- CodeExpressionStatement.cs
- SharedPersonalizationStateInfo.cs
- CFGGrammar.cs
- SafeHandle.cs
- LicenseProviderAttribute.cs
- UpDownBase.cs
- Partitioner.cs
- SHA1.cs
- VerticalAlignConverter.cs
- SubpageParagraph.cs
- SetterTriggerConditionValueConverter.cs
- EntityWrapperFactory.cs
- TaiwanCalendar.cs
- SafeHandle.cs
- DataGridColumn.cs
- PageClientProxyGenerator.cs
- SharedUtils.cs
- LicenseException.cs
- EntityStoreSchemaFilterEntry.cs
- QilXmlWriter.cs
- SyncOperationState.cs
- ZipIOLocalFileHeader.cs
- Baml2006ReaderContext.cs
- ApplicationGesture.cs
- EncoderFallback.cs
- IfAction.cs
- TemplatedAdorner.cs
- PropertyMap.cs
- AnchoredBlock.cs
- CharacterMetrics.cs
- DataGridViewTopLeftHeaderCell.cs
- UrlAuthorizationModule.cs
- FlowDocumentPage.cs
- EntityDataSourceStatementEditor.cs
- TextTreeFixupNode.cs
- HttpCookiesSection.cs
- SystemException.cs
- TransformConverter.cs
- DetailsViewUpdatedEventArgs.cs
- validationstate.cs
- ElementsClipboardData.cs