Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / WinForms / Managed / System / WinForms / NotifyIcon.cs / 1 / 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() { 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() { 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
- ComboBox.cs
- X509SubjectKeyIdentifierClause.cs
- SelectionPatternIdentifiers.cs
- ExtentCqlBlock.cs
- VerificationAttribute.cs
- ImageCodecInfo.cs
- SessionStateItemCollection.cs
- KeyFrames.cs
- designeractionlistschangedeventargs.cs
- ToolStripRendererSwitcher.cs
- PropertyDescriptorComparer.cs
- FixedDocument.cs
- HtmlForm.cs
- EntityDataSourceDesigner.cs
- MimePart.cs
- BinaryCommonClasses.cs
- RootNamespaceAttribute.cs
- QilParameter.cs
- FileInfo.cs
- DetectRunnableInstancesTask.cs
- ToolStripCodeDomSerializer.cs
- CodeGeneratorAttribute.cs
- ServiceOperationHelpers.cs
- ModulesEntry.cs
- GatewayIPAddressInformationCollection.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- ClientApiGenerator.cs
- CodeEntryPointMethod.cs
- ConfigurationSection.cs
- InheritedPropertyChangedEventArgs.cs
- IndependentAnimationStorage.cs
- FixedPage.cs
- FixedTextPointer.cs
- TableProviderWrapper.cs
- DataGridPageChangedEventArgs.cs
- DataBindingCollectionEditor.cs
- PropertyOrder.cs
- WindowsAuthenticationModule.cs
- Image.cs
- SqlConnectionStringBuilder.cs
- MetadataItemEmitter.cs
- UIElementParagraph.cs
- EnumValidator.cs
- Stackframe.cs
- NetSectionGroup.cs
- XmlUtil.cs
- CngKeyBlobFormat.cs
- QueryStringParameter.cs
- EntityViewGenerator.cs
- StyleSheetComponentEditor.cs
- TableHeaderCell.cs
- PrePostDescendentsWalker.cs
- FuncCompletionCallbackWrapper.cs
- SiteOfOriginContainer.cs
- EdmFunction.cs
- ObjectDataSourceDisposingEventArgs.cs
- DataGridViewColumnEventArgs.cs
- UrlAuthorizationModule.cs
- ContainerParagraph.cs
- StrokeNode.cs
- CompilationRelaxations.cs
- CacheRequest.cs
- ConfigurationSectionGroupCollection.cs
- DetailsViewModeEventArgs.cs
- TreeNodeStyle.cs
- DataGridViewTopLeftHeaderCell.cs
- ReadWriteObjectLock.cs
- CmsInterop.cs
- OleDbStruct.cs
- LinearKeyFrames.cs
- CroppedBitmap.cs
- ProfileProvider.cs
- TraceHandlerErrorFormatter.cs
- DataGridViewHitTestInfo.cs
- ColorMatrix.cs
- ConsoleCancelEventArgs.cs
- ControlAdapter.cs
- CssClassPropertyAttribute.cs
- SecurityAccessDeniedException.cs
- ChangeBlockUndoRecord.cs
- WizardPanelChangingEventArgs.cs
- ImageListStreamer.cs
- Slider.cs
- MobileResource.cs
- _CommandStream.cs
- Inflater.cs
- EDesignUtil.cs
- XmlPropertyBag.cs
- DataGridState.cs
- WaitForChangedResult.cs
- IisTraceListener.cs
- SystemEvents.cs
- TimeIntervalCollection.cs
- smtppermission.cs
- TileModeValidation.cs
- ConfigurationLockCollection.cs
- MdbDataFileEditor.cs
- StylusShape.cs
- CollectionBase.cs
- HtmlInputButton.cs