Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / NotifyIcon.cs / 1305376 / NotifyIcon.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Remoting; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Windows.Forms.Design; using Microsoft.Win32; using System.Drawing; using System.Globalization; ////// /// [ DefaultProperty("Text"), DefaultEvent("MouseDoubleClick"), Designer("System.Windows.Forms.Design.NotifyIconDesigner, " + AssemblyRef.SystemDesign), ToolboxItemFilter("System.Windows.Forms"), SRDescription(SR.DescriptionNotifyIcon) ] public sealed class NotifyIcon : Component { private static readonly object EVENT_MOUSEDOWN = new object(); private static readonly object EVENT_MOUSEMOVE = new object(); private static readonly object EVENT_MOUSEUP = new object(); private static readonly object EVENT_CLICK = new object(); private static readonly object EVENT_DOUBLECLICK = new object(); private static readonly object EVENT_MOUSECLICK = new object(); private static readonly object EVENT_MOUSEDOUBLECLICK = new object(); private static readonly object EVENT_BALLOONTIPSHOWN = new object(); private static readonly object EVENT_BALLOONTIPCLICKED = new object(); private static readonly object EVENT_BALLOONTIPCLOSED = new object(); private const int WM_TRAYMOUSEMESSAGE = NativeMethods.WM_USER + 1024; private static int WM_TASKBARCREATED = SafeNativeMethods.RegisterWindowMessage("TaskbarCreated"); private object syncObj = new object(); private Icon icon = null; private string text = ""; private int id = 0; private bool added = false; private NotifyIconNativeWindow window = null; private ContextMenu contextMenu = null; private ContextMenuStrip contextMenuStrip = null; private ToolTipIcon balloonTipIcon; private string balloonTipText = ""; private string balloonTipTitle = ""; private static int nextId = 0; private object userData; private bool doubleClick = false; // checks if doubleclick is fired // Visible defaults to false, but the NotifyIconDesigner makes it seem like the default is // true. We do this because while visible is the more common case, if it was a true default, // there would be no way to create a hidden NotifyIcon without being visible for a moment. private bool visible = false; ////// Specifies a component that creates /// an icon in the Windows System Tray. This class cannot be inherited. /// ////// /// public NotifyIcon() { id = ++nextId; window = new NotifyIconNativeWindow(this); UpdateIcon(visible); } ////// Initializes a new instance of the ///class. /// /// /// public NotifyIcon(IContainer container) : this() { if (container == null) { throw new ArgumentNullException("container"); } container.Add(this); } ////// Initializes a new instance of the ///class. /// /// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconBalloonTipTextDescr), Editor("System.ComponentModel.Design.MultilineStringEditor, " + AssemblyRef.SystemDesign, typeof(System.Drawing.Design.UITypeEditor)) ] public string BalloonTipText { get { return balloonTipText; } set { if (value != balloonTipText) { balloonTipText = value; } } } ////// Gets or sets the BalloonTip text displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), DefaultValue(ToolTipIcon.None), SRDescription(SR.NotifyIconBalloonTipIconDescr) ] public ToolTipIcon BalloonTipIcon { get { return balloonTipIcon; } set { //valid values are 0x0 to 0x3 if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolTipIcon.None, (int)ToolTipIcon.Error)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolTipIcon)); } if (value != balloonTipIcon) { balloonTipIcon = value; } } } ////// Gets or sets the BalloonTip icon displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconBalloonTipTitleDescr) ] public string BalloonTipTitle { get { return balloonTipTitle; } set { if (value != balloonTipTitle) { balloonTipTitle = value; } } } ////// Gets or sets the BalloonTip title displayed when /// the mouse hovers over a system tray icon. /// ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipClickedDescr)] public event EventHandler BalloonTipClicked { add { Events.AddHandler(EVENT_BALLOONTIPCLICKED, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPCLICKED, value); } } ///[This event is raised on the NIN_BALLOONUSERCLICK message.] ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipClosedDescr)] public event EventHandler BalloonTipClosed { add { Events.AddHandler(EVENT_BALLOONTIPCLOSED, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPCLOSED, value); } } ///[This event is raised on the NIN_BALLOONTIMEOUT message.] ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipShownDescr)] public event EventHandler BalloonTipShown { add { Events.AddHandler(EVENT_BALLOONTIPSHOWN, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPSHOWN, value); } } ///[This event is raised on the NIN_BALLOONSHOW or NIN_BALLOONHIDE message.] ////// /// [ Browsable(false), DefaultValue(null), SRCategory(SR.CatBehavior), SRDescription(SR.NotifyIconMenuDescr) ] public ContextMenu ContextMenu { get { return contextMenu; } set { this.contextMenu = value; } } [ DefaultValue(null), SRCategory(SR.CatBehavior), SRDescription(SR.NotifyIconMenuDescr) ] public ContextMenuStrip ContextMenuStrip { get { return contextMenuStrip; } set { this.contextMenuStrip = value; } } ////// Gets or sets context menu /// for the tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(null), SRDescription(SR.NotifyIconIconDescr) ] public Icon Icon { get { return icon; } set { if (icon != value) { this.icon = value; UpdateIcon(visible); } } } ////// Gets or sets the current /// icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconTextDescr), Editor("System.ComponentModel.Design.MultilineStringEditor, " + AssemblyRef.SystemDesign, typeof(System.Drawing.Design.UITypeEditor)) ] public string Text { get { return text; } set { if (value == null) value = ""; if (value != null && !value.Equals(this.text)) { if (value != null && value.Length > 63) { throw new ArgumentOutOfRangeException("Text", value, SR.GetString(SR.TrayIcon_TextTooLong)); } this.text = value; if (added) { UpdateIcon(true); } } } } ////// Gets or sets the ToolTip text displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatBehavior), Localizable(true), DefaultValue(false), SRDescription(SR.NotifyIconVisDescr) ] public bool Visible { get { return visible; } set { if (visible != value) { UpdateIcon(value); visible = value; } } } ////// Gets or sets a value indicating whether the icon is visible in the Windows System Tray. /// ///[ SRCategory(SR.CatData), Localizable(false), Bindable(true), SRDescription(SR.ControlTagDescr), DefaultValue(null), TypeConverter(typeof(StringConverter)), ] public object Tag { get { return userData; } set { userData = value; } } /// /// /// Occurs when the user clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.ControlOnClickDescr)] public event EventHandler Click { add { Events.AddHandler(EVENT_CLICK, value); } remove { Events.RemoveHandler(EVENT_CLICK, value); } } ////// /// Occurs when the user double-clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.ControlOnDoubleClickDescr)] public event EventHandler DoubleClick { add { Events.AddHandler(EVENT_DOUBLECLICK, value); } remove { Events.RemoveHandler(EVENT_DOUBLECLICK, value); } } ////// /// Occurs when the user clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconMouseClickDescr)] public event MouseEventHandler MouseClick { add { Events.AddHandler(EVENT_MOUSECLICK, value); } remove { Events.RemoveHandler(EVENT_MOUSECLICK, value); } } ////// /// Occurs when the user mouse double clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconMouseDoubleClickDescr)] public event MouseEventHandler MouseDoubleClick { add { Events.AddHandler(EVENT_MOUSEDOUBLECLICK, value); } remove { Events.RemoveHandler(EVENT_MOUSEDOUBLECLICK, value); } } ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseDownDescr)] public event MouseEventHandler MouseDown { add { Events.AddHandler(EVENT_MOUSEDOWN, value); } remove { Events.RemoveHandler(EVENT_MOUSEDOWN, value); } } ////// Occurs when the /// user presses a mouse button while the pointer is over the icon in the system tray. /// ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseMoveDescr)] public event MouseEventHandler MouseMove { add { Events.AddHandler(EVENT_MOUSEMOVE, value); } remove { Events.RemoveHandler(EVENT_MOUSEMOVE, value); } } ////// Occurs /// when the user moves the mouse pointer over the icon in the system tray. /// ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseUpDescr)] public event MouseEventHandler MouseUp { add { Events.AddHandler(EVENT_MOUSEUP, value); } remove { Events.RemoveHandler(EVENT_MOUSEUP, value); } } ////// Occurs when the /// user releases the mouse button while the pointer /// is over the icon in the system tray. /// ////// /// protected override void Dispose(bool disposing) { if (disposing) { if (window != null) { this.icon = null; this.Text = String.Empty; UpdateIcon(false); window.DestroyHandle(); window = null; contextMenu = null; contextMenuStrip = null; } } else { // This same post is done in ControlNativeWindow's finalize method, so if you change // it, change it there too. // if (window != null && window.Handle != IntPtr.Zero) { UnsafeNativeMethods.PostMessage(new HandleRef(window, window.Handle), NativeMethods.WM_CLOSE, 0, 0); window.ReleaseHandle(); } } base.Dispose(disposing); } ////// Disposes of the resources (other than memory) used by the /// ///. /// /// /// private void OnBalloonTipClicked() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPCLICKED]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipClicked event. /// ////// /// private void OnBalloonTipClosed() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPCLOSED]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipClosed event. /// ////// /// private void OnBalloonTipShown() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPSHOWN]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipShown event. /// ////// /// private void OnClick(EventArgs e) { EventHandler handler = (EventHandler) Events[ EVENT_CLICK ]; if (handler != null) handler( this, e ); } ////// This method actually raises the Click event. Inheriting classes should /// override this if they wish to be notified of a Click event. (This is far /// preferable to actually adding an event handler.) They should not, /// however, forget to call base.onClick(e); before exiting, to ensure that /// other recipients do actually get the event. /// ////// /// Inheriting classes should override this method to handle this event. /// Call base.onDoubleClick to send this event to any registered event listeners. /// private void OnDoubleClick(EventArgs e) { EventHandler handler = (EventHandler) Events[ EVENT_DOUBLECLICK ]; if (handler != null) handler( this, e ); } ////// /// Inheriting classes should override this method to handle this event. /// Call base.OnMouseClick to send this event to any registered event listeners. /// private void OnMouseClick(MouseEventArgs mea) { MouseEventHandler handler = (MouseEventHandler) Events[ EVENT_MOUSECLICK ]; if (handler != null) handler( this, mea ); } ////// /// Inheriting classes should override this method to handle this event. /// Call base.OnMouseDoubleClick to send this event to any registered event listeners. /// private void OnMouseDoubleClick(MouseEventArgs mea) { MouseEventHandler handler = (MouseEventHandler) Events[ EVENT_MOUSEDOUBLECLICK ]; if (handler != null) handler( this, mea ); } ////// /// private void OnMouseDown(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEDOWN]; if (handler != null) handler(this, e); } ////// Raises the ///event. /// Inheriting classes should override this method to handle this event. /// Call base.onMouseDown to send this event to any registered event listeners. /// /// /// /// private void OnMouseMove(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEMOVE]; if (handler != null) handler(this, e); } ////// Inheriting classes should override this method to handle this event. /// Call base.onMouseMove to send this event to any registered event listeners. /// /// ////// /// private void OnMouseUp(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEUP]; if (handler != null) handler(this, e); } ////// Inheriting classes should override this method to handle this event. /// Call base.onMouseUp to send this event to any registered event listeners. /// ////// /// public void ShowBalloonTip(int timeout) { ShowBalloonTip(timeout, this.balloonTipTitle, this.balloonTipText, this.balloonTipIcon); } ////// Displays a balloon tooltip in the taskbar. /// /// The system enforces minimum and maximum timeout values. Timeout /// values that are too large are set to the maximum value and values /// that are too small default to the minimum value. The operating system's /// default minimum and maximum timeout values are 10 seconds and 30 seconds, /// respectively. /// /// No more than one balloon ToolTip at at time is displayed for the taskbar. /// If an application attempts to display a ToolTip when one is already being displayed, /// the ToolTip will not appear until the existing balloon ToolTip has been visible for at /// least the system minimum timeout value. For example, a balloon ToolTip with timeout /// set to 30 seconds has been visible for seven seconds when another application attempts /// to display a balloon ToolTip. If the system minimum timeout is ten seconds, the first /// ToolTip displays for an additional three seconds before being replaced by the second ToolTip. /// ////// /// public void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon) { if (timeout < 0) { throw new ArgumentOutOfRangeException("timeout", SR.GetString(SR.InvalidArgument, "timeout", (timeout).ToString(CultureInfo.CurrentCulture))); } if (string.IsNullOrEmpty(tipText)) { throw new ArgumentException(SR.GetString(SR.NotifyIconEmptyOrNullTipText)); } //valid values are 0x0 to 0x3 if (!ClientUtils.IsEnumValid(tipIcon, (int)tipIcon, (int)ToolTipIcon.None, (int)ToolTipIcon.Error)){ throw new InvalidEnumArgumentException("tipIcon", (int)tipIcon, typeof(ToolTipIcon)); } if (added ) { // Bail if in design mode... if (DesignMode) { return; } IntSecurity.UnrestrictedWindows.Demand(); NativeMethods.NOTIFYICONDATA data = new NativeMethods.NOTIFYICONDATA(); if (window.Handle == IntPtr.Zero) { window.CreateHandle(new CreateParams()); } data.hWnd = window.Handle; data.uID = id; data.uFlags = NativeMethods.NIF_INFO; data.uTimeoutOrVersion = timeout; data.szInfoTitle = tipTitle; data.szInfo = tipText; switch (tipIcon) { case ToolTipIcon.Info: data.dwInfoFlags = NativeMethods.NIIF_INFO; break; case ToolTipIcon.Warning: data.dwInfoFlags = NativeMethods.NIIF_WARNING; break; case ToolTipIcon.Error: data.dwInfoFlags = NativeMethods.NIIF_ERROR; break; case ToolTipIcon.None: data.dwInfoFlags = NativeMethods.NIIF_NONE; break; } UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_MODIFY, data); } } ////// Displays a balloon tooltip in the taskbar with the specified title, /// text, and icon for a duration of the specified timeout value. /// /// The system enforces minimum and maximum timeout values. Timeout /// values that are too large are set to the maximum value and values /// that are too small default to the minimum value. The operating system's /// default minimum and maximum timeout values are 10 seconds and 30 seconds, /// respectively. /// /// No more than one balloon ToolTip at at time is displayed for the taskbar. /// If an application attempts to display a ToolTip when one is already being displayed, /// the ToolTip will not appear until the existing balloon ToolTip has been visible for at /// least the system minimum timeout value. For example, a balloon ToolTip with timeout /// set to 30 seconds has been visible for seven seconds when another application attempts /// to display a balloon ToolTip. If the system minimum timeout is ten seconds, the first /// ToolTip displays for an additional three seconds before being replaced by the second ToolTip. /// ////// /// Shows the context menu for the tray icon. /// ///private void ShowContextMenu() { if (contextMenu != null || contextMenuStrip != null) { NativeMethods.POINT pt = new NativeMethods.POINT(); UnsafeNativeMethods.GetCursorPos(pt); // VS7 #38994 // The solution to this problem was found in MSDN Article ID: Q135788. // Summary: the current window must be made the foreground window // before calling TrackPopupMenuEx, and a task switch must be // forced after the call. UnsafeNativeMethods.SetForegroundWindow(new HandleRef(window, window.Handle)); if (contextMenu != null) { contextMenu.OnPopup( EventArgs.Empty ); SafeNativeMethods.TrackPopupMenuEx(new HandleRef(contextMenu, contextMenu.Handle), NativeMethods.TPM_VERTICAL | NativeMethods.TPM_RIGHTALIGN, pt.x, pt.y, new HandleRef(window, window.Handle), null); // Force task switch (see above) UnsafeNativeMethods.PostMessage(new HandleRef(window, window.Handle), NativeMethods.WM_NULL, IntPtr.Zero, IntPtr.Zero); } else if (contextMenuStrip != null) { // this will set the context menu strip to be toplevel // and will allow us to overlap the system tray contextMenuStrip.ShowInTaskbar(pt.x, pt.y); } } } /// /// /// Updates the icon in the system tray. /// ///private void UpdateIcon(bool showIconInTray) { lock(syncObj) { // Bail if in design mode... // if (DesignMode) { return; } IntSecurity.UnrestrictedWindows.Demand(); window.LockReference(showIconInTray); NativeMethods.NOTIFYICONDATA data = new NativeMethods.NOTIFYICONDATA(); data.uCallbackMessage = WM_TRAYMOUSEMESSAGE; data.uFlags = NativeMethods.NIF_MESSAGE; if (showIconInTray) { if (window.Handle == IntPtr.Zero) { window.CreateHandle(new CreateParams()); } } data.hWnd = window.Handle; data.uID = id; data.hIcon = IntPtr.Zero; data.szTip = null; if (icon != null) { data.uFlags |= NativeMethods.NIF_ICON; data.hIcon = icon.Handle; } data.uFlags |= NativeMethods.NIF_TIP; data.szTip = text; if (showIconInTray && icon != null) { if (!added) { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_ADD, data); added = true; } else { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_MODIFY, data); } } else if (added) { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_DELETE, data); added = false; } } } /// /// /// Handles the mouse-down event /// ///private void WmMouseDown(ref Message m, MouseButtons button, int clicks) { if (clicks == 2) { OnDoubleClick(new MouseEventArgs(button, 2, 0, 0, 0)); OnMouseDoubleClick(new MouseEventArgs(button, 2, 0, 0, 0)); doubleClick = true; } OnMouseDown(new MouseEventArgs(button, clicks, 0, 0, 0)); } /// /// /// Handles the mouse-move event /// ///private void WmMouseMove(ref Message m) { OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0)); } /// /// /// Handles the mouse-up event /// ///private void WmMouseUp(ref Message m, MouseButtons button) { OnMouseUp(new MouseEventArgs(button, 0, 0, 0, 0)); //subhag if(!doubleClick) { OnClick(new MouseEventArgs(button, 0, 0, 0, 0)); OnMouseClick(new MouseEventArgs(button, 0, 0, 0, 0)); } doubleClick = false; } private void WmTaskbarCreated(ref Message m) { added = false; UpdateIcon(visible); } private void WndProc(ref Message msg) { switch (msg.Msg) { case WM_TRAYMOUSEMESSAGE: switch ((int)msg.LParam) { case NativeMethods.WM_LBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Left, 2); break; case NativeMethods.WM_LBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Left, 1); break; case NativeMethods.WM_LBUTTONUP: WmMouseUp(ref msg, MouseButtons.Left); break; case NativeMethods.WM_MBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Middle, 2); break; case NativeMethods.WM_MBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Middle, 1); break; case NativeMethods.WM_MBUTTONUP: WmMouseUp(ref msg, MouseButtons.Middle); break; case NativeMethods.WM_MOUSEMOVE: WmMouseMove(ref msg); break; case NativeMethods.WM_RBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Right, 2); break; case NativeMethods.WM_RBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Right, 1); break; case NativeMethods.WM_RBUTTONUP: if (contextMenu != null || contextMenuStrip != null) { ShowContextMenu(); } WmMouseUp(ref msg, MouseButtons.Right); break; case NativeMethods.NIN_BALLOONSHOW: OnBalloonTipShown(); break; case NativeMethods.NIN_BALLOONHIDE: OnBalloonTipClosed(); break; case NativeMethods.NIN_BALLOONTIMEOUT: OnBalloonTipClosed(); break; case NativeMethods.NIN_BALLOONUSERCLICK: OnBalloonTipClicked(); break; } break; case NativeMethods.WM_COMMAND: if (IntPtr.Zero == msg.LParam) { if (Command.DispatchID((int)msg.WParam & 0xFFFF)) return; } else { window.DefWndProc(ref msg); } break; case NativeMethods.WM_DRAWITEM: // If the wparam is zero, then the message was sent by a menu. // See WM_DRAWITEM in MSDN. if (msg.WParam == IntPtr.Zero) { WmDrawItemMenuItem(ref msg); } break; case NativeMethods.WM_MEASUREITEM: // If the wparam is zero, then the message was sent by a menu. if (msg.WParam == IntPtr.Zero) { WmMeasureMenuItem(ref msg); } break; case NativeMethods.WM_INITMENUPOPUP: WmInitMenuPopup(ref msg); break; case NativeMethods.WM_DESTROY: // Remove the icon from the taskbar UpdateIcon(false); break; default: if (msg.Msg == WM_TASKBARCREATED) { WmTaskbarCreated(ref msg); } window.DefWndProc(ref msg); break; } } private void WmInitMenuPopup(ref Message m) { if (contextMenu != null) { if (contextMenu.ProcessInitMenuPopup(m.WParam)) { return; } } window.DefWndProc(ref m); } private void WmMeasureMenuItem(ref Message m) { // Obtain the menu item object NativeMethods.MEASUREITEMSTRUCT mis = (NativeMethods.MEASUREITEMSTRUCT)m.GetLParam(typeof(NativeMethods.MEASUREITEMSTRUCT)); Debug.Assert(m.LParam != IntPtr.Zero, "m.lparam is null"); // A pointer to the correct MenuItem is stored in the measure item // information sent with the message. // (See MenuItem.CreateMenuItemInfo) MenuItem menuItem = MenuItem.GetMenuItemFromItemData(mis.itemData); Debug.Assert(menuItem != null, "UniqueID is not associated with a menu item"); // Delegate this message to the menu item if (menuItem != null) { menuItem.WmMeasureItem(ref m); } } private void WmDrawItemMenuItem(ref Message m) { // Obtain the menu item object NativeMethods.DRAWITEMSTRUCT dis = (NativeMethods.DRAWITEMSTRUCT)m.GetLParam(typeof(NativeMethods.DRAWITEMSTRUCT)); // A pointer to the correct MenuItem is stored in the draw item // information sent with the message. // (See MenuItem.CreateMenuItemInfo) MenuItem menuItem = MenuItem.GetMenuItemFromItemData(dis.itemData); // Delegate this message to the menu item if (menuItem != null) { menuItem.WmDrawItem(ref m); } } /// /// /// Defines a placeholder window that the NotifyIcon is attached to. /// ///private class NotifyIconNativeWindow : NativeWindow { internal NotifyIcon reference; private GCHandle rootRef; // We will root the control when we do not want to be elligible for garbage collection. /// /// /// Create a new NotifyIcon, and bind the window to the NotifyIcon component. /// ///internal NotifyIconNativeWindow(NotifyIcon component) { reference = component; } ~NotifyIconNativeWindow() { // This same post is done in Control's Dispose method, so if you change // it, change it there too. // if (Handle != IntPtr.Zero) { UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), NativeMethods.WM_CLOSE, 0, 0); } // This releases the handle from our window proc, re-routing it back to // the system. } public void LockReference(bool locked) { if (locked) { if (!rootRef.IsAllocated) { rootRef = GCHandle.Alloc(reference, GCHandleType.Normal); } } else { if (rootRef.IsAllocated) { rootRef.Free(); } } } protected override void OnThreadException(Exception e) { Application.OnThreadException(e); } /// /// /// Pass messages on to the NotifyIcon object's wndproc handler. /// ///protected override void WndProc(ref Message m) { Debug.Assert(reference != null, "NotifyIcon was garbage collected while it was still visible. How did we let that happen?"); reference.WndProc(ref m); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Runtime.Remoting; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Windows.Forms.Design; using Microsoft.Win32; using System.Drawing; using System.Globalization; ////// /// [ DefaultProperty("Text"), DefaultEvent("MouseDoubleClick"), Designer("System.Windows.Forms.Design.NotifyIconDesigner, " + AssemblyRef.SystemDesign), ToolboxItemFilter("System.Windows.Forms"), SRDescription(SR.DescriptionNotifyIcon) ] public sealed class NotifyIcon : Component { private static readonly object EVENT_MOUSEDOWN = new object(); private static readonly object EVENT_MOUSEMOVE = new object(); private static readonly object EVENT_MOUSEUP = new object(); private static readonly object EVENT_CLICK = new object(); private static readonly object EVENT_DOUBLECLICK = new object(); private static readonly object EVENT_MOUSECLICK = new object(); private static readonly object EVENT_MOUSEDOUBLECLICK = new object(); private static readonly object EVENT_BALLOONTIPSHOWN = new object(); private static readonly object EVENT_BALLOONTIPCLICKED = new object(); private static readonly object EVENT_BALLOONTIPCLOSED = new object(); private const int WM_TRAYMOUSEMESSAGE = NativeMethods.WM_USER + 1024; private static int WM_TASKBARCREATED = SafeNativeMethods.RegisterWindowMessage("TaskbarCreated"); private object syncObj = new object(); private Icon icon = null; private string text = ""; private int id = 0; private bool added = false; private NotifyIconNativeWindow window = null; private ContextMenu contextMenu = null; private ContextMenuStrip contextMenuStrip = null; private ToolTipIcon balloonTipIcon; private string balloonTipText = ""; private string balloonTipTitle = ""; private static int nextId = 0; private object userData; private bool doubleClick = false; // checks if doubleclick is fired // Visible defaults to false, but the NotifyIconDesigner makes it seem like the default is // true. We do this because while visible is the more common case, if it was a true default, // there would be no way to create a hidden NotifyIcon without being visible for a moment. private bool visible = false; ////// Specifies a component that creates /// an icon in the Windows System Tray. This class cannot be inherited. /// ////// /// public NotifyIcon() { id = ++nextId; window = new NotifyIconNativeWindow(this); UpdateIcon(visible); } ////// Initializes a new instance of the ///class. /// /// /// public NotifyIcon(IContainer container) : this() { if (container == null) { throw new ArgumentNullException("container"); } container.Add(this); } ////// Initializes a new instance of the ///class. /// /// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconBalloonTipTextDescr), Editor("System.ComponentModel.Design.MultilineStringEditor, " + AssemblyRef.SystemDesign, typeof(System.Drawing.Design.UITypeEditor)) ] public string BalloonTipText { get { return balloonTipText; } set { if (value != balloonTipText) { balloonTipText = value; } } } ////// Gets or sets the BalloonTip text displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), DefaultValue(ToolTipIcon.None), SRDescription(SR.NotifyIconBalloonTipIconDescr) ] public ToolTipIcon BalloonTipIcon { get { return balloonTipIcon; } set { //valid values are 0x0 to 0x3 if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolTipIcon.None, (int)ToolTipIcon.Error)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolTipIcon)); } if (value != balloonTipIcon) { balloonTipIcon = value; } } } ////// Gets or sets the BalloonTip icon displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconBalloonTipTitleDescr) ] public string BalloonTipTitle { get { return balloonTipTitle; } set { if (value != balloonTipTitle) { balloonTipTitle = value; } } } ////// Gets or sets the BalloonTip title displayed when /// the mouse hovers over a system tray icon. /// ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipClickedDescr)] public event EventHandler BalloonTipClicked { add { Events.AddHandler(EVENT_BALLOONTIPCLICKED, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPCLICKED, value); } } ///[This event is raised on the NIN_BALLOONUSERCLICK message.] ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipClosedDescr)] public event EventHandler BalloonTipClosed { add { Events.AddHandler(EVENT_BALLOONTIPCLOSED, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPCLOSED, value); } } ///[This event is raised on the NIN_BALLOONTIMEOUT message.] ////// /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconOnBalloonTipShownDescr)] public event EventHandler BalloonTipShown { add { Events.AddHandler(EVENT_BALLOONTIPSHOWN, value); } remove { Events.RemoveHandler(EVENT_BALLOONTIPSHOWN, value); } } ///[This event is raised on the NIN_BALLOONSHOW or NIN_BALLOONHIDE message.] ////// /// [ Browsable(false), DefaultValue(null), SRCategory(SR.CatBehavior), SRDescription(SR.NotifyIconMenuDescr) ] public ContextMenu ContextMenu { get { return contextMenu; } set { this.contextMenu = value; } } [ DefaultValue(null), SRCategory(SR.CatBehavior), SRDescription(SR.NotifyIconMenuDescr) ] public ContextMenuStrip ContextMenuStrip { get { return contextMenuStrip; } set { this.contextMenuStrip = value; } } ////// Gets or sets context menu /// for the tray icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(null), SRDescription(SR.NotifyIconIconDescr) ] public Icon Icon { get { return icon; } set { if (icon != value) { this.icon = value; UpdateIcon(visible); } } } ////// Gets or sets the current /// icon. /// ////// /// [ SRCategory(SR.CatAppearance), Localizable(true), DefaultValue(""), SRDescription(SR.NotifyIconTextDescr), Editor("System.ComponentModel.Design.MultilineStringEditor, " + AssemblyRef.SystemDesign, typeof(System.Drawing.Design.UITypeEditor)) ] public string Text { get { return text; } set { if (value == null) value = ""; if (value != null && !value.Equals(this.text)) { if (value != null && value.Length > 63) { throw new ArgumentOutOfRangeException("Text", value, SR.GetString(SR.TrayIcon_TextTooLong)); } this.text = value; if (added) { UpdateIcon(true); } } } } ////// Gets or sets the ToolTip text displayed when /// the mouse hovers over a system tray icon. /// ////// /// [ SRCategory(SR.CatBehavior), Localizable(true), DefaultValue(false), SRDescription(SR.NotifyIconVisDescr) ] public bool Visible { get { return visible; } set { if (visible != value) { UpdateIcon(value); visible = value; } } } ////// Gets or sets a value indicating whether the icon is visible in the Windows System Tray. /// ///[ SRCategory(SR.CatData), Localizable(false), Bindable(true), SRDescription(SR.ControlTagDescr), DefaultValue(null), TypeConverter(typeof(StringConverter)), ] public object Tag { get { return userData; } set { userData = value; } } /// /// /// Occurs when the user clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.ControlOnClickDescr)] public event EventHandler Click { add { Events.AddHandler(EVENT_CLICK, value); } remove { Events.RemoveHandler(EVENT_CLICK, value); } } ////// /// Occurs when the user double-clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.ControlOnDoubleClickDescr)] public event EventHandler DoubleClick { add { Events.AddHandler(EVENT_DOUBLECLICK, value); } remove { Events.RemoveHandler(EVENT_DOUBLECLICK, value); } } ////// /// Occurs when the user clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconMouseClickDescr)] public event MouseEventHandler MouseClick { add { Events.AddHandler(EVENT_MOUSECLICK, value); } remove { Events.RemoveHandler(EVENT_MOUSECLICK, value); } } ////// /// Occurs when the user mouse double clicks the icon in the system tray. /// [SRCategory(SR.CatAction), SRDescription(SR.NotifyIconMouseDoubleClickDescr)] public event MouseEventHandler MouseDoubleClick { add { Events.AddHandler(EVENT_MOUSEDOUBLECLICK, value); } remove { Events.RemoveHandler(EVENT_MOUSEDOUBLECLICK, value); } } ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseDownDescr)] public event MouseEventHandler MouseDown { add { Events.AddHandler(EVENT_MOUSEDOWN, value); } remove { Events.RemoveHandler(EVENT_MOUSEDOWN, value); } } ////// Occurs when the /// user presses a mouse button while the pointer is over the icon in the system tray. /// ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseMoveDescr)] public event MouseEventHandler MouseMove { add { Events.AddHandler(EVENT_MOUSEMOVE, value); } remove { Events.RemoveHandler(EVENT_MOUSEMOVE, value); } } ////// Occurs /// when the user moves the mouse pointer over the icon in the system tray. /// ////// /// [SRCategory(SR.CatMouse), SRDescription(SR.ControlOnMouseUpDescr)] public event MouseEventHandler MouseUp { add { Events.AddHandler(EVENT_MOUSEUP, value); } remove { Events.RemoveHandler(EVENT_MOUSEUP, value); } } ////// Occurs when the /// user releases the mouse button while the pointer /// is over the icon in the system tray. /// ////// /// protected override void Dispose(bool disposing) { if (disposing) { if (window != null) { this.icon = null; this.Text = String.Empty; UpdateIcon(false); window.DestroyHandle(); window = null; contextMenu = null; contextMenuStrip = null; } } else { // This same post is done in ControlNativeWindow's finalize method, so if you change // it, change it there too. // if (window != null && window.Handle != IntPtr.Zero) { UnsafeNativeMethods.PostMessage(new HandleRef(window, window.Handle), NativeMethods.WM_CLOSE, 0, 0); window.ReleaseHandle(); } } base.Dispose(disposing); } ////// Disposes of the resources (other than memory) used by the /// ///. /// /// /// private void OnBalloonTipClicked() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPCLICKED]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipClicked event. /// ////// /// private void OnBalloonTipClosed() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPCLOSED]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipClosed event. /// ////// /// private void OnBalloonTipShown() { EventHandler handler = (EventHandler)Events[EVENT_BALLOONTIPSHOWN]; if (handler != null) { handler(this, EventArgs.Empty); } } ////// This method raised the BalloonTipShown event. /// ////// /// private void OnClick(EventArgs e) { EventHandler handler = (EventHandler) Events[ EVENT_CLICK ]; if (handler != null) handler( this, e ); } ////// This method actually raises the Click event. Inheriting classes should /// override this if they wish to be notified of a Click event. (This is far /// preferable to actually adding an event handler.) They should not, /// however, forget to call base.onClick(e); before exiting, to ensure that /// other recipients do actually get the event. /// ////// /// Inheriting classes should override this method to handle this event. /// Call base.onDoubleClick to send this event to any registered event listeners. /// private void OnDoubleClick(EventArgs e) { EventHandler handler = (EventHandler) Events[ EVENT_DOUBLECLICK ]; if (handler != null) handler( this, e ); } ////// /// Inheriting classes should override this method to handle this event. /// Call base.OnMouseClick to send this event to any registered event listeners. /// private void OnMouseClick(MouseEventArgs mea) { MouseEventHandler handler = (MouseEventHandler) Events[ EVENT_MOUSECLICK ]; if (handler != null) handler( this, mea ); } ////// /// Inheriting classes should override this method to handle this event. /// Call base.OnMouseDoubleClick to send this event to any registered event listeners. /// private void OnMouseDoubleClick(MouseEventArgs mea) { MouseEventHandler handler = (MouseEventHandler) Events[ EVENT_MOUSEDOUBLECLICK ]; if (handler != null) handler( this, mea ); } ////// /// private void OnMouseDown(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEDOWN]; if (handler != null) handler(this, e); } ////// Raises the ///event. /// Inheriting classes should override this method to handle this event. /// Call base.onMouseDown to send this event to any registered event listeners. /// /// /// /// private void OnMouseMove(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEMOVE]; if (handler != null) handler(this, e); } ////// Inheriting classes should override this method to handle this event. /// Call base.onMouseMove to send this event to any registered event listeners. /// /// ////// /// private void OnMouseUp(MouseEventArgs e) { MouseEventHandler handler = (MouseEventHandler)Events[EVENT_MOUSEUP]; if (handler != null) handler(this, e); } ////// Inheriting classes should override this method to handle this event. /// Call base.onMouseUp to send this event to any registered event listeners. /// ////// /// public void ShowBalloonTip(int timeout) { ShowBalloonTip(timeout, this.balloonTipTitle, this.balloonTipText, this.balloonTipIcon); } ////// Displays a balloon tooltip in the taskbar. /// /// The system enforces minimum and maximum timeout values. Timeout /// values that are too large are set to the maximum value and values /// that are too small default to the minimum value. The operating system's /// default minimum and maximum timeout values are 10 seconds and 30 seconds, /// respectively. /// /// No more than one balloon ToolTip at at time is displayed for the taskbar. /// If an application attempts to display a ToolTip when one is already being displayed, /// the ToolTip will not appear until the existing balloon ToolTip has been visible for at /// least the system minimum timeout value. For example, a balloon ToolTip with timeout /// set to 30 seconds has been visible for seven seconds when another application attempts /// to display a balloon ToolTip. If the system minimum timeout is ten seconds, the first /// ToolTip displays for an additional three seconds before being replaced by the second ToolTip. /// ////// /// public void ShowBalloonTip(int timeout, string tipTitle, string tipText, ToolTipIcon tipIcon) { if (timeout < 0) { throw new ArgumentOutOfRangeException("timeout", SR.GetString(SR.InvalidArgument, "timeout", (timeout).ToString(CultureInfo.CurrentCulture))); } if (string.IsNullOrEmpty(tipText)) { throw new ArgumentException(SR.GetString(SR.NotifyIconEmptyOrNullTipText)); } //valid values are 0x0 to 0x3 if (!ClientUtils.IsEnumValid(tipIcon, (int)tipIcon, (int)ToolTipIcon.None, (int)ToolTipIcon.Error)){ throw new InvalidEnumArgumentException("tipIcon", (int)tipIcon, typeof(ToolTipIcon)); } if (added ) { // Bail if in design mode... if (DesignMode) { return; } IntSecurity.UnrestrictedWindows.Demand(); NativeMethods.NOTIFYICONDATA data = new NativeMethods.NOTIFYICONDATA(); if (window.Handle == IntPtr.Zero) { window.CreateHandle(new CreateParams()); } data.hWnd = window.Handle; data.uID = id; data.uFlags = NativeMethods.NIF_INFO; data.uTimeoutOrVersion = timeout; data.szInfoTitle = tipTitle; data.szInfo = tipText; switch (tipIcon) { case ToolTipIcon.Info: data.dwInfoFlags = NativeMethods.NIIF_INFO; break; case ToolTipIcon.Warning: data.dwInfoFlags = NativeMethods.NIIF_WARNING; break; case ToolTipIcon.Error: data.dwInfoFlags = NativeMethods.NIIF_ERROR; break; case ToolTipIcon.None: data.dwInfoFlags = NativeMethods.NIIF_NONE; break; } UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_MODIFY, data); } } ////// Displays a balloon tooltip in the taskbar with the specified title, /// text, and icon for a duration of the specified timeout value. /// /// The system enforces minimum and maximum timeout values. Timeout /// values that are too large are set to the maximum value and values /// that are too small default to the minimum value. The operating system's /// default minimum and maximum timeout values are 10 seconds and 30 seconds, /// respectively. /// /// No more than one balloon ToolTip at at time is displayed for the taskbar. /// If an application attempts to display a ToolTip when one is already being displayed, /// the ToolTip will not appear until the existing balloon ToolTip has been visible for at /// least the system minimum timeout value. For example, a balloon ToolTip with timeout /// set to 30 seconds has been visible for seven seconds when another application attempts /// to display a balloon ToolTip. If the system minimum timeout is ten seconds, the first /// ToolTip displays for an additional three seconds before being replaced by the second ToolTip. /// ////// /// Shows the context menu for the tray icon. /// ///private void ShowContextMenu() { if (contextMenu != null || contextMenuStrip != null) { NativeMethods.POINT pt = new NativeMethods.POINT(); UnsafeNativeMethods.GetCursorPos(pt); // VS7 #38994 // The solution to this problem was found in MSDN Article ID: Q135788. // Summary: the current window must be made the foreground window // before calling TrackPopupMenuEx, and a task switch must be // forced after the call. UnsafeNativeMethods.SetForegroundWindow(new HandleRef(window, window.Handle)); if (contextMenu != null) { contextMenu.OnPopup( EventArgs.Empty ); SafeNativeMethods.TrackPopupMenuEx(new HandleRef(contextMenu, contextMenu.Handle), NativeMethods.TPM_VERTICAL | NativeMethods.TPM_RIGHTALIGN, pt.x, pt.y, new HandleRef(window, window.Handle), null); // Force task switch (see above) UnsafeNativeMethods.PostMessage(new HandleRef(window, window.Handle), NativeMethods.WM_NULL, IntPtr.Zero, IntPtr.Zero); } else if (contextMenuStrip != null) { // this will set the context menu strip to be toplevel // and will allow us to overlap the system tray contextMenuStrip.ShowInTaskbar(pt.x, pt.y); } } } /// /// /// Updates the icon in the system tray. /// ///private void UpdateIcon(bool showIconInTray) { lock(syncObj) { // Bail if in design mode... // if (DesignMode) { return; } IntSecurity.UnrestrictedWindows.Demand(); window.LockReference(showIconInTray); NativeMethods.NOTIFYICONDATA data = new NativeMethods.NOTIFYICONDATA(); data.uCallbackMessage = WM_TRAYMOUSEMESSAGE; data.uFlags = NativeMethods.NIF_MESSAGE; if (showIconInTray) { if (window.Handle == IntPtr.Zero) { window.CreateHandle(new CreateParams()); } } data.hWnd = window.Handle; data.uID = id; data.hIcon = IntPtr.Zero; data.szTip = null; if (icon != null) { data.uFlags |= NativeMethods.NIF_ICON; data.hIcon = icon.Handle; } data.uFlags |= NativeMethods.NIF_TIP; data.szTip = text; if (showIconInTray && icon != null) { if (!added) { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_ADD, data); added = true; } else { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_MODIFY, data); } } else if (added) { UnsafeNativeMethods.Shell_NotifyIcon(NativeMethods.NIM_DELETE, data); added = false; } } } /// /// /// Handles the mouse-down event /// ///private void WmMouseDown(ref Message m, MouseButtons button, int clicks) { if (clicks == 2) { OnDoubleClick(new MouseEventArgs(button, 2, 0, 0, 0)); OnMouseDoubleClick(new MouseEventArgs(button, 2, 0, 0, 0)); doubleClick = true; } OnMouseDown(new MouseEventArgs(button, clicks, 0, 0, 0)); } /// /// /// Handles the mouse-move event /// ///private void WmMouseMove(ref Message m) { OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0)); } /// /// /// Handles the mouse-up event /// ///private void WmMouseUp(ref Message m, MouseButtons button) { OnMouseUp(new MouseEventArgs(button, 0, 0, 0, 0)); //subhag if(!doubleClick) { OnClick(new MouseEventArgs(button, 0, 0, 0, 0)); OnMouseClick(new MouseEventArgs(button, 0, 0, 0, 0)); } doubleClick = false; } private void WmTaskbarCreated(ref Message m) { added = false; UpdateIcon(visible); } private void WndProc(ref Message msg) { switch (msg.Msg) { case WM_TRAYMOUSEMESSAGE: switch ((int)msg.LParam) { case NativeMethods.WM_LBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Left, 2); break; case NativeMethods.WM_LBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Left, 1); break; case NativeMethods.WM_LBUTTONUP: WmMouseUp(ref msg, MouseButtons.Left); break; case NativeMethods.WM_MBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Middle, 2); break; case NativeMethods.WM_MBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Middle, 1); break; case NativeMethods.WM_MBUTTONUP: WmMouseUp(ref msg, MouseButtons.Middle); break; case NativeMethods.WM_MOUSEMOVE: WmMouseMove(ref msg); break; case NativeMethods.WM_RBUTTONDBLCLK: WmMouseDown(ref msg, MouseButtons.Right, 2); break; case NativeMethods.WM_RBUTTONDOWN: WmMouseDown(ref msg, MouseButtons.Right, 1); break; case NativeMethods.WM_RBUTTONUP: if (contextMenu != null || contextMenuStrip != null) { ShowContextMenu(); } WmMouseUp(ref msg, MouseButtons.Right); break; case NativeMethods.NIN_BALLOONSHOW: OnBalloonTipShown(); break; case NativeMethods.NIN_BALLOONHIDE: OnBalloonTipClosed(); break; case NativeMethods.NIN_BALLOONTIMEOUT: OnBalloonTipClosed(); break; case NativeMethods.NIN_BALLOONUSERCLICK: OnBalloonTipClicked(); break; } break; case NativeMethods.WM_COMMAND: if (IntPtr.Zero == msg.LParam) { if (Command.DispatchID((int)msg.WParam & 0xFFFF)) return; } else { window.DefWndProc(ref msg); } break; case NativeMethods.WM_DRAWITEM: // If the wparam is zero, then the message was sent by a menu. // See WM_DRAWITEM in MSDN. if (msg.WParam == IntPtr.Zero) { WmDrawItemMenuItem(ref msg); } break; case NativeMethods.WM_MEASUREITEM: // If the wparam is zero, then the message was sent by a menu. if (msg.WParam == IntPtr.Zero) { WmMeasureMenuItem(ref msg); } break; case NativeMethods.WM_INITMENUPOPUP: WmInitMenuPopup(ref msg); break; case NativeMethods.WM_DESTROY: // Remove the icon from the taskbar UpdateIcon(false); break; default: if (msg.Msg == WM_TASKBARCREATED) { WmTaskbarCreated(ref msg); } window.DefWndProc(ref msg); break; } } private void WmInitMenuPopup(ref Message m) { if (contextMenu != null) { if (contextMenu.ProcessInitMenuPopup(m.WParam)) { return; } } window.DefWndProc(ref m); } private void WmMeasureMenuItem(ref Message m) { // Obtain the menu item object NativeMethods.MEASUREITEMSTRUCT mis = (NativeMethods.MEASUREITEMSTRUCT)m.GetLParam(typeof(NativeMethods.MEASUREITEMSTRUCT)); Debug.Assert(m.LParam != IntPtr.Zero, "m.lparam is null"); // A pointer to the correct MenuItem is stored in the measure item // information sent with the message. // (See MenuItem.CreateMenuItemInfo) MenuItem menuItem = MenuItem.GetMenuItemFromItemData(mis.itemData); Debug.Assert(menuItem != null, "UniqueID is not associated with a menu item"); // Delegate this message to the menu item if (menuItem != null) { menuItem.WmMeasureItem(ref m); } } private void WmDrawItemMenuItem(ref Message m) { // Obtain the menu item object NativeMethods.DRAWITEMSTRUCT dis = (NativeMethods.DRAWITEMSTRUCT)m.GetLParam(typeof(NativeMethods.DRAWITEMSTRUCT)); // A pointer to the correct MenuItem is stored in the draw item // information sent with the message. // (See MenuItem.CreateMenuItemInfo) MenuItem menuItem = MenuItem.GetMenuItemFromItemData(dis.itemData); // Delegate this message to the menu item if (menuItem != null) { menuItem.WmDrawItem(ref m); } } /// /// /// Defines a placeholder window that the NotifyIcon is attached to. /// ///private class NotifyIconNativeWindow : NativeWindow { internal NotifyIcon reference; private GCHandle rootRef; // We will root the control when we do not want to be elligible for garbage collection. /// /// /// Create a new NotifyIcon, and bind the window to the NotifyIcon component. /// ///internal NotifyIconNativeWindow(NotifyIcon component) { reference = component; } ~NotifyIconNativeWindow() { // This same post is done in Control's Dispose method, so if you change // it, change it there too. // if (Handle != IntPtr.Zero) { UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), NativeMethods.WM_CLOSE, 0, 0); } // This releases the handle from our window proc, re-routing it back to // the system. } public void LockReference(bool locked) { if (locked) { if (!rootRef.IsAllocated) { rootRef = GCHandle.Alloc(reference, GCHandleType.Normal); } } else { if (rootRef.IsAllocated) { rootRef.Free(); } } } protected override void OnThreadException(Exception e) { Application.OnThreadException(e); } /// /// /// Pass messages on to the NotifyIcon object's wndproc handler. /// ///protected override void WndProc(ref Message m) { Debug.Assert(reference != null, "NotifyIcon was garbage collected while it was still visible. How did we let that happen?"); reference.WndProc(ref m); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PopOutPanel.cs
- FlowLayoutPanel.cs
- XmlReaderSettings.cs
- SmtpNetworkElement.cs
- Italic.cs
- CompositeDuplexElement.cs
- ToolStripOverflowButton.cs
- TextWriter.cs
- ZoomPercentageConverter.cs
- ConditionalWeakTable.cs
- VersionedStreamOwner.cs
- GuidConverter.cs
- GeneralTransform2DTo3DTo2D.cs
- OdbcConnectionHandle.cs
- SmiEventSink_Default.cs
- CodeGroup.cs
- ProcessInfo.cs
- DataSetFieldSchema.cs
- ItemCheckedEvent.cs
- TypeToken.cs
- EntityPropertyMappingAttribute.cs
- ArrayWithOffset.cs
- IListConverters.cs
- WebPartDescriptionCollection.cs
- DataGridTableCollection.cs
- ImageSourceValueSerializer.cs
- AppModelKnownContentFactory.cs
- ObjectDataSourceView.cs
- MappingModelBuildProvider.cs
- ExecutedRoutedEventArgs.cs
- ChildrenQuery.cs
- SectionVisual.cs
- VisualBrush.cs
- PrintPreviewDialog.cs
- remotingproxy.cs
- IHttpResponseInternal.cs
- PolyLineSegment.cs
- SerializerWriterEventHandlers.cs
- TransactionValidationBehavior.cs
- ToolStripArrowRenderEventArgs.cs
- FileInfo.cs
- FunctionImportMapping.cs
- XmlParser.cs
- lengthconverter.cs
- SessionEndingCancelEventArgs.cs
- LinearGradientBrush.cs
- FrameworkReadOnlyPropertyMetadata.cs
- ColorKeyFrameCollection.cs
- GroupItem.cs
- ProfileService.cs
- RTTrackingProfile.cs
- GACIdentityPermission.cs
- TemplateBindingExpressionConverter.cs
- TabItem.cs
- EmptyControlCollection.cs
- ObfuscationAttribute.cs
- DataViewListener.cs
- GenericsInstances.cs
- Calendar.cs
- XmlILIndex.cs
- PathFigureCollection.cs
- DockAndAnchorLayout.cs
- ProtocolViolationException.cs
- AssemblyFilter.cs
- AddInContractAttribute.cs
- XPathDocumentNavigator.cs
- Lasso.cs
- Vector3DAnimationUsingKeyFrames.cs
- IsolationInterop.cs
- CodeBlockBuilder.cs
- EntityProviderFactory.cs
- DataGridColumnHeaderAutomationPeer.cs
- MissingMethodException.cs
- SafeProcessHandle.cs
- SyndicationItemFormatter.cs
- BinaryKeyIdentifierClause.cs
- WebBrowserNavigatedEventHandler.cs
- DateRangeEvent.cs
- PenThreadPool.cs
- Timer.cs
- NavigationWindow.cs
- XmlBaseReader.cs
- InertiaExpansionBehavior.cs
- DropDownList.cs
- HitTestWithPointDrawingContextWalker.cs
- EmptyStringExpandableObjectConverter.cs
- TextSpan.cs
- OutputCacheSection.cs
- CodeDelegateCreateExpression.cs
- TextViewBase.cs
- WindowsFormsSectionHandler.cs
- OLEDB_Enum.cs
- ArraySegment.cs
- ProtectedProviderSettings.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- HttpWebRequest.cs
- TreeNodeCollection.cs
- DebugHandleTracker.cs
- GridToolTip.cs
- BooleanSwitch.cs