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