diff --git a/Source/NotifyIconWpf/Interop/WindowMessageSink.Handle.cs b/Source/NotifyIconWpf/Interop/WindowMessageSink.Handle.cs index 5a4d4e9..d99dd34 100644 --- a/Source/NotifyIconWpf/Interop/WindowMessageSink.Handle.cs +++ b/Source/NotifyIconWpf/Interop/WindowMessageSink.Handle.cs @@ -35,13 +35,15 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// private WindowProcedureHandler messageHandler; + /// /// Creates the helper message window that is used /// to receive messages from the taskbar icon. /// private void CreateMessageWindow() { - WindowId = "WPFTaskbarIcon_" + Guid.NewGuid().ToString(); + //generate a unique ID for the window + WindowId = "WPFTaskbarIcon_" + DateTime.Now.Ticks; //register window message handler messageHandler = OnWindowMessageReceived; @@ -86,14 +88,13 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop { if (messageId == taskbarRestartMessageId) { - //recreate the icon if the taskbar was restarted - //TODO refresh icon + //recreate the icon if the taskbar was restarted (e.g. due to Win Explorer shutdown) + TaskbarCreated(); } + //forward message ProcessWindowMessage(messageId, wparam, lparam); - //handle mouse clicks... - // Pass the message to the default window procedure return WinApi.DefWindowProc(hwnd, messageId, wparam, lparam); } diff --git a/Source/NotifyIconWpf/Interop/WindowMessageSink.cs b/Source/NotifyIconWpf/Interop/WindowMessageSink.cs index 29e2542..3e59a39 100644 --- a/Source/NotifyIconWpf/Interop/WindowMessageSink.cs +++ b/Source/NotifyIconWpf/Interop/WindowMessageSink.cs @@ -24,6 +24,14 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// public NotifyIconVersion Version { get; set; } + + /// + /// Used to track whether a mouse-up event is just + /// the aftermath of a double-click and therefore needs + /// to be suppressed. + /// + private bool isDoubleClick; + #endregion @@ -47,7 +55,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop public event Action BallonToolTipChanged; /// - /// Fired if the taskbar was created. Requires the taskbar + /// Fired if the taskbar was created or restarted. Requires the taskbar /// icon to be reset. /// public event Action TaskbarCreated; @@ -119,11 +127,16 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop case 0x202: Debug.WriteLine("left up"); - MouseEventReceived(MouseEvent.IconLeftMouseUp); + if (!isDoubleClick) + { + MouseEventReceived(MouseEvent.IconLeftMouseUp); + } + isDoubleClick = false; break; case 0x203: Debug.WriteLine("left click 2"); + isDoubleClick = true; MouseEventReceived(MouseEvent.IconDoubleClick); break; diff --git a/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs b/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs index e3a893a..21aead1 100644 --- a/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs +++ b/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs @@ -74,7 +74,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region ToolTip dependency property override /// @@ -119,7 +118,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region Icon property / IconSource dependency property private Icon icon; @@ -194,7 +192,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region TaskbarIconPopup dependency property /// @@ -242,12 +239,11 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Provides information about the updated property. private void OnTaskbarIconPopupPropertyChanged(DependencyPropertyChangedEventArgs e) { - Popup newValue = (Popup) e.NewValue; + //currently not needed } #endregion - #region MenuActivation dependency property /// @@ -297,19 +293,15 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Provides information about the updated property. private void OnMenuActivationPropertyChanged(DependencyPropertyChangedEventArgs e) { - PopupActivationMode newValue = (PopupActivationMode) e.NewValue; - - //TODO provide implementation - throw new NotImplementedException("Change event handler for dependency property MenuActivation not implemented."); + //currently not needed } #endregion - #region PopupActivation dependency property /// - /// Defines what mouse events trigger the . + /// Defines what mouse events trigger the . /// Default is . /// public static readonly DependencyProperty PopupActivationProperty = @@ -321,7 +313,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// /// A property wrapper for the /// dependency property:
- /// Defines what mouse events trigger the . + /// Defines what mouse events trigger the . /// Default is . ///
public PopupActivationMode PopupActivation @@ -355,15 +347,11 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Provides information about the updated property. private void OnPopupActivationPropertyChanged(DependencyPropertyChangedEventArgs e) { - PopupActivationMode newValue = (PopupActivationMode) e.NewValue; - - //TODO provide implementation - throw new NotImplementedException("Change event handler for dependency property PopupActivation not implemented."); + //currently not needed } #endregion - #region Visibility dependency property override /// @@ -405,7 +393,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region ContextMenu dependency property override /// @@ -432,8 +419,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Provides information about the updated property. private void OnContextMenuPropertyChanged(DependencyPropertyChangedEventArgs e) { - ContextMenu newValue = (ContextMenu) e.NewValue; - //TODO provide implementation + //currently not needed } #endregion @@ -524,6 +510,48 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion + #region TaskbarIconMiddleMouseDown + + /// + /// TaskbarIconMiddleMouseDown Routed Event + /// + public static readonly RoutedEvent TaskbarIconMiddleMouseDownEvent = EventManager.RegisterRoutedEvent("TaskbarIconMiddleMouseDown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user presses the middle mouse button. + /// + public event RoutedEventHandler TaskbarIconMiddleMouseDown + { + add { AddHandler(TaskbarIconMiddleMouseDownEvent, value); } + remove { RemoveHandler(TaskbarIconMiddleMouseDownEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconMiddleMouseDown event. + /// + protected RoutedEventArgs RaiseTaskbarIconMiddleMouseDownEvent() + { + return RaiseTaskbarIconMiddleMouseDownEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconMiddleMouseDown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconMiddleMouseDownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconMiddleMouseDownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TaskbarIconLeftMouseUp /// @@ -606,6 +634,332 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion + #region TaskbarIconMiddleMouseUp + + /// + /// TaskbarIconMiddleMouseUp Routed Event + /// + public static readonly RoutedEvent TaskbarIconMiddleMouseUpEvent = EventManager.RegisterRoutedEvent("TaskbarIconMiddleMouseUp", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user releases the middle mouse button. + /// + public event RoutedEventHandler TaskbarIconMiddleMouseUp + { + add { AddHandler(TaskbarIconMiddleMouseUpEvent, value); } + remove { RemoveHandler(TaskbarIconMiddleMouseUpEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconMiddleMouseUp event. + /// + protected RoutedEventArgs RaiseTaskbarIconMiddleMouseUpEvent() + { + return RaiseTaskbarIconMiddleMouseUpEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconMiddleMouseUp event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconMiddleMouseUpEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconMiddleMouseUpEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TaskbarIconMouseDoubleClick + + /// + /// TaskbarIconMouseDoubleClick Routed Event + /// + public static readonly RoutedEvent TaskbarIconMouseDoubleClickEvent = EventManager.RegisterRoutedEvent("TaskbarIconMouseDoubleClick", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user double-clicks the taskbar icon. + /// + public event RoutedEventHandler TaskbarIconMouseDoubleClick + { + add { AddHandler(TaskbarIconMouseDoubleClickEvent, value); } + remove { RemoveHandler(TaskbarIconMouseDoubleClickEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconMouseDoubleClick event. + /// + protected RoutedEventArgs RaiseTaskbarIconMouseDoubleClickEvent() + { + return RaiseTaskbarIconMouseDoubleClickEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconMouseDoubleClick event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconMouseDoubleClickEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconMouseDoubleClickEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TaskbarIconMouseMove + + /// + /// TaskbarIconMouseMove Routed Event + /// + public static readonly RoutedEvent TaskbarIconMouseMoveEvent = EventManager.RegisterRoutedEvent("TaskbarIconMouseMove", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user moves the mouse over the taskbar icon. + /// + public event RoutedEventHandler TaskbarIconMouseMove + { + add { AddHandler(TaskbarIconMouseMoveEvent, value); } + remove { RemoveHandler(TaskbarIconMouseMoveEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconMouseMove event. + /// + protected RoutedEventArgs RaiseTaskbarIconMouseMoveEvent() + { + return RaiseTaskbarIconMouseMoveEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconMouseMove event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconMouseMoveEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconMouseMoveEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TaskbarIconBalloonTipShown + + /// + /// TaskbarIconBalloonTipShown Routed Event + /// + public static readonly RoutedEvent TaskbarIconBalloonTipShownEvent = EventManager.RegisterRoutedEvent("TaskbarIconBalloonTipShown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when a balloon ToolTip is displayed. + /// + public event RoutedEventHandler TaskbarIconBalloonTipShown + { + add { AddHandler(TaskbarIconBalloonTipShownEvent, value); } + remove { RemoveHandler(TaskbarIconBalloonTipShownEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconBalloonTipShown event. + /// + protected RoutedEventArgs RaiseTaskbarIconBalloonTipShownEvent() + { + return RaiseTaskbarIconBalloonTipShownEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconBalloonTipShown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconBalloonTipShownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconBalloonTipShownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TaskbarIconBalloonTipClosed + + /// + /// TaskbarIconBalloonTipClosed Routed Event + /// + public static readonly RoutedEvent TaskbarIconBalloonTipClosedEvent = EventManager.RegisterRoutedEvent("TaskbarIconBalloonTipClosed", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when a balloon ToolTip was closed. + /// + public event RoutedEventHandler TaskbarIconBalloonTipClosed + { + add { AddHandler(TaskbarIconBalloonTipClosedEvent, value); } + remove { RemoveHandler(TaskbarIconBalloonTipClosedEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconBalloonTipClosed event. + /// + protected RoutedEventArgs RaiseTaskbarIconBalloonTipClosedEvent() + { + return RaiseTaskbarIconBalloonTipClosedEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconBalloonTipClosed event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconBalloonTipClosedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconBalloonTipClosedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TaskbarIconBalloonTipClicked + + /// + /// TaskbarIconBalloonTipClicked Routed Event + /// + public static readonly RoutedEvent TaskbarIconBalloonTipClickedEvent = EventManager.RegisterRoutedEvent("TaskbarIconBalloonTipClicked", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user clicks on a balloon ToolTip. + /// + public event RoutedEventHandler TaskbarIconBalloonTipClicked + { + add { AddHandler(TaskbarIconBalloonTipClickedEvent, value); } + remove { RemoveHandler(TaskbarIconBalloonTipClickedEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconBalloonTipClicked event. + /// + protected RoutedEventArgs RaiseTaskbarIconBalloonTipClickedEvent() + { + return RaiseTaskbarIconBalloonTipClickedEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconBalloonTipClicked event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconBalloonTipClickedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconBalloonTipClickedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TaskbarIconContextMenuOpen (and PreviewTaskbarIconContextMenuOpen) + + /// + /// TaskbarIconContextMenuOpen Routed Event + /// + public static readonly RoutedEvent TaskbarIconContextMenuOpenEvent = EventManager.RegisterRoutedEvent("TaskbarIconContextMenuOpen", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Bubbled event that occurs when the context menu of the taskbar icon is being displayed. + /// + public event RoutedEventHandler TaskbarIconContextMenuOpen + { + add { AddHandler(TaskbarIconContextMenuOpenEvent, value); } + remove { RemoveHandler(TaskbarIconContextMenuOpenEvent, value); } + } + + /// + /// A helper method to raise the TaskbarIconContextMenuOpen event. + /// + protected RoutedEventArgs RaiseTaskbarIconContextMenuOpenEvent() + { + return RaiseTaskbarIconContextMenuOpenEvent(this); + } + + /// + /// A static helper method to raise the TaskbarIconContextMenuOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTaskbarIconContextMenuOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TaskbarIconContextMenuOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + /// + /// PreviewTaskbarIconContextMenuOpen Routed Event + /// + public static readonly RoutedEvent PreviewTaskbarIconContextMenuOpenEvent = EventManager.RegisterRoutedEvent("PreviewTaskbarIconContextMenuOpen", + RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Tunneled event that occurs when the context menu of the taskbar icon is being displayed. + /// + public event RoutedEventHandler PreviewTaskbarIconContextMenuOpen + { + add { AddHandler(PreviewTaskbarIconContextMenuOpenEvent, value); } + remove { RemoveHandler(PreviewTaskbarIconContextMenuOpenEvent, value); } + } + + /// + /// A helper method to raise the PreviewTaskbarIconContextMenuOpen event. + /// + protected RoutedEventArgs RaisePreviewTaskbarIconContextMenuOpenEvent() + { + return RaisePreviewTaskbarIconContextMenuOpenEvent(this); + } + + /// + /// A static helper method to raise the PreviewTaskbarIconContextMenuOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePreviewTaskbarIconContextMenuOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PreviewTaskbarIconContextMenuOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion #region TaskbarIconPopupOpen (and PreviewTaskbarIconPopupOpen) @@ -685,6 +1039,7 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion + #region TaskbarIconToolTipOpen (and PreviewTaskbarIconToolTipOpen) /// @@ -763,88 +1118,87 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region TaskbarIconContextMenuOpen (and PreviewTaskbarIconContextMenuOpen) + #region TaskbarIconToolTipClose (and PreviewTaskbarIconToolTipClose) /// - /// TaskbarIconContextMenuOpen Routed Event + /// TaskbarIconToolTipClose Routed Event /// - public static readonly RoutedEvent TaskbarIconContextMenuOpenEvent = EventManager.RegisterRoutedEvent("TaskbarIconContextMenuOpen", + public static readonly RoutedEvent TaskbarIconToolTipCloseEvent = EventManager.RegisterRoutedEvent("TaskbarIconToolTipClose", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); /// - /// Bubbled event that occurs when the context menu of the taskbar icon is being displayed. + /// Bubbled event that occurs when a custom tooltip is being closed. /// - public event RoutedEventHandler TaskbarIconContextMenuOpen + public event RoutedEventHandler TaskbarIconToolTipClose { - add { AddHandler(TaskbarIconContextMenuOpenEvent, value); } - remove { RemoveHandler(TaskbarIconContextMenuOpenEvent, value); } + add { AddHandler(TaskbarIconToolTipCloseEvent, value); } + remove { RemoveHandler(TaskbarIconToolTipCloseEvent, value); } } /// - /// A helper method to raise the TaskbarIconContextMenuOpen event. + /// A helper method to raise the TaskbarIconToolTipClose event. /// - protected RoutedEventArgs RaiseTaskbarIconContextMenuOpenEvent() + protected RoutedEventArgs RaiseTaskbarIconToolTipCloseEvent() { - return RaiseTaskbarIconContextMenuOpenEvent(this); + return RaiseTaskbarIconToolTipCloseEvent(this); } /// - /// A static helper method to raise the TaskbarIconContextMenuOpen event on a target element. + /// A static helper method to raise the TaskbarIconToolTipClose event on a target element. /// /// UIElement or ContentElement on which to raise the event - internal static RoutedEventArgs RaiseTaskbarIconContextMenuOpenEvent(DependencyObject target) + internal static RoutedEventArgs RaiseTaskbarIconToolTipCloseEvent(DependencyObject target) { if (target == null) return null; RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TaskbarIconContextMenuOpenEvent; + args.RoutedEvent = TaskbarIconToolTipCloseEvent; RoutedEventHelper.RaiseEvent(target, args); return args; } /// - /// PreviewTaskbarIconContextMenuOpen Routed Event + /// PreviewTaskbarIconToolTipClose Routed Event /// - public static readonly RoutedEvent PreviewTaskbarIconContextMenuOpenEvent = EventManager.RegisterRoutedEvent("PreviewTaskbarIconContextMenuOpen", + public static readonly RoutedEvent PreviewTaskbarIconToolTipCloseEvent = EventManager.RegisterRoutedEvent("PreviewTaskbarIconToolTipClose", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); /// - /// Tunneled event that occurs when the context menu of the taskbar icon is being displayed. + /// Tunneled event that occurs when a custom tooltip is being closed. /// - public event RoutedEventHandler PreviewTaskbarIconContextMenuOpen + public event RoutedEventHandler PreviewTaskbarIconToolTipClose { - add { AddHandler(PreviewTaskbarIconContextMenuOpenEvent, value); } - remove { RemoveHandler(PreviewTaskbarIconContextMenuOpenEvent, value); } + add { AddHandler(PreviewTaskbarIconToolTipCloseEvent, value); } + remove { RemoveHandler(PreviewTaskbarIconToolTipCloseEvent, value); } } /// - /// A helper method to raise the PreviewTaskbarIconContextMenuOpen event. + /// A helper method to raise the PreviewTaskbarIconToolTipClose event. /// - protected RoutedEventArgs RaisePreviewTaskbarIconContextMenuOpenEvent() + protected RoutedEventArgs RaisePreviewTaskbarIconToolTipCloseEvent() { - return RaisePreviewTaskbarIconContextMenuOpenEvent(this); + return RaisePreviewTaskbarIconToolTipCloseEvent(this); } /// - /// A static helper method to raise the PreviewTaskbarIconContextMenuOpen event on a target element. + /// A static helper method to raise the PreviewTaskbarIconToolTipClose event on a target element. /// /// UIElement or ContentElement on which to raise the event - internal static RoutedEventArgs RaisePreviewTaskbarIconContextMenuOpenEvent(DependencyObject target) + internal static RoutedEventArgs RaisePreviewTaskbarIconToolTipCloseEvent(DependencyObject target) { if (target == null) return null; RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PreviewTaskbarIconContextMenuOpenEvent; + args.RoutedEvent = PreviewTaskbarIconToolTipCloseEvent; RoutedEventHelper.RaiseEvent(target, args); return args; } #endregion - - //CONSTRUCTOR DECLARATIONS + //BASE CLASS PROPERTY OVERRIDES /// /// Registers properties. diff --git a/Source/NotifyIconWpf/TaskbarIcon.Interop.cs b/Source/NotifyIconWpf/TaskbarIcon.Interop.cs index 4921a97..43ef54d 100644 --- a/Source/NotifyIconWpf/TaskbarIcon.Interop.cs +++ b/Source/NotifyIconWpf/TaskbarIcon.Interop.cs @@ -1,13 +1,9 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Drawing; -using System.Linq; -using System.Text; using System.Threading; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; using Hardcodet.Wpf.TaskbarNotification.Interop; namespace Hardcodet.Wpf.TaskbarNotification @@ -27,39 +23,11 @@ namespace Hardcodet.Wpf.TaskbarNotification private readonly Timer singleClickTimer; - #region SetVersion + #region Update ToolTip Settings /// - /// Sets the version flag for the . - /// - private void SetVersion() - { - iconData.VersionOrTimeout = (uint) NotifyIconVersion.Vista; - bool status = WinApi.Shell_NotifyIcon(NotifyCommand.SetVersion, ref iconData); - - if (!status) - { - iconData.VersionOrTimeout = (uint) NotifyIconVersion.Win2000; - status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); - } - - if (!status) - { - iconData.VersionOrTimeout = (uint)NotifyIconVersion.Win95; - status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); - } - - if (!status) - { - Debug.Fail("Could not set version"); - } - } - - #endregion - - - /// - /// Sets tooltip settings for the class. + /// Sets tooltip settings for the class depending on defined + /// dependency properties and OS support. /// private void WriteToolTipSettings() { @@ -86,6 +54,7 @@ namespace Hardcodet.Wpf.TaskbarNotification Util.WriteIconData(ref iconData, NotifyCommand.Modify, flags); } + #endregion #region Show / Hide Balloon ToolTip @@ -98,7 +67,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Indicates the severity. public void ShowBalloonTip(string title, string message, BalloonIcon icon) { - lock(this) + lock (this) { ShowBalloonTip(title, message, icon.GetBalloonFlag(), IntPtr.Zero); } @@ -118,14 +87,13 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (customIcon == null) throw new ArgumentNullException("customIcon"); - lock(this) + lock (this) { ShowBalloonTip(title, message, BalloonFlags.User, customIcon.Handle); } } - /// /// Invokes in order to display /// a given balloon ToolTip. @@ -148,7 +116,6 @@ namespace Hardcodet.Wpf.TaskbarNotification } - /// /// Hides a balloon ToolTip, if any is displayed. /// @@ -163,7 +130,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region Single Click Timer event /// @@ -175,6 +141,8 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (IsDisposed) return; + Console.Out.WriteLine("TIMER EVENT"); + //run action Action action = delayedTimerAction; if (action != null) @@ -189,7 +157,6 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion - #region Show Tray Popup / Context Menu /// @@ -232,10 +199,10 @@ namespace Hardcodet.Wpf.TaskbarNotification //raise preview event var args = RaisePreviewTaskbarIconContextMenuOpenEvent(); if (args.Handled) return; - + //CreateActivationWindow(); ContextMenu.IsOpen = true; - + //activate the message window to track deactivation - otherwise, the context menu //does not close if the user clicks somewhere else WinApi.SetForegroundWindow(messageSink.MessageWindowHandle); @@ -247,4 +214,4 @@ namespace Hardcodet.Wpf.TaskbarNotification #endregion } -} +} \ No newline at end of file diff --git a/Source/NotifyIconWpf/TaskbarIcon.cs b/Source/NotifyIconWpf/TaskbarIcon.cs index d13005a..b8b711d 100644 --- a/Source/NotifyIconWpf/TaskbarIcon.cs +++ b/Source/NotifyIconWpf/TaskbarIcon.cs @@ -1,47 +1,18 @@ using System; using System.ComponentModel; +using System.Diagnostics; using System.Threading; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Media; using Hardcodet.Wpf.TaskbarNotification.Interop; -using Rect=Hardcodet.Wpf.TaskbarNotification.Interop.Rect; + + namespace Hardcodet.Wpf.TaskbarNotification { - internal class MyClass - { - public void Test() - { - TaskbarIcon icon = new TaskbarIcon(); - icon.Icon = Properties.Resources.DefaultTrayIcon; - Console.Out.WriteLine("DISPLAY NOW..."); - Thread.CurrentThread.Join(1500); - //icon.ShowBalloonTip("some title", "hello world", Properties.Resources.DefaultTrayIcon); - //Console.Out.WriteLine("status = {0}", status); - Thread.CurrentThread.Join(5000); - } - - public void Test2() - { - var tbInfo = TrayLocator.GetTaskbarInformation(); - var w = new Window(); - w.Background = Brushes.Red; - w.WindowStyle = WindowStyle.None; - - Rect rect = tbInfo.Rectangle; - w.Width = Math.Max(20, rect.right - rect.left); - w.Height = Math.Max(20, rect.bottom - rect.top); - w.Left = rect.left; - w.Top = rect.top - 100; - w.ShowDialog(); - } - } - /// - /// Represent a taskbar icon that sits in the system - /// tray. + /// A WPF proxy to for a taskbar icon (NotifyIcon) that sits in the system's + /// taskbar notification area ("system tray"). /// public partial class TaskbarIcon : FrameworkElement, IDisposable { @@ -62,7 +33,9 @@ namespace Hardcodet.Wpf.TaskbarNotification /// - /// Indicates whether custom tooltips are supported. + /// Indicates whether custom tooltips are supported, which depends + /// on the OS. Windows Vista or higher is required in order to + /// support this feature. /// public bool SupportsCustomToolTips { @@ -102,10 +75,8 @@ namespace Hardcodet.Wpf.TaskbarNotification //init single click timer singleClickTimer = new Timer(DoSingleClickAction); - //register listener in order to get notified when the application closes if (Application.Current != null) Application.Current.Exit += OnExit; - } @@ -124,6 +95,7 @@ namespace Hardcodet.Wpf.TaskbarNotification switch(me) { case MouseEvent.MouseMove: + RaiseTaskbarIconMouseMoveEvent(); break; case MouseEvent.IconRightMouseDown: RaiseTaskbarIconRightMouseDownEvent(); @@ -138,16 +110,19 @@ namespace Hardcodet.Wpf.TaskbarNotification RaiseTaskbarIconLeftMouseUpEvent(); break; case MouseEvent.IconMiddleMouseDown: + RaiseTaskbarIconMiddleMouseDownEvent(); break; case MouseEvent.IconMiddleMouseUp: + RaiseTaskbarIconMiddleMouseUpEvent(); break; case MouseEvent.IconDoubleClick: - //cancel single click timer singleClickTimer.Change(Timeout.Infinite, Timeout.Infinite); - + //bubble event + RaiseTaskbarIconMouseDoubleClickEvent(); break; case MouseEvent.BalloonToolTipClicked: + RaiseTaskbarIconBalloonTipClickedEvent(); break; default: throw new ArgumentOutOfRangeException("me", "Missing handler for mouse event flag: " + me); @@ -191,23 +166,92 @@ namespace Hardcodet.Wpf.TaskbarNotification + /// + /// Displays a custom tooltip, if available. This functionality + /// is only available for Windows Vista and above. + /// + /// Whether to show or hide the tooltip. private void OnToolTipChange(bool visible) { //if we have a custom tooltip, show it now if (ToolTip == null) return; + ToolTip tt = (ToolTip)ToolTip; - tt.IsOpen = visible; + + if (visible) + { + var args = RaisePreviewTaskbarIconToolTipOpenEvent(); + if (args.Handled) return; + + tt.IsOpen = true; + RaiseTaskbarIconToolTipOpenEvent(); + } + else + { + var args = RaisePreviewTaskbarIconToolTipCloseEvent(); + if (args.Handled) return; + + tt.IsOpen = false; + RaiseTaskbarIconToolTipCloseEvent(); + } } + /// + /// Bubbles events if a balloon ToolTip was displayed + /// or removed. + /// + /// Whether the ToolTip was just displayed + /// or removed. private void OnBalloonToolTipChanged(bool visible) { - //TODO just raise event + if (visible) + { + RaiseTaskbarIconBalloonTipShownEvent(); + } + else + { + RaiseTaskbarIconBalloonTipClosedEvent(); + } } + + #region SetVersion + + /// + /// Sets the version flag for the . + /// + private void SetVersion() + { + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Vista; + bool status = WinApi.Shell_NotifyIcon(NotifyCommand.SetVersion, ref iconData); + + if (!status) + { + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Win2000; + status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); + } + + if (!status) + { + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Win95; + status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); + } + + if (!status) + { + Debug.Fail("Could not set version"); + } + } + + #endregion + + + #region Create / Remove Taskbar Icon + /// /// Recreates the taskbar icon if the whole taskbar was /// recreated (e.g. because Explorer was shut down). @@ -219,12 +263,6 @@ namespace Hardcodet.Wpf.TaskbarNotification } - - - - - #region create / remove taskbar icon - /// /// Creates the taskbar icon. This message is invoked during initialization, /// if the taskbar is restarted, and whenever the icon is displayed. diff --git a/Source/Sample Project/Window1.xaml b/Source/Sample Project/Window1.xaml index 8c449cf..d373d1e 100644 --- a/Source/Sample Project/Window1.xaml +++ b/Source/Sample Project/Window1.xaml @@ -68,8 +68,8 @@ Title="Window1" Height="480" Width="579"> x:Name="tb" ToolTip="{StaticResource yb}" Height="23" VerticalAlignment="Top" > - - + +