1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //	Peter Bartok	pbartok@novell.com
24 //
25 //
26 
27 using System;
28 using System.ComponentModel;
29 using System.ComponentModel.Design;
30 using System.Drawing;
31 using System.Drawing.Text;
32 
33 namespace System.Windows.Forms {
34 	[DefaultProperty("Text")]
35 	[DefaultEvent("MouseDoubleClick")]
36 	[Designer ("System.Windows.Forms.Design.NotifyIconDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
37 	[ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow)]
38 	public sealed class NotifyIcon : Component {
39 		#region Local Variables
40 		private ContextMenu		context_menu;
41 		private Icon			icon;
42 		private Bitmap			icon_bitmap;
43 		private string			text;
44 		private bool			visible;
45 		private NotifyIconWindow	window;
46 		private bool			systray_active;
47 		private ToolTip			tooltip;
48 		private bool			double_click;
49 		private string balloon_text;
50 		private string balloon_title;
51 		private ToolTipIcon balloon_icon;
52 		private ContextMenuStrip	context_menu_strip;
53 		private object			tag;
54 		#endregion	// Local Variables
55 
56 		#region NotifyIconWindow Class
57 		internal class NotifyIconWindow : Form {
58 			NotifyIcon	owner;
59 			Rectangle	rect;
60 
NotifyIconWindow(NotifyIcon owner)61 			public NotifyIconWindow(NotifyIcon owner) {
62 				this.owner = owner;
63 				is_visible = false;
64 				rect = new Rectangle(0, 0, 1, 1);
65 
66 				FormBorderStyle = FormBorderStyle.None;
67 
68 				//CreateControl();
69 
70 				SizeChanged += new EventHandler(HandleSizeChanged);
71 
72 				// Events that need to be sent to our parent
73 				DoubleClick += new EventHandler(HandleDoubleClick);
74 				MouseDown +=new MouseEventHandler(HandleMouseDown);
75 				MouseUp +=new MouseEventHandler(HandleMouseUp);
76 				MouseMove +=new MouseEventHandler(HandleMouseMove);
77 				ContextMenu = owner.context_menu;
78 				ContextMenuStrip = owner.context_menu_strip;
79 			}
80 
81 			protected override CreateParams CreateParams {
82 				get {
83 					CreateParams cp;
84 
85 					cp = base.CreateParams;
86 
87 					cp.Parent = IntPtr.Zero;
88 					cp.Style = (int)WindowStyles.WS_POPUP;
89 					cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;
90 
91 					cp.ExStyle = (int)(WindowExStyles.WS_EX_TOOLWINDOW);
92 
93 					return cp;
94 				}
95 			}
96 
WndProc(ref Message m)97 			protected override void WndProc(ref Message m) {
98 				switch((Msg)m.Msg) {
99 						//
100 						//  NotifyIcon does CONTEXTMENU on mouse up, not down
101 						//  so we swallow the message here, and handle it on our own
102 						//
103 				        case Msg.WM_CONTEXTMENU:
104 						return;
105 
106 					case Msg.WM_USER: {
107 						switch ((Msg)m.LParam.ToInt32()) {
108 							case Msg.WM_LBUTTONDOWN: {
109 								owner.OnMouseDown (new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
110 								return;
111 							}
112 
113 							case Msg.WM_LBUTTONUP: {
114 								owner.OnMouseUp (new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
115 								return;
116 							}
117 
118 							case Msg.WM_LBUTTONDBLCLK: {
119 								owner.OnDoubleClick (EventArgs.Empty);
120 								owner.OnMouseDoubleClick (new MouseEventArgs (MouseButtons.Left, 2, Control.MousePosition.X, Control.MousePosition.Y, 0));
121 								return;
122 							}
123 
124 							case Msg.WM_MOUSEMOVE: {
125 								owner.OnMouseMove (new MouseEventArgs(MouseButtons.None, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
126 								return;
127 							}
128 
129 							case Msg.WM_RBUTTONDOWN: {
130 								owner.OnMouseDown (new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
131 								return;
132 							}
133 
134 							case Msg.WM_RBUTTONUP: {
135 								owner.OnMouseUp (new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
136 								return;
137 							}
138 
139 							case Msg.WM_RBUTTONDBLCLK: {
140 								owner.OnDoubleClick (EventArgs.Empty);
141 								owner.OnMouseDoubleClick (new MouseEventArgs (MouseButtons.Left, 2, Control.MousePosition.X, Control.MousePosition.Y, 0));
142 								return;
143 							}
144 
145 							case Msg.NIN_BALLOONUSERCLICK: {
146 								owner.OnBalloonTipClicked (EventArgs.Empty);
147 								return;
148 							}
149 
150 							case Msg.NIN_BALLOONSHOW: {
151 								owner.OnBalloonTipShown (EventArgs.Empty);
152 								return;
153 							}
154 
155 							case Msg.NIN_BALLOONHIDE:
156 							case Msg.NIN_BALLOONTIMEOUT: {
157 								owner.OnBalloonTipClosed (EventArgs.Empty);
158 								return;
159 							}
160 						}
161 						return;
162 					}
163 				}
164 				base.WndProc (ref m);
165 			}
166 
CalculateIconRect()167 			internal void CalculateIconRect() {
168 				int		x;
169 				int		y;
170 				int		size;
171 
172 				// Icons are always square. Try to center them in the window
173 				if (ClientRectangle.Width < ClientRectangle.Height) {
174 					size = ClientRectangle.Width;
175 				} else {
176 					size = ClientRectangle.Height;
177 				}
178 				x = this.ClientRectangle.Width / 2 - size / 2;
179 				y = this.ClientRectangle.Height / 2 - size / 2;
180 				rect = new Rectangle(x, y, size, size);
181 
182 				Bounds = new Rectangle (0, 0, size, size);
183 			}
184 
OnPaintInternal(PaintEventArgs e)185 			internal override void OnPaintInternal (PaintEventArgs e) {
186 				if (owner.icon != null) {
187 					// At least in Gnome, the background of the panel is the same as the Menu, so we go for it
188 					// instead of (most of the time) plain white.
189 					e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(SystemColors.Menu), rect);
190 					e.Graphics.DrawImage(owner.icon_bitmap,
191 							     rect,
192 							     new Rectangle (0, 0, owner.icon_bitmap.Width, owner.icon_bitmap.Height),
193 							     GraphicsUnit.Pixel);
194 
195 				}
196 			}
197 
InternalRecreateHandle()198 			internal void InternalRecreateHandle () {
199 				base.RecreateHandle ();
200 			}
201 
HandleSizeChanged(object sender, EventArgs e)202 			private void HandleSizeChanged(object sender, EventArgs e) {
203 				owner.Recalculate ();
204 			}
205 
HandleDoubleClick(object sender, EventArgs e)206 			private void HandleDoubleClick (object sender, EventArgs e)
207 			{
208 				owner.OnDoubleClick (e);
209 				owner.OnMouseDoubleClick (new MouseEventArgs (MouseButtons.Left, 2, Control.MousePosition.X, Control.MousePosition.Y, 0));
210 			}
211 
HandleMouseDown(object sender, MouseEventArgs e)212 			private void HandleMouseDown (object sender, MouseEventArgs e)
213 			{
214 				owner.OnMouseDown (e);
215 			}
216 
HandleMouseUp(object sender, MouseEventArgs e)217 			private void HandleMouseUp (object sender, MouseEventArgs e)
218 			{
219 				owner.OnMouseUp (e);
220 			}
221 
HandleMouseMove(object sender, MouseEventArgs e)222 			private void HandleMouseMove (object sender, MouseEventArgs e)
223 			{
224 				owner.OnMouseMove (e);
225 			}
226 		}
227 		#endregion	// NotifyIconWindow Class
228 
229 		#region NotifyIconBalloonWindow Class
230 		internal class BalloonWindow : Form
231 		{
232 			private IntPtr owner;
233 			private Timer timer;
234 
235 			private string title;
236 			private string text;
237 			private ToolTipIcon icon;
238 
BalloonWindow(IntPtr owner)239 			public BalloonWindow (IntPtr owner)
240 			{
241 				this.owner = owner;
242 
243 				StartPosition = FormStartPosition.Manual;
244 				FormBorderStyle = FormBorderStyle.None;
245 
246 				MouseDown += new MouseEventHandler (HandleMouseDown);
247 
248 				timer = new Timer ();
249 				timer.Enabled = false;
250 				timer.Tick += new EventHandler (HandleTimer);
251 			}
252 
253 			public IntPtr OwnerHandle {
254 				get {
255 					return owner;
256 				}
257 			}
258 
Dispose(bool disposing)259 			protected override void Dispose (bool disposing)
260 			{
261 				if (disposing) {
262 					timer.Stop();
263 					timer.Dispose();
264 				}
265 				base.Dispose (disposing);
266 			}
267 
268 			protected override CreateParams CreateParams {
269 				get {
270 					CreateParams cp;
271 
272 					cp = base.CreateParams;
273 
274 					cp.Style = (int)WindowStyles.WS_POPUP;
275 					cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;
276 
277 					cp.ExStyle = (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST);
278 
279 					return cp;
280 				}
281 			}
282 
Close()283 			public new void Close () {
284 				base.Close ();
285 				XplatUI.SendMessage (owner, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONHIDE);
286 			}
287 
OnShown(EventArgs e)288 			protected override void OnShown (EventArgs e)
289 			{
290 				base.OnShown (e);
291 				timer.Start ();
292 			}
293 
OnPaint(PaintEventArgs e)294 			protected override void OnPaint (PaintEventArgs e)
295 			{
296 				ThemeEngine.Current.DrawBalloonWindow (e.Graphics, ClientRectangle, this);
297 				base.OnPaint (e);
298 			}
299 
Recalculate()300 			private void Recalculate ()
301 			{
302 				Rectangle rect = ThemeEngine.Current.BalloonWindowRect (this);
303 
304 				Left = rect.Left;
305 				Top = rect.Top;
306 				Width = rect.Width;
307 				Height = rect.Height;
308 			}
309 
310 			// To be used when we have a "close button" inside balloon.
311 			//private void HandleClick (object sender, EventArgs e)
312 			//{
313 			//	Close ();
314 			//}
315 
HandleMouseDown(object sender, MouseEventArgs e)316 			private void HandleMouseDown (object sender, MouseEventArgs e)
317 			{
318 				XplatUI.SendMessage (owner, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONUSERCLICK);
319 				base.Close ();
320 			}
321 
HandleTimer(object sender, EventArgs e)322 			private void HandleTimer (object sender, EventArgs e)
323 			{
324 				timer.Stop ();
325 				XplatUI.SendMessage (owner, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONTIMEOUT);
326 				base.Close ();
327 			}
328 
329 			internal StringFormat Format {
330 				get {
331 					StringFormat format = new StringFormat ();
332 					format.Alignment = StringAlignment.Near;
333 					format.HotkeyPrefix = HotkeyPrefix.Hide;
334 
335 					return format;
336 				}
337 			}
338 
339 			public new ToolTipIcon Icon {
340 				get { return this.icon; }
341 				set {
342 					if (value == this.icon)
343 						return;
344 
345 					this.icon = value;
346 					Recalculate ();
347 				}
348 			}
349 
350 			public string Title {
351 				get { return this.title; }
352 				set {
353 					if (value == this.title)
354 						return;
355 
356 					this.title = value;
357 					Recalculate ();
358 				}
359 			}
360 
361 			public override string Text {
362 				get { return this.text; }
363 				set {
364 					if (value == this.text)
365 						return;
366 
367 					this.text = value;
368 					Recalculate ();
369 				}
370 			}
371 
372 			public int Timeout {
373 				get { return timer.Interval; }
374 				set {
375 					// Some systems theres a limitiation in timeout, WinXP is between 10k and 30k.
376 					if (value < 10000)
377 						timer.Interval = 10000;
378 					else if (value > 30000)
379 						timer.Interval = 30000;
380 					else
381 						timer.Interval = value;
382 				}
383 			}
384 		}
385 		#endregion  // NotifyIconBalloonWindow Class
386 
387 		#region Public Constructors
NotifyIcon()388 		public NotifyIcon() {
389 			window = new NotifyIconWindow(this);
390 			systray_active = false;
391 
392 			balloon_title = "";
393 			balloon_text = "";
394 		}
395 
NotifyIcon(System.ComponentModel.IContainer container)396 		public NotifyIcon(System.ComponentModel.IContainer container) : this() {
397 		}
398 		#endregion	// Public Constructors
399 
400 		#region Public Methods
ShowBalloonTip(int timeout)401 		public void ShowBalloonTip (int timeout)
402 		{
403 			ShowBalloonTip(timeout, balloon_title, balloon_text, balloon_icon);
404 		}
405 
ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon)406 		public void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon)
407 		{
408 			XplatUI.SystrayBalloon(window.Handle, timeout, tipTitle, tipText, tipIcon);
409 		}
410 		#endregion Public Methods
411 
412 		#region Private Methods
OnBalloonTipClicked(EventArgs e)413 		private void OnBalloonTipClicked (EventArgs e)
414 		{
415 			EventHandler eh = (EventHandler)(Events [BalloonTipClickedEvent]);
416 			if (eh != null)
417 				eh (this, e);
418 		}
419 
OnBalloonTipClosed(EventArgs e)420 		private void OnBalloonTipClosed (EventArgs e)
421 		{
422 			EventHandler eh = (EventHandler)(Events [BalloonTipClosedEvent]);
423 			if (eh != null)
424 				eh (this, e);
425 		}
426 
OnBalloonTipShown(EventArgs e)427 		private void OnBalloonTipShown (EventArgs e)
428 		{
429 			EventHandler eh = (EventHandler)(Events [BalloonTipShownEvent]);
430 			if (eh != null)
431 				eh (this, e);
432 		}
433 
OnClick(EventArgs e)434 		private void OnClick (EventArgs e)
435 		{
436 			EventHandler eh = (EventHandler)(Events [ClickEvent]);
437 			if (eh != null)
438 				eh (this, e);
439 		}
440 
OnDoubleClick(EventArgs e)441 		private void OnDoubleClick (EventArgs e)
442 		{
443 			double_click = true;
444 			EventHandler eh = (EventHandler)(Events [DoubleClickEvent]);
445 			if (eh != null)
446 				eh (this, e);
447 		}
448 
OnMouseClick(MouseEventArgs e)449 		private void OnMouseClick (MouseEventArgs e)
450 		{
451 			MouseEventHandler eh = (MouseEventHandler)(Events[MouseClickEvent]);
452 			if (eh != null)
453 				eh (this, e);
454 		}
455 
OnMouseDoubleClick(MouseEventArgs e)456 		private void OnMouseDoubleClick (MouseEventArgs e)
457 		{
458 			MouseEventHandler eh = (MouseEventHandler)(Events[MouseDoubleClickEvent]);
459 			if (eh != null)
460 				eh (this, e);
461 		}
462 
OnMouseDown(MouseEventArgs e)463 		private void OnMouseDown (MouseEventArgs e)
464 		{
465 			MouseEventHandler eh = (MouseEventHandler)(Events [MouseDownEvent]);
466 			if (eh != null)
467 				eh (this, e);
468 		}
469 
OnMouseUp(MouseEventArgs e)470 		private void OnMouseUp (MouseEventArgs e)
471 		{
472 			if ((e.Button & MouseButtons.Right) == MouseButtons.Right) {
473 				if (context_menu != null) {
474 					XplatUI.SetForegroundWindow (window.Handle);
475 					context_menu.Show (window, new Point(e.X, e.Y));
476 				}
477 				else if (context_menu_strip != null) {
478 					XplatUI.SetForegroundWindow (window.Handle);
479 					context_menu_strip.Show (window, new Point (e.X, e.Y), ToolStripDropDownDirection.AboveLeft);
480 				}
481 			}
482 
483 			MouseEventHandler eh = (MouseEventHandler)(Events [MouseUpEvent]);
484 			if (eh != null)
485 				eh (this, e);
486 
487 			if (!double_click) {
488 				OnClick (EventArgs.Empty);
489 				OnMouseClick (e);
490 				double_click = false;
491 			}
492 		}
493 
OnMouseMove(MouseEventArgs e)494 		private void OnMouseMove (MouseEventArgs e)
495 		{
496 			MouseEventHandler eh = (MouseEventHandler)(Events [MouseMoveEvent]);
497 			if (eh != null)
498 				eh (this, e);
499 		}
500 
Recalculate()501 		private void Recalculate ()
502 		{
503 			window.CalculateIconRect ();
504 
505 			if (!Visible || (text == string.Empty && icon == null)) {
506 				HideSystray ();
507 			} else {
508 
509 				if (systray_active)
510 					UpdateSystray ();
511 				else
512 					ShowSystray ();
513 			}
514 		}
515 
ShowSystray()516 		private void ShowSystray()
517 		{
518 			if (icon == null)
519 				return;
520 
521 			icon_bitmap = icon.ToBitmap();
522 
523 			systray_active = true;
524 			XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip);
525 		}
526 
HideSystray()527 		private void HideSystray()
528 		{
529 			if (!systray_active) {
530 				return;
531 			}
532 
533 			systray_active = false;
534 			XplatUI.SystrayRemove(window.Handle, ref tooltip);
535 		}
536 
UpdateSystray()537 		private void UpdateSystray()
538 		{
539 			if (icon_bitmap != null) {
540 				icon_bitmap.Dispose();
541 			}
542 
543 			if (icon != null) {
544 				icon_bitmap = icon.ToBitmap();
545 			}
546 
547 			window.Invalidate();
548 			XplatUI.SystrayChange(window.Handle, text, icon, ref tooltip);
549 		}
550 		#endregion	// Private Methods
551 
552 		#region Public Instance Properties
553 		[DefaultValue ("None")]
554 		public ToolTipIcon BalloonTipIcon {
555 			get { return this.balloon_icon; }
556 			set {
557 				if (value == this.balloon_icon)
558 					return;
559 
560             	this.balloon_icon = value;
561 			}
562 		}
563 
564 		[Localizable(true)]
565 		[DefaultValue ("")]
566 		[Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design,
567 			 "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
568 		public string BalloonTipText {
569 			get { return this.balloon_text; }
570 			set {
571 				if (value == this.balloon_text)
572 					return;
573 
574 				this.balloon_text = value;
575 			}
576 		}
577 
578 		[Localizable(true)]
579 		[DefaultValue ("")]
580 		public string BalloonTipTitle {
581 			get { return this.balloon_title; }
582 			set {
583 				if (value == this.balloon_title)
584 					return;
585 
586 				this.balloon_title = value;
587 			}
588 		}
589 
590 		[DefaultValue(null)]
591 		[Browsable (false)]
592 		public ContextMenu ContextMenu {
593 			get {
594 				return context_menu;
595 			}
596 
597 			set {
598 				if (context_menu != value) {
599 					context_menu = value;
600 					window.ContextMenu = value;
601 				}
602 			}
603 		}
604 
605 		[DefaultValue (null)]
606 		public ContextMenuStrip ContextMenuStrip {
607 			get { return this.context_menu_strip; }
608 			set {
609 				if (this.context_menu_strip != value) {
610 					this.context_menu_strip = value;
611 					window.ContextMenuStrip = value;
612 				}
613 			}
614 		}
615 
616 		[Localizable(true)]
617 		[DefaultValue(null)]
618 		public Icon Icon {
619 			get {
620 				return icon;
621 			}
622 
623 			set {
624 				if (icon != value) {
625 					icon = value;
626 					Recalculate ();
627 				}
628 			}
629 		}
630 
631 		[Localizable (false)]
632 		[Bindable (true)]
633 		[TypeConverter (typeof (StringConverter))]
634 		[DefaultValue (null)]
635 		public object Tag {
636 			get { return this.tag; }
637 			set { this.tag = value; }
638 		}
639 
640 		[DefaultValue ("")]
641 		[Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design,
642 			 typeof (System.Drawing.Design.UITypeEditor))]
643 		[Localizable (true)]
644 		public string Text {
645 			get {
646 				return text;
647 			}
648 
649 			set {
650 				if (text != value) {
651 					if (value.Length >= 64) {
652 						throw new ArgumentException("ToolTip length must be less than 64 characters long", "Text");
653 					}
654 					text = value;
655 					Recalculate ();
656 				}
657 			}
658 		}
659 
660 		[Localizable(true)]
661 		[DefaultValue(false)]
662 		public bool Visible {
663 			get {
664 				return visible;
665 			}
666 
667 			set {
668 				if (visible != value) {
669 					visible = value;
670 
671 					// Let our control know, too
672 					window.is_visible = value;
673 
674 					if (visible) {
675 						ShowSystray ();
676 					} else {
677 						HideSystray();
678 					}
679 				}
680 			}
681 		}
682 		#endregion	// Public Instance Properties
683 
684 		#region Protected Instance Methods
Dispose(bool disposing)685 		protected override void Dispose(bool disposing) {
686 			if (visible)
687 				HideSystray();
688 
689 			if (icon_bitmap != null) {
690 				icon_bitmap.Dispose();
691 			}
692 
693 			if (disposing)
694 				icon = null;
695 
696 			base.Dispose (disposing);
697 		}
698 
699 		#endregion	// Protected Instance Methods
700 
701 		#region Events
702 		static object ClickEvent = new object ();
703 		static object DoubleClickEvent = new object ();
704 		static object MouseDownEvent = new object ();
705 		static object MouseMoveEvent = new object ();
706 		static object MouseUpEvent = new object ();
707 		static object BalloonTipClickedEvent = new object ();
708 		static object BalloonTipClosedEvent = new object ();
709 		static object BalloonTipShownEvent = new object ();
710 		static object MouseClickEvent = new object ();
711 		static object MouseDoubleClickEvent = new object ();
712 
713 		[MWFCategory("Action")]
714 		public event EventHandler BalloonTipClicked {
715 			add { Events.AddHandler (BalloonTipClickedEvent, value); }
716 			remove { Events.RemoveHandler (BalloonTipClickedEvent, value); }
717 		}
718 
719 		[MWFCategory("Action")]
720 		public event EventHandler BalloonTipClosed {
721 			add { Events.AddHandler (BalloonTipClosedEvent, value); }
722 			remove { Events.RemoveHandler (BalloonTipClosedEvent, value); }
723 		}
724 
725 		[MWFCategory("Action")]
726 		public event EventHandler BalloonTipShown {
727 			add { Events.AddHandler (BalloonTipShownEvent, value); }
728 			remove { Events.RemoveHandler (BalloonTipShownEvent, value); }
729 		}
730 
731 		[MWFCategory("Action")]
732 		public event MouseEventHandler MouseClick {
733 			add { Events.AddHandler (MouseClickEvent, value); }
734 			remove { Events.RemoveHandler (MouseClickEvent, value); }
735 		}
736 
737 		[MWFCategory ("Action")]
738 		public event MouseEventHandler MouseDoubleClick {
739 			add { Events.AddHandler (MouseDoubleClickEvent, value); }
740 			remove { Events.RemoveHandler (MouseDoubleClickEvent, value); }
741 		}
742 
743 		[MWFCategory("Action")]
744 		public event EventHandler Click {
745 			add { Events.AddHandler (ClickEvent, value); }
746 			remove { Events.RemoveHandler (ClickEvent, value); }
747 		}
748 
749 		[MWFCategory("Action")]
750 		public event EventHandler DoubleClick {
751 			add { Events.AddHandler (DoubleClickEvent, value); }
752 			remove { Events.RemoveHandler (DoubleClickEvent, value); }
753 		}
754 
755 		public event MouseEventHandler MouseDown {
756 			add { Events.AddHandler (MouseDownEvent, value); }
757 			remove { Events.RemoveHandler (MouseDownEvent, value); }
758 		}
759 
760 		public event MouseEventHandler MouseMove {
761 			add { Events.AddHandler (MouseMoveEvent, value); }
762 			remove { Events.RemoveHandler (MouseMoveEvent, value); }
763 		}
764 
765 		public event MouseEventHandler MouseUp {
766 			add { Events.AddHandler (MouseUpEvent, value); }
767 			remove { Events.RemoveHandler (MouseUpEvent, value); }
768 		}
769 
770 		#endregion	// Events
771 	}
772 }
773