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