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 [EditorBrowsable (EditorBrowsableState.Never)]
\r
62 public bool AllowTransparency {
\r
63 get { return allow_transparency; }
\r
65 if (value == allow_transparency)
\r
68 if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0) {
\r
69 allow_transparency = value;
\r
72 XplatUI.SetWindowTransparency (Handle, Opacity, Color.Empty);
\r
74 UpdateStyles (); // Remove the WS_EX_LAYERED style
\r
80 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
81 public override AnchorStyles Anchor {
\r
82 get { return base.Anchor; }
\r
83 set { base.Anchor = value; }
\r
87 [EditorBrowsable (EditorBrowsableState.Never)]
\r
88 public bool AutoClose
\r
90 get { return this.auto_close; }
\r
91 set { this.auto_close = value; }
\r
94 [DefaultValue (true)]
\r
95 public override bool AutoSize {
\r
96 get { return base.AutoSize; }
\r
97 set { base.AutoSize = value; }
\r
100 [Browsable (false)]
\r
101 [EditorBrowsable (EditorBrowsableState.Never)]
\r
102 public ContextMenu ContextMenu {
\r
103 get { return null; }
\r
107 //[Browsable (false)]
\r
108 //[EditorBrowsable (EditorBrowsableState.Never)]
\r
109 //public ContextMenuStrip ContextMenuStrip {
\r
110 // get { return null; }
\r
114 [Browsable (false)]
\r
115 [EditorBrowsable (EditorBrowsableState.Never)]
\r
116 public override DockStyle Dock {
\r
117 get { return base.Dock; }
\r
118 set { base.Dock = value; }
\r
121 public bool DropShadowEnabled {
\r
122 get { return this.drop_shadow_enabled; }
\r
124 if (this.drop_shadow_enabled == value)
\r
127 this.drop_shadow_enabled = value;
\r
128 UpdateStyles (); // Re-CreateParams
\r
132 public override Font Font {
\r
133 get { return base.Font; }
\r
134 set { base.Font = value; }
\r
137 [Browsable (false)]
\r
138 [EditorBrowsable (EditorBrowsableState.Never)]
\r
139 public ToolStripGripDisplayStyle GripDisplayStyle {
\r
140 get { return ToolStripGripDisplayStyle.Vertical; }
\r
144 [Browsable (false)]
\r
145 [EditorBrowsable (EditorBrowsableState.Never)]
\r
146 public Padding GripMargin {
\r
147 get { return Padding.Empty; }
\r
151 [Browsable (false)]
\r
152 [EditorBrowsable (EditorBrowsableState.Never)]
\r
153 public Rectangle GripRectangle {
\r
154 get { return Rectangle.Empty; }
\r
158 [Browsable (false)]
\r
159 [EditorBrowsable (EditorBrowsableState.Never)]
\r
160 public ToolStripGripStyle GripStyle {
\r
161 get { return base.GripStyle; }
\r
162 set { base.GripStyle = value; }
\r
165 [Browsable (false)]
\r
166 [EditorBrowsable (EditorBrowsableState.Never)]
\r
167 public Point Location {
\r
168 get { return base.Location; }
\r
169 set { base.Location = value; }
\r
172 public double Opacity {
\r
173 get { return this.opacity; }
\r
175 if (this.opacity == value)
\r
178 this.opacity = value;
\r
179 this.allow_transparency = true;
\r
182 XplatUI.SetWindowTransparency (Handle, opacity, Color.Empty);
\r
186 public ToolStripItem OwnerItem {
\r
187 get { return this.owner_item; }
\r
188 set { this.owner_item = value;
\r
190 if (this.owner_item != null)
\r
191 if (this.owner_item.Owner != null)
\r
192 this.Renderer = this.owner_item.Owner.Renderer;
\r
196 public Region Region {
\r
197 get { return base.Region; }
\r
198 set { base.Region = value; }
\r
201 [Localizable (true)]
\r
202 public override RightToLeft RightToLeft {
\r
203 get { return base.RightToLeft; }
\r
204 set { base.RightToLeft = value; }
\r
207 [Browsable (false)]
\r
208 [EditorBrowsable (EditorBrowsableState.Never)]
\r
209 public bool Stretch {
\r
210 get { return false; }
\r
214 [Browsable (false)]
\r
215 [EditorBrowsable (EditorBrowsableState.Never)]
\r
216 public int TabIndex {
\r
221 public bool TopLevel {
\r
222 get { return this.TopMost; }
\r
226 [Localizable (true)]
\r
227 public bool Visible {
\r
228 get { return base.Visible; }
\r
229 set { base.Visible = value; }
\r
233 #region Protected Properties
\r
234 protected override CreateParams CreateParams {
\r
236 CreateParams cp = base.CreateParams;
\r
238 cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_CLIPCHILDREN));
\r
239 cp.ClassStyle = unchecked ((int)0x82000000);
\r
240 cp.ExStyle |= (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST);
\r
242 if (Opacity < 1.0 && allow_transparency)
\r
243 cp.ExStyle |= (int)WindowExStyles.WS_EX_LAYERED;
\r
249 protected override DockStyle DefaultDock {
\r
250 get { return DockStyle.None; }
\r
253 protected override Padding DefaultPadding {
\r
254 get { return new Padding (1, 2, 1, 2); }
\r
257 protected override bool DefaultShowItemToolTips {
\r
258 get { return true; }
\r
261 //protected internal override Size MaxItemSize {
\r
262 // get { return new Size (Screen.PrimaryScreen.Bounds.Width - 2, Screen.PrimaryScreen.Bounds.Height - 34); }
\r
265 protected virtual bool TopMost {
\r
266 get { return true; }
\r
270 #region Public Methods
\r
271 public void Close ()
\r
273 this.Close (ToolStripDropDownCloseReason.CloseCalled);
\r
276 public void Close (ToolStripDropDownCloseReason reason)
\r
278 // Give users a chance to cancel the close
\r
279 ToolStripDropDownClosingEventArgs e = new ToolStripDropDownClosingEventArgs (reason);
\r
280 this.OnClosing (e);
\r
285 // Don't actually close if AutoClose == true unless explicitly called
\r
286 if (!this.auto_close && reason != ToolStripDropDownCloseReason.CloseCalled)
\r
289 // Detach from the tracker
\r
290 ToolStripManager.AppClicked -= new EventHandler (ToolStripMenuTracker_AppClicked); ;
\r
291 ToolStripManager.AppFocusChange -= new EventHandler (ToolStripMenuTracker_AppFocusChange);
\r
293 // Owner MenuItem needs to be told to redraw (it's no longer selected)
\r
294 if (owner_item != null)
\r
295 owner_item.Invalidate ();
\r
297 // Recursive hide all child dropdowns
\r
298 foreach (ToolStripItem tsi in this.Items)
\r
299 if (tsi is ToolStripMenuItem)
\r
300 (tsi as ToolStripMenuItem).HideDropDown (reason);
\r
302 // Hide this dropdown
\r
305 this.OnClosed (new ToolStripDropDownClosedEventArgs (reason));
\r
308 public void Show ()
\r
310 CancelEventArgs e = new CancelEventArgs ();
\r
311 this.OnOpening (e);
\r
316 // The tracker lets us know when the form is clicked or loses focus
\r
317 ToolStripManager.AppClicked += new EventHandler (ToolStripMenuTracker_AppClicked);
\r
318 ToolStripManager.AppFocusChange += new EventHandler (ToolStripMenuTracker_AppFocusChange);
\r
322 this.OnOpened (EventArgs.Empty);
\r
325 public void Show (Point screenLocation)
\r
327 this.Location = screenLocation;
\r
331 public void Show (Control control, Point position)
\r
333 if (control == null)
\r
334 throw new ArgumentNullException ("control");
\r
336 this.Location = control.PointToScreen (position);
\r
339 public void Show (int x, int y)
\r
341 this.Location = new Point (x, y);
\r
345 public void Show (Control control, int x, int y)
\r
347 Show (control, new Point (x, y));
\r
352 #region Protected Methods
\r
353 protected override void CreateHandle ()
\r
355 base.CreateHandle ();
\r
358 protected override void Dispose (bool disposing)
\r
360 base.Dispose (disposing);
\r
363 protected virtual void OnClosed (ToolStripDropDownClosedEventArgs e)
\r
365 if (Closed != null) Closed (this, e);
\r
368 protected virtual void OnClosing (ToolStripDropDownClosingEventArgs e)
\r
370 if (Closing != null) Closing (this, e);
\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 if (Opened != null) Opened (this, e);
\r
425 protected virtual void OnOpening (CancelEventArgs e)
\r
427 if (Opening != null) Opening (this, e);
\r
430 protected override void OnParentChanged (EventArgs e)
\r
432 base.OnParentChanged (e);
\r
434 if (parent is ToolStrip)
\r
435 this.Renderer = (parent as ToolStrip).Renderer;
\r
438 protected override void OnVisibleChanged (EventArgs e)
\r
440 base.OnVisibleChanged (e);
\r
443 protected override bool ProcessDialogChar (char charCode)
\r
445 return base.ProcessDialogChar (charCode);
\r
448 protected override bool ProcessDialogKey (Keys keyData)
\r
450 return base.ProcessDialogKey (keyData);
\r
453 protected override bool ProcessMnemonic (char charCode)
\r
455 return base.ProcessMnemonic (charCode);
\r
458 protected override void ScaleCore (float dx, float dy)
\r
460 base.ScaleCore (dx, dy);
\r
463 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
\r
465 base.SetBoundsCore (x, y, width, height, specified);
\r
468 protected override void SetVisibleCore (bool value)
\r
470 base.SetVisibleCore (value);
\r
473 protected override void WndProc (ref Message m)
\r
475 const int MA_NOACTIVATE = 0x0003;
\r
477 // Don't activate when the WM tells us to
\r
478 if ((Msg)m.Msg == Msg.WM_MOUSEACTIVATE) {
\r
479 m.Result = (IntPtr)MA_NOACTIVATE;
\r
483 base.WndProc (ref m);
\r
487 #region Public Events
\r
488 public event EventHandler BackgroundImageChanged;
\r
489 public event EventHandler BackgroundImageLayoutChanged;
\r
490 public event EventHandler BindingContextChanged;
\r
491 public event UICuesEventHandler ChangeUICues;
\r
492 public event ToolStripDropDownClosedEventHandler Closed;
\r
493 public event ToolStripDropDownClosingEventHandler Closing;
\r
494 [Browsable (false)]
\r
495 [EditorBrowsable (EditorBrowsableState.Never)]
\r
496 public event EventHandler ContextMenuChanged;
\r
497 [Browsable (false)]
\r
498 [EditorBrowsable (EditorBrowsableState.Never)]
\r
499 public event EventHandler ContextMenuStripChanged;
\r
500 [Browsable (false)]
\r
501 [EditorBrowsable (EditorBrowsableState.Never)]
\r
502 public event EventHandler DockChanged;
\r
503 public event EventHandler Enter;
\r
504 public event EventHandler FontChanged;
\r
505 public event EventHandler ForeColorChanged;
\r
506 [Browsable (false)]
\r
507 [EditorBrowsable (EditorBrowsableState.Never)]
\r
508 public event GiveFeedbackEventHandler GiveFeedback;
\r
509 public event HelpEventHandler HelpRequested;
\r
510 public event EventHandler ImeModeChanged;
\r
511 public event KeyEventHandler KeyDown;
\r
512 public event KeyPressEventHandler KeyPress;
\r
513 public event KeyEventHandler KeyUp;
\r
514 public event EventHandler Leave;
\r
515 public event EventHandler Opened;
\r
516 public event CancelEventHandler Opening;
\r
517 public event EventHandler RegionChanged;
\r
518 [Browsable (false)]
\r
519 [EditorBrowsable (EditorBrowsableState.Never)]
\r
520 public event ScrollEventHandler Scroll;
\r
521 public event EventHandler StyleChanged;
\r
522 [Browsable (false)]
\r
523 [EditorBrowsable (EditorBrowsableState.Never)]
\r
524 public event EventHandler TabIndexChanged;
\r
525 [Browsable (false)]
\r
526 [EditorBrowsable (EditorBrowsableState.Never)]
\r
527 public event EventHandler TabStopChanged;
\r
528 [Browsable (false)]
\r
529 [EditorBrowsable (EditorBrowsableState.Never)]
\r
530 public event EventHandler TextChanged;
\r
531 [Browsable (false)]
\r
532 [EditorBrowsable (EditorBrowsableState.Never)]
\r
533 public event EventHandler Validated;
\r
534 [Browsable (false)]
\r
535 [EditorBrowsable (EditorBrowsableState.Never)]
\r
536 public event CancelEventHandler Validating;
\r
539 #region Private Methods
\r
540 private void ToolStripMenuTracker_AppFocusChange (object sender, EventArgs e)
\r
542 this.Close (ToolStripDropDownCloseReason.AppFocusChange);
\r
545 private void ToolStripMenuTracker_AppClicked (object sender, EventArgs e)
\r
547 this.Close (ToolStripDropDownCloseReason.AppClicked);
\r