2 // ToolStripDropDown.cs
\r
4 // Permission is hereby granted, free of charge, to any person obtaining
\r
5 // a copy of this software and associated documentation files (the
\r
6 // "Software"), to deal in the Software without restriction, including
\r
7 // without limitation the rights to use, copy, modify, merge, publish,
\r
8 // distribute, sublicense, and/or sell copies of the Software, and to
\r
9 // permit persons to whom the Software is furnished to do so, subject to
\r
10 // the following conditions:
\r
12 // The above copyright notice and this permission notice shall be
\r
13 // included in all copies or substantial portions of the Software.
\r
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
23 // Copyright (c) 2006 Jonathan Pobst
\r
26 // Jonathan Pobst (monkey@jpobst.com)
\r
30 using System.Drawing;
\r
31 using System.Runtime.InteropServices;
\r
32 using System.ComponentModel;
\r
34 namespace System.Windows.Forms
\r
36 [ClassInterface (ClassInterfaceType.AutoDispatch)]
\r
38 public class ToolStripDropDown : ToolStrip
\r
40 private bool allow_transparency;
\r
41 private bool auto_close;
\r
42 private bool drop_shadow_enabled = true;
\r
43 private double opacity = 1D;
\r
44 private ToolStripItem owner_item;
\r
46 #region Public Constructor
\r
47 public ToolStripDropDown () : base ()
\r
49 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
\r
50 SetStyle (ControlStyles.ResizeRedraw, true);
\r
52 this.auto_close = true;
\r
54 Hwnd.ObjectFromHandle (this.Handle).no_activate = true;
\r
55 this.GripStyle = ToolStripGripStyle.Hidden;
\r
59 #region Public Properties
\r
61 public bool AllowTransparency {
\r
62 get { return allow_transparency; }
\r
64 if (value == allow_transparency)
\r
67 if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0) {
\r
68 allow_transparency = value;
\r
71 XplatUI.SetWindowTransparency (Handle, Opacity, Color.Empty);
\r
73 UpdateStyles (); // Remove the WS_EX_LAYERED style
\r
79 public override AnchorStyles Anchor {
\r
80 get { return base.Anchor; }
\r
81 set { base.Anchor = value; }
\r
84 [DefaultValue (true)]
\r
85 public bool AutoClose
\r
87 get { return this.auto_close; }
\r
88 set { this.auto_close = value; }
\r
91 [DefaultValue (true)]
\r
92 public override bool AutoSize {
\r
93 get { return base.AutoSize; }
\r
94 set { base.AutoSize = value; }
\r
98 [EditorBrowsable (EditorBrowsableState.Never)]
\r
99 public new ContextMenu ContextMenu {
\r
100 get { return null; }
\r
104 //[Browsable (false)]
\r
105 //[EditorBrowsable (EditorBrowsableState.Never)]
\r
106 //public ContextMenuStrip ContextMenuStrip {
\r
107 // get { return null; }
\r
111 [Browsable (false)]
\r
112 [EditorBrowsable (EditorBrowsableState.Never)]
\r
113 public override DockStyle Dock {
\r
114 get { return base.Dock; }
\r
115 set { base.Dock = value; }
\r
118 public bool DropShadowEnabled {
\r
119 get { return this.drop_shadow_enabled; }
\r
121 if (this.drop_shadow_enabled == value)
\r
124 this.drop_shadow_enabled = value;
\r
125 UpdateStyles (); // Re-CreateParams
\r
129 public override Font Font {
\r
130 get { return base.Font; }
\r
131 set { base.Font = value; }
\r
134 [Browsable (false)]
\r
135 [EditorBrowsable (EditorBrowsableState.Never)]
\r
136 public new ToolStripGripDisplayStyle GripDisplayStyle {
\r
137 get { return ToolStripGripDisplayStyle.Vertical; }
\r
140 [Browsable (false)]
\r
141 [EditorBrowsable (EditorBrowsableState.Never)]
\r
142 public new Padding GripMargin {
\r
143 get { return Padding.Empty; }
\r
147 [Browsable (false)]
\r
148 [EditorBrowsable (EditorBrowsableState.Never)]
\r
149 public new Rectangle GripRectangle {
\r
150 get { return Rectangle.Empty; }
\r
153 [Browsable (false)]
\r
154 [EditorBrowsable (EditorBrowsableState.Never)]
\r
155 public new ToolStripGripStyle GripStyle {
\r
156 get { return base.GripStyle; }
\r
157 set { base.GripStyle = value; }
\r
160 [Browsable (false)]
\r
161 [EditorBrowsable (EditorBrowsableState.Never)]
\r
162 public new Point Location {
\r
163 get { return base.Location; }
\r
164 set { base.Location = value; }
\r
167 public double Opacity {
\r
168 get { return this.opacity; }
\r
170 if (this.opacity == value)
\r
173 this.opacity = value;
\r
174 this.allow_transparency = true;
\r
177 XplatUI.SetWindowTransparency (Handle, opacity, Color.Empty);
\r
181 public ToolStripItem OwnerItem {
\r
182 get { return this.owner_item; }
\r
183 set { this.owner_item = value;
\r
185 if (this.owner_item != null)
\r
186 if (this.owner_item.Owner != null)
\r
187 this.Renderer = this.owner_item.Owner.Renderer;
\r
191 public new Region Region {
\r
192 get { return base.Region; }
\r
193 set { base.Region = value; }
\r
196 [Localizable (true)]
\r
197 public override RightToLeft RightToLeft {
\r
198 get { return base.RightToLeft; }
\r
199 set { base.RightToLeft = value; }
\r
202 [Browsable (false)]
\r
203 [EditorBrowsable (EditorBrowsableState.Never)]
\r
204 public new bool Stretch {
\r
205 get { return false; }
\r
209 [Browsable (false)]
\r
210 [EditorBrowsable (EditorBrowsableState.Never)]
\r
211 public new int TabIndex {
\r
216 public bool TopLevel {
\r
217 get { return this.TopMost; }
\r
221 [Localizable (true)]
\r
222 public new bool Visible {
\r
223 get { return base.Visible; }
\r
224 set { base.Visible = value; }
\r
228 #region Protected Properties
\r
229 protected override CreateParams CreateParams {
\r
231 CreateParams cp = base.CreateParams;
\r
233 cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_CLIPCHILDREN));
\r
234 cp.ClassStyle = unchecked ((int)0x82000000);
\r
235 cp.ExStyle |= (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST);
\r
237 if (Opacity < 1.0 && allow_transparency)
\r
238 cp.ExStyle |= (int)WindowExStyles.WS_EX_LAYERED;
\r
244 protected override DockStyle DefaultDock {
\r
245 get { return DockStyle.None; }
\r
248 protected override Padding DefaultPadding {
\r
249 get { return new Padding (1, 2, 1, 2); }
\r
252 protected override bool DefaultShowItemToolTips {
\r
253 get { return true; }
\r
256 //protected internal override Size MaxItemSize {
\r
257 // get { return new Size (Screen.PrimaryScreen.Bounds.Width - 2, Screen.PrimaryScreen.Bounds.Height - 34); }
\r
260 protected virtual bool TopMost {
\r
261 get { return true; }
\r
265 #region Public Methods
\r
266 public void Close ()
\r
268 this.Close (ToolStripDropDownCloseReason.CloseCalled);
\r
271 public void Close (ToolStripDropDownCloseReason reason)
\r
273 // Give users a chance to cancel the close
\r
274 ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs (reason);
\r
275 this.OnClosing (e);
\r
280 // Don't actually close if AutoClose == true unless explicitly called
\r
281 if (!this.auto_close && reason != ToolStripDropDownCloseReason.CloseCalled)
\r
284 // Detach from the tracker
\r
285 ToolStripManager.AppClicked -= new EventHandler (ToolStripMenuTracker_AppClicked); ;
\r
286 ToolStripManager.AppFocusChange -= new EventHandler (ToolStripMenuTracker_AppFocusChange);
\r
288 // Owner MenuItem needs to be told to redraw (it's no longer selected)
\r
289 if (owner_item != null)
\r
290 owner_item.Invalidate ();
\r
292 // Recursive hide all child dropdowns
\r
293 foreach (ToolStripItem tsi in this.Items)
\r
294 if (tsi is ToolStripMenuItem)
\r
295 (tsi as ToolStripMenuItem).HideDropDown (reason);
\r
297 // Hide this dropdown
\r
300 this.OnClosed (new ToolStripDropDownClosedEventArgs (reason));
\r
303 public new void Show ()
\r
305 CancelEventArgs e = new CancelEventArgs ();
\r
306 this.OnOpening (e);
\r
311 // The tracker lets us know when the form is clicked or loses focus
\r
312 ToolStripManager.AppClicked += new EventHandler (ToolStripMenuTracker_AppClicked);
\r
313 ToolStripManager.AppFocusChange += new EventHandler (ToolStripMenuTracker_AppFocusChange);
\r
317 this.OnOpened (EventArgs.Empty);
\r
320 public void Show (Point screenLocation)
\r
322 this.Location = screenLocation;
\r
326 public void Show (Control control, Point position)
\r
328 if (control == null)
\r
329 throw new ArgumentNullException ("control");
\r
331 this.Location = control.PointToScreen (position);
\r
335 public void Show (int x, int y)
\r
337 this.Location = new Point (x, y);
\r
341 public void Show (Control control, int x, int y)
\r
343 Show (control, new Point (x, y));
\r
348 #region Protected Methods
\r
349 protected override void CreateHandle ()
\r
351 base.CreateHandle ();
\r
354 protected override void Dispose (bool disposing)
\r
356 base.Dispose (disposing);
\r
359 protected virtual void OnClosed (ToolStripDropDownClosedEventArgs e)
\r
361 ToolStripDropDownClosedEventHandler eh = (ToolStripDropDownClosedEventHandler)(Events [ClosedEvent]);
\r
366 protected virtual void OnClosing (ToolStripDropDownClosingEventArgs e)
\r
368 ToolStripDropDownClosingEventHandler eh = (ToolStripDropDownClosingEventHandler)(Events [ClosingEvent]);
\r
373 protected override void OnHandleCreated (EventArgs e)
\r
375 base.OnHandleCreated (e);
\r
378 protected override void OnItemClicked (ToolStripItemClickedEventArgs e)
\r
380 base.OnItemClicked (e);
\r
383 protected override void OnLayout (LayoutEventArgs e)
\r
387 // Find the widest menu item
\r
390 foreach (ToolStripItem tsi in this.Items)
\r
391 if (tsi.GetPreferredSize (Size.Empty).Width > widest)
\r
392 widest = tsi.GetPreferredSize (Size.Empty).Width;
\r
394 int x = this.Padding.Left;
\r
395 widest += 68 - this.Padding.Horizontal;
\r
396 int y = this.Padding.Top;
\r
398 foreach (ToolStripItem tsi in this.Items) {
\r
399 y += tsi.Margin.Top;
\r
403 if (tsi is ToolStripSeparator)
\r
408 tsi.SetBounds (new Rectangle (x, y, widest, height));
\r
409 y += tsi.Height + tsi.Margin.Bottom;
\r
412 this.Size = new Size (widest + this.Padding.Horizontal, y + this.Padding.Bottom);// + 2);
\r
415 protected override void OnMouseUp (MouseEventArgs mea)
\r
417 base.OnMouseUp (mea);
\r
420 protected virtual void OnOpened (EventArgs e)
\r
422 EventHandler eh = (EventHandler)(Events [OpenedEvent]);
\r
427 protected virtual void OnOpening (CancelEventArgs e)
\r
429 CancelEventHandler eh = (CancelEventHandler)(Events [OpeningEvent]);
\r
434 protected override void OnParentChanged (EventArgs e)
\r
436 base.OnParentChanged (e);
\r
438 if (Parent is ToolStrip)
\r
439 this.Renderer = (Parent as ToolStrip).Renderer;
\r
442 protected override void OnVisibleChanged (EventArgs e)
\r
444 base.OnVisibleChanged (e);
\r
447 protected override bool ProcessDialogChar (char charCode)
\r
449 return base.ProcessDialogChar (charCode);
\r
452 protected override bool ProcessDialogKey (Keys keyData)
\r
454 return base.ProcessDialogKey (keyData);
\r
457 protected override bool ProcessMnemonic (char charCode)
\r
459 return base.ProcessMnemonic (charCode);
\r
462 protected override void ScaleCore (float dx, float dy)
\r
464 base.ScaleCore (dx, dy);
\r
467 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
\r
469 base.SetBoundsCore (x, y, width, height, specified);
\r
472 protected override void SetVisibleCore (bool value)
\r
474 base.SetVisibleCore (value);
\r
477 protected override void WndProc (ref Message m)
\r
479 const int MA_NOACTIVATE = 0x0003;
\r
481 // Don't activate when the WM tells us to
\r
482 if ((Msg)m.Msg == Msg.WM_MOUSEACTIVATE) {
\r
483 m.Result = (IntPtr)MA_NOACTIVATE;
\r
487 base.WndProc (ref m);
\r
491 #region Public Events
\r
492 static object ClosedEvent = new object ();
\r
493 static object ClosingEvent = new object ();
\r
494 static object OpenedEvent = new object ();
\r
495 static object OpeningEvent = new object ();
\r
496 static object ScrollEvent = new object ();
\r
498 public new event EventHandler BackgroundImageChanged {
\r
499 add { base.BackgroundImageChanged += value; }
\r
500 remove { base.BackgroundImageChanged -= value; }
\r
503 public new event EventHandler BackgroundImageLayoutChanged {
\r
504 add { base.BackgroundImageLayoutChanged += value; }
\r
505 remove { base.BackgroundImageLayoutChanged -= value; }
\r
508 public new event EventHandler BindingContextChanged {
\r
509 add { base.BindingContextChanged += value; }
\r
510 remove { base.BindingContextChanged -= value; }
\r
512 public new event UICuesEventHandler ChangeUICues {
\r
513 add { base.ChangeUICues += value; }
\r
514 remove { base.ChangeUICues -= value; }
\r
517 public event ToolStripDropDownClosedEventHandler Closed {
\r
518 add { Events.AddHandler (ClosedEvent, value); }
\r
519 remove { Events.RemoveHandler (ClosedEvent, value); }
\r
522 public event ToolStripDropDownClosingEventHandler Closing {
\r
523 add { Events.AddHandler (ClosingEvent, value); }
\r
524 remove { Events.RemoveHandler (ClosingEvent, value); }
\r
527 [Browsable (false)]
\r
528 [EditorBrowsable (EditorBrowsableState.Never)]
\r
529 public new event EventHandler ContextMenuChanged {
\r
530 add { base.ContextMenuChanged += value; }
\r
531 remove { base.ContextMenuChanged -= value; }
\r
534 [Browsable (false)]
\r
535 [EditorBrowsable (EditorBrowsableState.Never)]
\r
536 public new event EventHandler ContextMenuStripChanged {
\r
537 add { base.ContextMenuStripChanged += value; }
\r
538 remove { base.ContextMenuStripChanged -= value; }
\r
541 [Browsable (false)]
\r
542 [EditorBrowsable (EditorBrowsableState.Never)]
\r
543 public new event EventHandler DockChanged {
\r
544 add { base.DockChanged += value; }
\r
545 remove { base.DockChanged -= value; }
\r
548 public new event EventHandler Enter {
\r
549 add { base.Enter += value; }
\r
550 remove { base.Enter -= value; }
\r
553 public new event EventHandler FontChanged {
\r
554 add { base.FontChanged += value; }
\r
555 remove { base.FontChanged -= value; }
\r
558 public new event EventHandler ForeColorChanged {
\r
559 add { base.ForeColorChanged += value; }
\r
560 remove { base.ForeColorChanged -= value; }
\r
563 [Browsable (false)]
\r
564 [EditorBrowsable (EditorBrowsableState.Never)]
\r
565 public new event GiveFeedbackEventHandler GiveFeedback {
\r
566 add { base.GiveFeedback += value; }
\r
567 remove { base.GiveFeedback -= value; }
\r
570 public new event HelpEventHandler HelpRequested {
\r
571 add { base.HelpRequested += value; }
\r
572 remove { base.HelpRequested -= value; }
\r
575 public new event EventHandler ImeModeChanged {
\r
576 add { base.ImeModeChanged += value; }
\r
577 remove { base.ImeModeChanged -= value; }
\r
580 public new event KeyEventHandler KeyDown {
\r
581 add { base.KeyDown += value; }
\r
582 remove { base.KeyDown -= value; }
\r
585 public new event KeyPressEventHandler KeyPress {
\r
586 add { base.KeyPress += value; }
\r
587 remove { base.KeyPress -= value; }
\r
590 public new event KeyEventHandler KeyUp {
\r
591 add { base.KeyUp += value; }
\r
592 remove { base.KeyUp -= value; }
\r
595 public new event EventHandler Leave {
\r
596 add { base.Leave += value; }
\r
597 remove { base.Leave -= value; }
\r
600 public event EventHandler Opened {
\r
601 add { Events.AddHandler (OpenedEvent, value); }
\r
602 remove { Events.RemoveHandler (OpenedEvent, value); }
\r
605 public event CancelEventHandler Opening {
\r
606 add { Events.AddHandler (OpeningEvent, value); }
\r
607 remove { Events.RemoveHandler (OpeningEvent, value); }
\r
610 public new event EventHandler RegionChanged {
\r
611 add { base.RegionChanged += value; }
\r
612 remove { base.RegionChanged -= value; }
\r
615 [Browsable (false)]
\r
616 [EditorBrowsable (EditorBrowsableState.Never)]
\r
617 public event ScrollEventHandler Scroll {
\r
618 add { Events.AddHandler (ScrollEvent, value); }
\r
619 remove { Events.RemoveHandler (ScrollEvent, value); }
\r
622 public new event EventHandler StyleChanged {
\r
623 add { base.StyleChanged += value; }
\r
624 remove { base.StyleChanged -= value; }
\r
627 [Browsable (false)]
\r
628 [EditorBrowsable (EditorBrowsableState.Never)]
\r
629 public new event EventHandler TabIndexChanged {
\r
630 add { base.TabIndexChanged += value; }
\r
631 remove { base.TabIndexChanged -= value; }
\r
634 [Browsable (false)]
\r
635 [EditorBrowsable (EditorBrowsableState.Never)]
\r
636 public new event EventHandler TabStopChanged {
\r
637 add { base.TabStopChanged += value; }
\r
638 remove { base.TabStopChanged -= value; }
\r
641 [Browsable (false)]
\r
642 [EditorBrowsable (EditorBrowsableState.Never)]
\r
643 public new event EventHandler TextChanged {
\r
644 add { base.TextChanged += value; }
\r
645 remove { base.TextChanged -= value; }
\r
648 [Browsable (false)]
\r
649 [EditorBrowsable (EditorBrowsableState.Never)]
\r
650 public new event EventHandler Validated {
\r
651 add { base.Validated += value; }
\r
652 remove { base.Validated -= value; }
\r
655 [Browsable (false)]
\r
656 [EditorBrowsable (EditorBrowsableState.Never)]
\r
657 public new event CancelEventHandler Validating {
\r
658 add { base.Validating += value; }
\r
659 remove { base.Validating -= value; }
\r
663 #region Private Methods
\r
664 private void ToolStripMenuTracker_AppFocusChange (object sender, EventArgs e)
\r
666 this.Close (ToolStripDropDownCloseReason.AppFocusChange);
\r
669 private void ToolStripMenuTracker_AppClicked (object sender, EventArgs e)
\r
671 this.Close (ToolStripDropDownCloseReason.AppClicked);
\r