diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/AppBarInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/AppBarInfo.cs new file mode 100644 index 0000000..a5d2ee1 --- /dev/null +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/AppBarInfo.cs @@ -0,0 +1,109 @@ +// Some interop code taken from Mike Marshall's AnyForm + +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + public class AppBarInfo + { + [DllImport("user32.dll")] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport("shell32.dll")] + private static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA data); + + [DllImport("user32.dll")] + private static extern int SystemParametersInfo(uint uiAction, uint uiParam, + IntPtr pvParam, uint fWinIni); + + + private const int ABE_BOTTOM = 3; + private const int ABE_LEFT = 0; + private const int ABE_RIGHT = 2; + private const int ABE_TOP = 1; + + private const int ABM_GETTASKBARPOS = 0x00000005; + + // SystemParametersInfo constants + private const uint SPI_GETWORKAREA = 0x0030; + + private APPBARDATA m_data; + + public ScreenEdge Edge + { + get { return (ScreenEdge) m_data.uEdge; } + } + + public Rectangle WorkArea + { + get { return GetRectangle(m_data.rc); } + } + + private Rectangle GetRectangle(RECT rc) + { + return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); + } + + public void GetPosition(string strClassName, string strWindowName) + { + m_data = new APPBARDATA(); + m_data.cbSize = (uint) Marshal.SizeOf(m_data.GetType()); + + IntPtr hWnd = FindWindow(strClassName, strWindowName); + + if (hWnd != IntPtr.Zero) + { + uint uResult = SHAppBarMessage(ABM_GETTASKBARPOS, ref m_data); + + if (uResult != 1) + { + throw new Exception("Failed to communicate with the given AppBar"); + } + } + else + { + throw new Exception("Failed to find an AppBar that matched the given criteria"); + } + } + + + public void GetSystemTaskBarPosition() + { + GetPosition("Shell_TrayWnd", null); + } + + + public enum ScreenEdge + { + Undefined = -1, + Left = ABE_LEFT, + Top = ABE_TOP, + Right = ABE_RIGHT, + Bottom = ABE_BOTTOM + } + + + [StructLayout(LayoutKind.Sequential)] + private struct APPBARDATA + { + public uint cbSize; + public IntPtr hWnd; + public uint uCallbackMessage; + public uint uEdge; + public RECT rc; + public int lParam; + } + + + [StructLayout(LayoutKind.Sequential)] + private struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + } +} \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/BalloonFlags.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/BalloonFlags.cs index 2e02633..c6c8e7e 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/BalloonFlags.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/BalloonFlags.cs @@ -1,3 +1,5 @@ +using System; + namespace Hardcodet.Wpf.TaskbarNotification.Interop { /// diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/NotifyIconData.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/NotifyIconData.cs index e51db51..da8231d 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/NotifyIconData.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/NotifyIconData.cs @@ -56,7 +56,8 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// the terminating NULL. For Version 5.0 and later, szTip can have a maximum of /// 128 characters, including the terminating NULL. /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string ToolTipText; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string ToolTipText; /// @@ -66,7 +67,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// /// A value that specifies which bits of the state member are retrieved or modified. - /// For example, setting this member to + /// For example, setting this member to /// causes only the item's hidden /// state to be retrieved. /// @@ -76,12 +77,13 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// String with the text for a balloon ToolTip. It can have a maximum of 255 characters. /// To remove the ToolTip, set the NIF_INFO flag in uFlags and set szInfo to an empty string. /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string BalloonText; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string BalloonText; /// /// Mainly used to set the version when is invoked /// with . However, for legacy operations, - /// the same member is also used to set timouts for balloon ToolTips. + /// the same member is also used to set timeouts for balloon ToolTips. /// public uint VersionOrTimeout; @@ -89,7 +91,8 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// String containing a title for a balloon ToolTip. This title appears in boldface /// above the text. It can have a maximum of 63 characters. /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string BalloonTitle; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string BalloonTitle; /// /// Adds an icon to a balloon ToolTip, which is placed to the left of the title. If the @@ -108,7 +111,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// /// Windows Vista (Shell32.dll version 6.0.6) and later. The handle of a customized /// balloon icon provided by the application that should be used independently - /// of the tray icon. If this member is non-NULL and the + /// of the tray icon. If this member is non-NULL and the /// flag is set, this icon is used as the balloon icon.
/// If this member is NULL, the legacy behavior is carried out. ///
@@ -120,7 +123,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// a hidden taskbar icon without the icon being set. ///
/// - /// + /// NotifyIconData public static NotifyIconData CreateDefault(IntPtr handle) { var data = new NotifyIconData(); @@ -157,7 +160,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop | IconDataMembers.Tip; //reset strings - data.ToolTipText = data.BalloonText = data.BalloonTitle = String.Empty; + data.ToolTipText = data.BalloonText = data.BalloonTitle = string.Empty; return data; } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/SystemInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/SystemInfo.cs index feb42a4..3171a8b 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/SystemInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/SystemInfo.cs @@ -2,37 +2,34 @@ using System.Windows.Interop; namespace Hardcodet.Wpf.TaskbarNotification.Interop { - public static class SystemInfo - { - private static System.Windows.Point? dpiFactors; - - private static System.Windows.Point? DpiFactors + /// + /// This class is a helper for system information, currently to get the DPI factors + /// + public static class SystemInfo { - get - { - if (dpiFactors == null) - using (var source = new HwndSource(new HwndSourceParameters())) - dpiFactors = new System.Windows.Point(source.CompositionTarget.TransformToDevice.M11, source.CompositionTarget.TransformToDevice.M22); - return dpiFactors; - } + private static readonly System.Windows.Point DpiFactors; + + static SystemInfo() + { + using (var source = new HwndSource(new HwndSourceParameters())) + { + if (source.CompositionTarget?.TransformToDevice != null) + { + DpiFactors = new System.Windows.Point(source.CompositionTarget.TransformToDevice.M11, source.CompositionTarget.TransformToDevice.M22); + return; + } + DpiFactors = new System.Windows.Point(1, 1); + } + } + + /// + /// Returns the DPI X Factor + /// + public static double DpiFactorX => DpiFactors.X; + + /// + /// Returns the DPI Y Factor + /// + public static double DpiFactorY => DpiFactors.Y; } - - public static double DpiXFactor - { - get - { - var factors = DpiFactors; - return factors.HasValue ? factors.Value.X : 1; - } - } - - public static double DpiYFactor - { - get - { - var factors = DpiFactors; - return factors.HasValue ? factors.Value.Y : 1; - } - } - } -} +} \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/TrayInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/TrayInfo.cs index 1516e1c..c762a68 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/TrayInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/TrayInfo.cs @@ -1,10 +1,6 @@ // Some interop code taken from Mike Marshall's AnyForm -using System; using System.Drawing; -using System.Runtime.InteropServices; -using System.Windows; - namespace Hardcodet.Wpf.TaskbarNotification.Interop { @@ -26,25 +22,24 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop Rectangle rcWorkArea = info.WorkArea; int x = 0, y = 0; - if (info.Edge == AppBarInfo.ScreenEdge.Left) + switch (info.Edge) { - x = rcWorkArea.Right + space; - y = rcWorkArea.Bottom; - } - else if (info.Edge == AppBarInfo.ScreenEdge.Bottom) - { - x = rcWorkArea.Right; - y = rcWorkArea.Bottom - rcWorkArea.Height - space; - } - else if (info.Edge == AppBarInfo.ScreenEdge.Top) - { - x = rcWorkArea.Right; - y = rcWorkArea.Top + rcWorkArea.Height + space; - } - else if (info.Edge == AppBarInfo.ScreenEdge.Right) - { - x = rcWorkArea.Right - rcWorkArea.Width - space; - y = rcWorkArea.Bottom; + case AppBarInfo.ScreenEdge.Left: + x = rcWorkArea.Right + space; + y = rcWorkArea.Bottom; + break; + case AppBarInfo.ScreenEdge.Bottom: + x = rcWorkArea.Right; + y = rcWorkArea.Bottom - rcWorkArea.Height - space; + break; + case AppBarInfo.ScreenEdge.Top: + x = rcWorkArea.Right; + y = rcWorkArea.Top + rcWorkArea.Height + space; + break; + case AppBarInfo.ScreenEdge.Right: + x = rcWorkArea.Right - rcWorkArea.Width - space; + y = rcWorkArea.Bottom; + break; } return GetDeviceCoordinates(new Point {X = x, Y = y}); @@ -54,112 +49,15 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// Recalculates OS coordinates in order to support WPFs coordinate /// system if OS scaling (DPIs) is not 100%. /// - /// - /// + /// Point + /// Point public static Point GetDeviceCoordinates(Point point) { - return new Point() { X = (int)(point.X / SystemInfo.DpiXFactor), Y = (int)(point.Y / SystemInfo.DpiYFactor) }; - } - } - - - public class AppBarInfo - { - [DllImport("user32.dll")] - private static extern IntPtr FindWindow(String lpClassName, String lpWindowName); - - [DllImport("shell32.dll")] - private static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA data); - - [DllImport("user32.dll")] - private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, - IntPtr pvParam, UInt32 fWinIni); - - - private const int ABE_BOTTOM = 3; - private const int ABE_LEFT = 0; - private const int ABE_RIGHT = 2; - private const int ABE_TOP = 1; - - private const int ABM_GETTASKBARPOS = 0x00000005; - - // SystemParametersInfo constants - private const UInt32 SPI_GETWORKAREA = 0x0030; - - private APPBARDATA m_data; - - public ScreenEdge Edge - { - get { return (ScreenEdge) m_data.uEdge; } - } - - public Rectangle WorkArea - { - get { return GetRectangle(m_data.rc); } - } - - private Rectangle GetRectangle(RECT rc) - { - return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); - } - - public void GetPosition(string strClassName, string strWindowName) - { - m_data = new APPBARDATA(); - m_data.cbSize = (UInt32) Marshal.SizeOf(m_data.GetType()); - - IntPtr hWnd = FindWindow(strClassName, strWindowName); - - if (hWnd != IntPtr.Zero) - { - UInt32 uResult = SHAppBarMessage(ABM_GETTASKBARPOS, ref m_data); - - if (uResult != 1) - { - throw new Exception("Failed to communicate with the given AppBar"); - } - } - else - { - throw new Exception("Failed to find an AppBar that matched the given criteria"); - } - } - - - public void GetSystemTaskBarPosition() - { - GetPosition("Shell_TrayWnd", null); - } - - - public enum ScreenEdge - { - Undefined = -1, - Left = ABE_LEFT, - Top = ABE_TOP, - Right = ABE_RIGHT, - Bottom = ABE_BOTTOM - } - - - [StructLayout(LayoutKind.Sequential)] - private struct APPBARDATA - { - public UInt32 cbSize; - public IntPtr hWnd; - public UInt32 uCallbackMessage; - public UInt32 uEdge; - public RECT rc; - public Int32 lParam; - } - - [StructLayout(LayoutKind.Sequential)] - private struct RECT - { - public Int32 left; - public Int32 top; - public Int32 right; - public Int32 bottom; + return new Point + { + X = (int)(point.X / SystemInfo.DpiFactorX), + Y = (int)(point.Y / SystemInfo.DpiFactorY) + }; } } } \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WinApi.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WinApi.cs index a3e4df2..94d6db6 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WinApi.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WinApi.cs @@ -8,6 +8,8 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// internal static class WinApi { + private const string User32 = "user32.dll"; + /// /// Creates, updates or deletes the taskbar icon. /// @@ -18,7 +20,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// /// Creates the helper window that receives messages from the taskar icon. /// - [DllImport("USER32.DLL", EntryPoint = "CreateWindowExW", SetLastError = true)] + [DllImport(User32, EntryPoint = "CreateWindowExW", SetLastError = true)] public static extern IntPtr CreateWindowEx(int dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, @@ -28,21 +30,21 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// /// Processes a default windows procedure. /// - [DllImport("USER32.DLL")] + [DllImport(User32)] public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wparam, IntPtr lparam); /// /// Registers the helper window class. /// - [DllImport("USER32.DLL", EntryPoint = "RegisterClassW", SetLastError = true)] + [DllImport(User32, EntryPoint = "RegisterClassW", SetLastError = true)] public static extern short RegisterClass(ref WindowClass lpWndClass); /// /// Registers a listener for a window message. /// /// - /// - [DllImport("User32.Dll", EntryPoint = "RegisterWindowMessageW")] + /// uint + [DllImport(User32, EntryPoint = "RegisterWindowMessageW")] public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString); /// @@ -50,8 +52,8 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// taskbar icon. /// /// - /// - [DllImport("USER32.DLL", SetLastError = true)] + /// bool + [DllImport(User32, SetLastError = true)] public static extern bool DestroyWindow(IntPtr hWnd); @@ -59,8 +61,8 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// Gives focus to a given window. /// /// - /// - [DllImport("USER32.DLL")] + /// bool + [DllImport(User32)] public static extern bool SetForegroundWindow(IntPtr hWnd); @@ -72,18 +74,18 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// The maximum amount of time, in milliseconds, that can /// elapse between a first click and a second click for the OS to /// consider the mouse action a double-click. - [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + [DllImport(User32, CharSet = CharSet.Auto, ExactSpelling = true)] public static extern int GetDoubleClickTime(); /// /// Gets the screen coordinates of the current mouse position. /// - [DllImport("USER32.DLL", SetLastError = true)] + [DllImport(User32, SetLastError = true)] public static extern bool GetPhysicalCursorPos(ref Point lpPoint); - [DllImport("USER32.DLL", SetLastError = true)] + [DllImport(User32, SetLastError = true)] public static extern bool GetCursorPos(ref Point lpPoint); } } \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowClass.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowClass.cs index 06ccf7e..0a3c5e2 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowClass.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowClass.cs @@ -7,7 +7,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// Callback delegate which is used by the Windows API to /// submit window messages. /// - public delegate IntPtr WindowProcedureHandler(IntPtr hwnd, uint uMsg, IntPtr wparam, IntPtr lparam); + public delegate IntPtr WindowProcedureHandler(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam); /// diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowMessageSink.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowMessageSink.cs index aeb00ce..121a256 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowMessageSink.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Interop/WindowMessageSink.cs @@ -131,7 +131,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// pointer rather than a real window handler.
/// Used at design time. ///
- /// + /// WindowMessageSink internal static WindowMessageSink CreateEmpty() { return new WindowMessageSink @@ -169,7 +169,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop wc.hIcon = IntPtr.Zero; wc.hCursor = IntPtr.Zero; wc.hbrBackground = IntPtr.Zero; - wc.lpszMenuName = ""; + wc.lpszMenuName = string.Empty; wc.lpszClassName = WindowId; // Register the window class @@ -185,11 +185,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop if (MessageWindowHandle == IntPtr.Zero) { -#if SILVERLIGHT - throw new Exception("Message window handle was not a valid pointer."); -#else throw new Win32Exception("Message window handle was not a valid pointer"); -#endif } } @@ -200,20 +196,20 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// /// Callback method that receives messages from the taskbar area. /// - private IntPtr OnWindowMessageReceived(IntPtr hwnd, uint messageId, IntPtr wparam, IntPtr lparam) + private IntPtr OnWindowMessageReceived(IntPtr hWnd, uint messageId, IntPtr wParam, IntPtr lParam) { if (messageId == taskbarRestartMessageId) { //recreate the icon if the taskbar was restarted (e.g. due to Win Explorer shutdown) var listener = TaskbarCreated; - if(listener != null) listener(); + listener?.Invoke(); } //forward message - ProcessWindowMessage(messageId, wparam, lparam); + ProcessWindowMessage(messageId, wParam, lParam); // Pass the message to the default window procedure - return WinApi.DefWindowProc(hwnd, messageId, wparam, lparam); + return WinApi.DefWindowProc(hWnd, messageId, wParam, lParam); } @@ -278,13 +274,13 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop case 0x402: var listener = BalloonToolTipChanged; - if (listener != null) listener(true); + listener?.Invoke(true); break; case 0x403: case 0x404: listener = BalloonToolTipChanged; - if (listener != null) listener(false); + listener?.Invoke(false); break; case 0x405: @@ -293,12 +289,12 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop case 0x406: listener = ChangeToolTipStateRequest; - if (listener != null) listener(true); + listener?.Invoke(true); break; case 0x407: listener = ChangeToolTipStateRequest; - if (listener != null) listener(false); + listener?.Invoke(false); break; default: @@ -328,7 +324,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop Dispose(true); // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to + // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. @@ -340,7 +336,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop /// method does not get called. This gives this base class the /// opportunity to finalize. /// - /// Important: Do not provide destructors in types derived from + /// Important: Do not provide destructor in types derived from /// this class. /// /// diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Properties/AssemblyInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Properties/AssemblyInfo.cs index 5788b36..4f5b5a1 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Properties/AssemblyInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System; -using System.Reflection; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Windows; using System.Windows.Markup; diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/RoutedEventHelper.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/RoutedEventHelper.cs index 2e3004a..a15893a 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/RoutedEventHelper.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/RoutedEventHelper.cs @@ -18,13 +18,13 @@ namespace Hardcodet.Wpf.TaskbarNotification /// RoutedEventArgs to use when raising the event internal static void RaiseEvent(DependencyObject target, RoutedEventArgs args) { - if (target is UIElement) + if (target is UIElement uiElement) { - (target as UIElement).RaiseEvent(args); + uiElement.RaiseEvent(args); } - else if (target is ContentElement) + else if (target is ContentElement contentElement) { - (target as ContentElement).RaiseEvent(args); + contentElement.RaiseEvent(args); } } @@ -37,18 +37,13 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Event handler to be added internal static void AddHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler) { - UIElement uie = element as UIElement; - if (uie != null) + if (element is UIElement uie) { uie.AddHandler(routedEvent, handler); } - else + else if (element is ContentElement ce) { - ContentElement ce = element as ContentElement; - if (ce != null) - { - ce.AddHandler(routedEvent, handler); - } + ce.AddHandler(routedEvent, handler); } } @@ -61,18 +56,13 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Event handler to be removed internal static void RemoveHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler) { - UIElement uie = element as UIElement; - if (uie != null) + if (element is UIElement uie) { uie.RemoveHandler(routedEvent, handler); } - else + else if (element is ContentElement ce) { - ContentElement ce = element as ContentElement; - if (ce != null) - { - ce.RemoveHandler(routedEvent, handler); - } + ce.RemoveHandler(routedEvent, handler); } } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs index d7157d9..b4a582e 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.Declarations.cs @@ -54,7 +54,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// TrayPopupResolved Read-Only Dependency Property /// private static readonly DependencyPropertyKey TrayPopupResolvedPropertyKey - = DependencyProperty.RegisterReadOnly("TrayPopupResolved", typeof (Popup), typeof (TaskbarIcon), + = DependencyProperty.RegisterReadOnly(nameof(TrayPopupResolved), typeof (Popup), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -96,7 +96,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// TrayToolTipResolved Read-Only Dependency Property /// private static readonly DependencyPropertyKey TrayToolTipResolvedPropertyKey - = DependencyProperty.RegisterReadOnly("TrayToolTipResolved", typeof (ToolTip), typeof (TaskbarIcon), + = DependencyProperty.RegisterReadOnly(nameof(TrayToolTipResolved), typeof (ToolTip), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -139,7 +139,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// CustomBalloon Read-Only Dependency Property /// private static readonly DependencyPropertyKey CustomBalloonPropertyKey - = DependencyProperty.RegisterReadOnly("CustomBalloon", typeof (Popup), typeof (TaskbarIcon), + = DependencyProperty.RegisterReadOnly(nameof(CustomBalloon), typeof (Popup), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); /// @@ -198,7 +198,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Resolves an image source and updates the property accordingly. /// public static readonly DependencyProperty IconSourceProperty = - DependencyProperty.Register("IconSource", + DependencyProperty.Register(nameof(IconSource), typeof (ImageSource), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null, IconSourcePropertyChanged)); @@ -256,10 +256,10 @@ namespace Hardcodet.Wpf.TaskbarNotification /// was set or if custom tooltips are not supported. /// public static readonly DependencyProperty ToolTipTextProperty = - DependencyProperty.Register("ToolTipText", + DependencyProperty.Register(nameof(ToolTipText), typeof (string), typeof (TaskbarIcon), - new FrameworkPropertyMetadata(String.Empty, ToolTipTextPropertyChanged)); + new FrameworkPropertyMetadata(string.Empty, ToolTipTextPropertyChanged)); /// @@ -330,7 +330,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// the property is set as well. /// public static readonly DependencyProperty TrayToolTipProperty = - DependencyProperty.Register("TrayToolTip", + DependencyProperty.Register(nameof(TrayToolTip), typeof (UIElement), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null, TrayToolTipPropertyChanged)); @@ -404,7 +404,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// A control that is displayed as a popup when the taskbar icon is clicked. /// public static readonly DependencyProperty TrayPopupProperty = - DependencyProperty.Register("TrayPopup", + DependencyProperty.Register(nameof(TrayPopup), typeof (UIElement), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null, TrayPopupPropertyChanged)); @@ -473,7 +473,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Defaults to . /// public static readonly DependencyProperty MenuActivationProperty = - DependencyProperty.Register("MenuActivation", + DependencyProperty.Register(nameof(MenuActivation), typeof (PopupActivationMode), typeof (TaskbarIcon), new FrameworkPropertyMetadata(PopupActivationMode.RightClick)); @@ -501,7 +501,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Default is . /// public static readonly DependencyProperty PopupActivationProperty = - DependencyProperty.Register("PopupActivation", + DependencyProperty.Register(nameof(PopupActivation), typeof (PopupActivationMode), typeof (TaskbarIcon), new FrameworkPropertyMetadata(PopupActivationMode.LeftClick)); @@ -673,7 +673,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// double clicked. /// public static readonly DependencyProperty DoubleClickCommandProperty = - DependencyProperty.Register("DoubleClickCommand", + DependencyProperty.Register(nameof(DoubleClickCommand), typeof (ICommand), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -700,7 +700,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Command parameter for the . /// public static readonly DependencyProperty DoubleClickCommandParameterProperty = - DependencyProperty.Register("DoubleClickCommandParameter", + DependencyProperty.Register(nameof(DoubleClickCommandParameter), typeof (object), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -726,7 +726,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// The target of the command that is fired if the notify icon is double clicked. /// public static readonly DependencyProperty DoubleClickCommandTargetProperty = - DependencyProperty.Register("DoubleClickCommandTarget", + DependencyProperty.Register(nameof(DoubleClickCommandTarget), typeof (IInputElement), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -753,7 +753,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// double clicked. /// public static readonly DependencyProperty LeftClickCommandProperty = - DependencyProperty.Register("LeftClickCommand", + DependencyProperty.Register(nameof(LeftClickCommand), typeof (ICommand), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -780,7 +780,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Command parameter for the . /// public static readonly DependencyProperty LeftClickCommandParameterProperty = - DependencyProperty.Register("LeftClickCommandParameter", + DependencyProperty.Register(nameof(LeftClickCommandParameter), typeof (object), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -807,7 +807,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// The target of the command that is fired if the notify icon is clicked. /// public static readonly DependencyProperty LeftClickCommandTargetProperty = - DependencyProperty.Register("LeftClickCommandTarget", + DependencyProperty.Register(nameof(LeftClickCommandTarget), typeof (IInputElement), typeof (TaskbarIcon), new FrameworkPropertyMetadata(null)); @@ -834,7 +834,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Set to true to make left clicks work without delay. /// public static readonly DependencyProperty NoLeftClickDelayProperty = - DependencyProperty.Register("NoLeftClickDelay", + DependencyProperty.Register(nameof(NoLeftClickDelay), typeof(bool), typeof(TaskbarIcon), new FrameworkPropertyMetadata(false)); @@ -893,8 +893,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayLeftMouseDownEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayLeftMouseDownEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -935,8 +934,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayRightMouseDownEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayRightMouseDownEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -977,8 +975,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayMiddleMouseDownEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayMiddleMouseDownEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1018,8 +1015,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayLeftMouseUpEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayLeftMouseUpEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1059,8 +1055,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayRightMouseUpEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayRightMouseUpEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1101,8 +1096,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayMiddleMouseUpEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayMiddleMouseUpEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1145,8 +1139,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayMouseDoubleClickEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayMouseDoubleClickEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1186,8 +1179,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - var args = new RoutedEventArgs(); - args.RoutedEvent = TrayMouseMoveEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayMouseMoveEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1228,8 +1220,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayBalloonTipShownEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayBalloonTipShownEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1270,8 +1261,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayBalloonTipClosedEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayBalloonTipClosedEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1312,8 +1302,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayBalloonTipClickedEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayBalloonTipClickedEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1354,8 +1343,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayContextMenuOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayContextMenuOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1392,8 +1380,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PreviewTrayContextMenuOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(PreviewTrayContextMenuOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1433,8 +1420,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayPopupOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayPopupOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1471,8 +1457,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PreviewTrayPopupOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(PreviewTrayPopupOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1512,8 +1497,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayToolTipOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayToolTipOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1550,8 +1534,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PreviewTrayToolTipOpenEvent; + RoutedEventArgs args = new RoutedEventArgs(PreviewTrayToolTipOpenEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1591,8 +1574,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = TrayToolTipCloseEvent; + RoutedEventArgs args = new RoutedEventArgs(TrayToolTipCloseEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1629,8 +1611,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PreviewTrayToolTipCloseEvent; + RoutedEventArgs args = new RoutedEventArgs(PreviewTrayToolTipCloseEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1675,8 +1656,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = PopupOpenedEvent; + RoutedEventArgs args = new RoutedEventArgs(PopupOpenedEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1719,8 +1699,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = ToolTipOpenedEvent; + RoutedEventArgs args = new RoutedEventArgs(ToolTipOpenedEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1763,8 +1742,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (target == null) return null; - RoutedEventArgs args = new RoutedEventArgs(); - args.RoutedEvent = ToolTipCloseEvent; + RoutedEventArgs args = new RoutedEventArgs(ToolTipCloseEvent); RoutedEventHelper.RaiseEvent(target, args); return args; } @@ -1864,7 +1842,7 @@ namespace Hardcodet.Wpf.TaskbarNotification #region ParentTaskbarIcon /// - /// An attached property that is assigned to displayed UI elements (balloos, tooltips, context menus), and + /// An attached property that is assigned to displayed UI elements (balloons, tooltips, context menus), and /// that can be used to bind to this control. The attached property is being derived, so binding is /// quite straightforward: /// @@ -1907,11 +1885,11 @@ namespace Hardcodet.Wpf.TaskbarNotification VisibilityProperty.OverrideMetadata(typeof (TaskbarIcon), md); //register change listener for the DataContext property - md = new FrameworkPropertyMetadata(new PropertyChangedCallback(DataContextPropertyChanged)); + md = new FrameworkPropertyMetadata(DataContextPropertyChanged); DataContextProperty.OverrideMetadata(typeof (TaskbarIcon), md); //register change listener for the ContextMenu property - md = new FrameworkPropertyMetadata(new PropertyChangedCallback(ContextMenuPropertyChanged)); + md = new FrameworkPropertyMetadata(ContextMenuPropertyChanged); ContextMenuProperty.OverrideMetadata(typeof (TaskbarIcon), md); } } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.cs index 58134ab..b590a6b 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/TaskbarIcon.cs @@ -43,6 +43,8 @@ namespace Hardcodet.Wpf.TaskbarNotification /// public partial class TaskbarIcon : FrameworkElement, IDisposable { + private readonly object lockObject = new object(); + #region Members /// @@ -70,10 +72,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// /// The time we should wait for a double click. /// - private int DoubleClickWaitTime - { - get { return NoLeftClickDelay ? 0 : WinApi.GetDoubleClickTime(); } - } + private int DoubleClickWaitTime => NoLeftClickDelay ? 0 : WinApi.GetDoubleClickTime(); /// /// A timer that is used to close open balloon tooltips. @@ -90,10 +89,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// on the OS. Windows Vista or higher is required in order to /// support this feature. /// - public bool SupportsCustomToolTips - { - get { return messageSink.Version == NotifyIconVersion.Vista; } - } + public bool SupportsCustomToolTips => messageSink.Version == NotifyIconVersion.Vista; /// @@ -113,54 +109,65 @@ namespace Hardcodet.Wpf.TaskbarNotification } } - private double scalingFactor = double.NaN; - #endregion #region Construction /// - /// Inits the taskbar icon and registers a message listener + /// Initializes the taskbar icon and registers a message listener /// in order to receive events from the taskbar area. /// public TaskbarIcon() { - //using dummy sink in design mode + // using dummy sink in design mode messageSink = Util.IsDesignMode ? WindowMessageSink.CreateEmpty() : new WindowMessageSink(NotifyIconVersion.Win95); - //init icon data structure + // init icon data structure iconData = NotifyIconData.CreateDefault(messageSink.MessageWindowHandle); - //create the taskbar icon + // create the taskbar icon CreateTaskbarIcon(); - //register event listeners + // register event listeners messageSink.MouseEventReceived += OnMouseEvent; messageSink.TaskbarCreated += OnTaskbarCreated; messageSink.ChangeToolTipStateRequest += OnToolTipChange; messageSink.BalloonToolTipChanged += OnBalloonToolTipChanged; - //init single click / balloon timers + // init single click / balloon timers singleClickTimer = new Timer(DoSingleClickAction); balloonCloseTimer = new Timer(CloseBalloonCallback); - //register listener in order to get notified when the application closes - if (Application.Current != null) Application.Current.Exit += OnExit; + // register listener in order to get notified when the application closes + if (Application.Current != null) + { + Application.Current.Exit += OnExit; + } } #endregion #region Custom Balloons + /// + /// A delegate to handle customer popup positions. + /// public delegate Point GetCustomPopupPosition(); - public GetCustomPopupPosition CustomPopupPosition; + /// + /// Specify a custom popup position + /// + public GetCustomPopupPosition CustomPopupPosition { get; set; } + /// + /// Returns the location of the system tray + /// + /// Point public Point GetPopupTrayPosition() { - return TrayInfo.GetTrayLocation(); - } + return TrayInfo.GetTrayLocation(); + } /// /// Shows a custom control as a tooltip in the tray location. @@ -168,13 +175,13 @@ namespace Hardcodet.Wpf.TaskbarNotification /// /// An optional animation for the popup. /// The time after which the popup is being closed. - /// Submit null in order to keep the balloon open inde + /// Submit null in order to keep the balloon open indefinitely /// /// If /// is a null reference. public void ShowCustomBalloon(UIElement balloon, PopupAnimation animation, int? timeout) { - Dispatcher dispatcher = this.GetDispatcher(); + var dispatcher = this.GetDispatcher(); if (!dispatcher.CheckAccess()) { var action = new Action(() => ShowCustomBalloon(balloon, animation, timeout)); @@ -182,45 +189,45 @@ namespace Hardcodet.Wpf.TaskbarNotification return; } - if (balloon == null) throw new ArgumentNullException("balloon"); + if (balloon == null) throw new ArgumentNullException(nameof(balloon)); if (timeout.HasValue && timeout < 500) { string msg = "Invalid timeout of {0} milliseconds. Timeout must be at least 500 ms"; - msg = String.Format(msg, timeout); - throw new ArgumentOutOfRangeException("timeout", msg); + msg = string.Format(msg, timeout); + throw new ArgumentOutOfRangeException(nameof(timeout), msg); } EnsureNotDisposed(); - //make sure we don't have an open balloon - lock (this) + // make sure we don't have an open balloon + lock (lockObject) { CloseBalloon(); } - //create an invisible popup that hosts the UIElement - Popup popup = new Popup(); - popup.AllowsTransparency = true; + // create an invisible popup that hosts the UIElement + Popup popup = new Popup + { + AllowsTransparency = true + }; - //provide the popup with the taskbar icon's data context + // provide the popup with the taskbar icon's data context UpdateDataContext(popup, null, DataContext); - //don't animate by default - devs can use attached - //events or override + // don't animate by default - developers can use attached events or override popup.PopupAnimation = animation; - //in case the balloon is cleaned up through routed events, the - //control didn't remove the balloon from its parent popup when - //if was closed the last time - just make sure it doesn't have - //a parent that is a popup + // in case the balloon is cleaned up through routed events, the + // control didn't remove the balloon from its parent popup when + // if was closed the last time - just make sure it doesn't have + // a parent that is a popup var parent = LogicalTreeHelper.GetParent(balloon) as Popup; if (parent != null) parent.Child = null; if (parent != null) { - string msg = - "Cannot display control [{0}] in a new balloon popup - that control already has a parent. You may consider creating new balloons every time you want to show one."; - msg = String.Format(msg, balloon); + string msg = "Cannot display control [{0}] in a new balloon popup - that control already has a parent. You may consider creating new balloons every time you want to show one."; + msg = string.Format(msg, balloon); throw new InvalidOperationException(msg); } @@ -233,29 +240,29 @@ namespace Hardcodet.Wpf.TaskbarNotification popup.Placement = PlacementMode.AbsolutePoint; popup.StaysOpen = true; - - Point position = this.CustomPopupPosition != null ? this.CustomPopupPosition() : this.GetPopupTrayPosition(); + + Point position = CustomPopupPosition != null ? CustomPopupPosition() : GetPopupTrayPosition(); popup.HorizontalOffset = position.X - 1; popup.VerticalOffset = position.Y - 1; //store reference - lock (this) + lock (lockObject) { SetCustomBalloon(popup); } - //assign this instance as an attached property + // assign this instance as an attached property SetParentTaskbarIcon(balloon, this); - //fire attached event + // fire attached event RaiseBalloonShowingEvent(balloon, this); - //display item + // display item popup.IsOpen = true; if (timeout.HasValue) { - //register timer to close the popup + // register timer to close the popup balloonCloseTimer.Change(timeout.Value, Timeout.Infinite); } } @@ -272,7 +279,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (IsDisposed) return; - lock (this) + lock (lockObject) { //reset timer in any case balloonCloseTimer.Change(Timeout.Infinite, Timeout.Infinite); @@ -296,38 +303,40 @@ namespace Hardcodet.Wpf.TaskbarNotification return; } - lock (this) + lock (lockObject) { - //reset timer in any case + // reset timer in any case balloonCloseTimer.Change(Timeout.Infinite, Timeout.Infinite); - //reset old popup, if we still have one + // reset old popup, if we still have one Popup popup = CustomBalloon; - if (popup != null) + if (popup == null) { - UIElement element = popup.Child; - - //announce closing - RoutedEventArgs eventArgs = RaiseBalloonClosingEvent(element, this); - if (!eventArgs.Handled) - { - //if the event was handled, clear the reference to the popup, - //but don't close it - the handling code has to manage this stuff now - - //close the popup - popup.IsOpen = false; - - //remove the reference of the popup to the balloon in case we want to reuse - //the balloon (then added to a new popup) - popup.Child = null; - - //reset attached property - if (element != null) SetParentTaskbarIcon(element, null); - } - - //remove custom balloon anyway - SetCustomBalloon(null); + return; } + + UIElement element = popup.Child; + + // announce closing + RoutedEventArgs eventArgs = RaiseBalloonClosingEvent(element, this); + if (!eventArgs.Handled) + { + // if the event was handled, clear the reference to the popup, + // but don't close it - the handling code has to manage this stuff now + + // close the popup + popup.IsOpen = false; + + // remove the reference of the popup to the balloon in case we want to reuse + // the balloon (then added to a new popup) + popup.Child = null; + + // reset attached property + if (element != null) SetParentTaskbarIcon(element, null); + } + + // remove custom balloon anyway + SetCustomBalloon(null); } } @@ -340,7 +349,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (IsDisposed) return; - //switch to UI thread + // switch to UI thread Action action = CloseBalloon; this.GetDispatcher().Invoke(action); } @@ -364,7 +373,7 @@ namespace Hardcodet.Wpf.TaskbarNotification { case MouseEvent.MouseMove: RaiseTrayMouseMoveEvent(); - //immediately return - there's nothing left to evaluate + // immediately return - there's nothing left to evaluate return; case MouseEvent.IconRightMouseDown: RaiseTrayRightMouseDownEvent(); @@ -385,24 +394,24 @@ namespace Hardcodet.Wpf.TaskbarNotification RaiseTrayMiddleMouseUpEvent(); break; case MouseEvent.IconDoubleClick: - //cancel single click timer + // cancel single click timer singleClickTimer.Change(Timeout.Infinite, Timeout.Infinite); - //bubble event + // bubble event RaiseTrayMouseDoubleClickEvent(); break; case MouseEvent.BalloonToolTipClicked: RaiseTrayBalloonTipClickedEvent(); break; default: - throw new ArgumentOutOfRangeException("me", "Missing handler for mouse event flag: " + me); + throw new ArgumentOutOfRangeException(nameof(me), "Missing handler for mouse event flag: " + me); } - //get mouse coordinates + // get mouse coordinates Point cursorPosition = new Point(); if (messageSink.Version == NotifyIconVersion.Vista) { - //physical cursor position is supported for Vista and above + // physical cursor position is supported for Vista and above WinApi.GetPhysicalCursorPos(ref cursorPosition); } else @@ -414,12 +423,12 @@ namespace Hardcodet.Wpf.TaskbarNotification bool isLeftClickCommandInvoked = false; - //show popup, if requested + // show popup, if requested if (me.IsMatch(PopupActivation)) { if (me == MouseEvent.IconLeftMouseUp) { - //show popup once we are sure it's not a double click + // show popup once we are sure it's not a double click singleClickTimerAction = () => { LeftClickCommand.ExecuteIfEnabled(LeftClickCommandParameter, LeftClickCommandTarget ?? this); @@ -430,18 +439,18 @@ namespace Hardcodet.Wpf.TaskbarNotification } else { - //show popup immediately + // show popup immediately ShowTrayPopup(cursorPosition); } } - //show context menu, if requested + // show context menu, if requested if (me.IsMatch(MenuActivation)) { if (me == MouseEvent.IconLeftMouseUp) { - //show context menu once we are sure it's not a double click + // show context menu once we are sure it's not a double click singleClickTimerAction = () => { LeftClickCommand.ExecuteIfEnabled(LeftClickCommandParameter, LeftClickCommandTarget ?? this); @@ -452,15 +461,15 @@ namespace Hardcodet.Wpf.TaskbarNotification } else { - //show context menu immediately + // show context menu immediately ShowContextMenu(cursorPosition); } } - //make sure the left click command is invoked on mouse clicks + // make sure the left click command is invoked on mouse clicks if (me == MouseEvent.IconLeftMouseUp && !isLeftClickCommandInvoked) { - //show context menu once we are sure it's not a double click + // show context menu once we are sure it's not a double click singleClickTimerAction = () => { @@ -481,14 +490,14 @@ namespace Hardcodet.Wpf.TaskbarNotification /// Whether to show or hide the tooltip. private void OnToolTipChange(bool visible) { - //if we don't have a tooltip, there's nothing to do here... + // if we don't have a tooltip, there's nothing to do here... if (TrayToolTipResolved == null) return; if (visible) { if (IsPopupOpen) { - //ignore if we are already displaying something down there + // ignore if we are already displaying something down there return; } @@ -497,10 +506,10 @@ namespace Hardcodet.Wpf.TaskbarNotification TrayToolTipResolved.IsOpen = true; - //raise attached event first + // raise attached event first if (TrayToolTip != null) RaiseToolTipOpenedEvent(TrayToolTip); - //bubble routed event + // bubble routed event RaiseTrayToolTipOpenEvent(); } else @@ -508,12 +517,12 @@ namespace Hardcodet.Wpf.TaskbarNotification var args = RaisePreviewTrayToolTipCloseEvent(); if (args.Handled) return; - //raise attached event first + // raise attached event first if (TrayToolTip != null) RaiseToolTipCloseEvent(TrayToolTip); TrayToolTipResolved.IsOpen = false; - //bubble event + // bubble event RaiseTrayToolTipCloseEvent(); } } @@ -534,44 +543,46 @@ namespace Hardcodet.Wpf.TaskbarNotification /// property which prevents this issue. private void CreateCustomToolTip() { - //check if the item itself is a tooltip + // check if the item itself is a tooltip ToolTip tt = TrayToolTip as ToolTip; if (tt == null && TrayToolTip != null) { - //create an invisible wrapper tooltip that hosts the UIElement - tt = new ToolTip(); - tt.Placement = PlacementMode.Mouse; + // create an invisible wrapper tooltip that hosts the UIElement + tt = new ToolTip + { + Placement = PlacementMode.Mouse, + // do *not* set the placement target, as it causes the popup to become hidden if the + // TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through + // the ParentTaskbarIcon attached dependency property: + // PlacementTarget = this; - //do *not* set the placement target, as it causes the popup to become hidden if the - //TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through - //the ParentTaskbarIcon attached dependency property: - //tt.PlacementTarget = this; - - //make sure the tooltip is invisible - tt.HasDropShadow = false; - tt.BorderThickness = new Thickness(0); - tt.Background = System.Windows.Media.Brushes.Transparent; - - //setting the - tt.StaysOpen = true; - tt.Content = TrayToolTip; + // make sure the tooltip is invisible + HasDropShadow = false, + BorderThickness = new Thickness(0), + Background = System.Windows.Media.Brushes.Transparent, + // setting the + StaysOpen = true, + Content = TrayToolTip + }; } - else if (tt == null && !String.IsNullOrEmpty(ToolTipText)) + else if (tt == null && !string.IsNullOrEmpty(ToolTipText)) { - //create a simple tooltip for the ToolTipText string - tt = new ToolTip(); - tt.Content = ToolTipText; + // create a simple tooltip for the ToolTipText string + tt = new ToolTip + { + Content = ToolTipText + }; } - //the tooltip explicitly gets the DataContext of this instance. - //If there is no DataContext, the TaskbarIcon assigns itself + // the tooltip explicitly gets the DataContext of this instance. + // If there is no DataContext, the TaskbarIcon assigns itself if (tt != null) { UpdateDataContext(tt, null, DataContext); } - //store a reference to the used tooltip + // store a reference to the used tooltip SetTrayToolTipResolved(tt); } @@ -587,17 +598,17 @@ namespace Hardcodet.Wpf.TaskbarNotification if (messageSink.Version == NotifyIconVersion.Vista) { - //we need to set a tooltip text to get tooltip events from the - //taskbar icon - if (String.IsNullOrEmpty(iconData.ToolTipText) && TrayToolTipResolved != null) + // we need to set a tooltip text to get tooltip events from the + // taskbar icon + if (string.IsNullOrEmpty(iconData.ToolTipText) && TrayToolTipResolved != null) { - //if we have not tooltip text but a custom tooltip, we - //need to set a dummy value (we're displaying the ToolTip control, not the string) + // if we have not tooltip text but a custom tooltip, we + // need to set a dummy value (we're displaying the ToolTip control, not the string) iconData.ToolTipText = "ToolTip"; } } - //update the tooltip text + // update the tooltip text Util.WriteIconData(ref iconData, NotifyCommand.Modify, flags); } @@ -620,90 +631,89 @@ namespace Hardcodet.Wpf.TaskbarNotification /// property which prevents this issue. private void CreatePopup() { - //check if the item itself is a popup + // check if the item itself is a popup Popup popup = TrayPopup as Popup; if (popup == null && TrayPopup != null) { - //create an invisible popup that hosts the UIElement - popup = new Popup(); - popup.AllowsTransparency = true; + // create an invisible popup that hosts the UIElement + popup = new Popup + { + AllowsTransparency = true, + // don't animate by default - developers can use attached events or override + PopupAnimation = PopupAnimation.None, + // the CreateRootPopup method outputs binding errors in the debug window because + // it tries to bind to "Popup-specific" properties in case they are provided by the child. + // We don't need that so just assign the control as the child. + Child = TrayPopup, + // do *not* set the placement target, as it causes the popup to become hidden if the + // TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through + // the ParentTaskbarIcon attached dependency property: + // PlacementTarget = this; - //don't animate by default - devs can use attached - //events or override - popup.PopupAnimation = PopupAnimation.None; - - //the CreateRootPopup method outputs binding errors in the debug window because - //it tries to bind to "Popup-specific" properties in case they are provided by the child. - //We don't need that so just assign the control as the child. - popup.Child = TrayPopup; - - //do *not* set the placement target, as it causes the popup to become hidden if the - //TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through - //the ParentTaskbarIcon attached dependency property: - //popup.PlacementTarget = this; - - popup.Placement = PlacementMode.AbsolutePoint; - popup.StaysOpen = false; + Placement = PlacementMode.AbsolutePoint, + StaysOpen = false + }; } - //the popup explicitly gets the DataContext of this instance. - //If there is no DataContext, the TaskbarIcon assigns itself + // the popup explicitly gets the DataContext of this instance. + // If there is no DataContext, the TaskbarIcon assigns itself if (popup != null) { UpdateDataContext(popup, null, DataContext); } - //store a reference to the used tooltip + // store a reference to the used tooltip SetTrayPopupResolved(popup); } /// - /// Displays the control if - /// it was set. + /// Displays the control if it was set. /// private void ShowTrayPopup(Point cursorPosition) { if (IsDisposed) return; - //raise preview event no matter whether popup is currently set - //or not (enables client to set it on demand) + // raise preview event no matter whether popup is currently set + // or not (enables client to set it on demand) var args = RaisePreviewTrayPopupOpenEvent(); if (args.Handled) return; - if (TrayPopup != null) + if (TrayPopup == null) { - //use absolute position, but place the popup centered above the icon - TrayPopupResolved.Placement = PlacementMode.AbsolutePoint; - TrayPopupResolved.HorizontalOffset = cursorPosition.X; - TrayPopupResolved.VerticalOffset = cursorPosition.Y; - - //open popup - TrayPopupResolved.IsOpen = true; - - IntPtr handle = IntPtr.Zero; - if (TrayPopupResolved.Child != null) - { - //try to get a handle on the popup itself (via its child) - HwndSource source = (HwndSource) PresentationSource.FromVisual(TrayPopupResolved.Child); - if (source != null) handle = source.Handle; - } - - //if we don't have a handle for the popup, fall back to the message sink - if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle; - - //activate either popup or message sink to track deactivation. - //otherwise, the popup does not close if the user clicks somewhere else - WinApi.SetForegroundWindow(handle); - - //raise attached event - item should never be null unless developers - //changed the CustomPopup directly... - if (TrayPopup != null) RaisePopupOpenedEvent(TrayPopup); - - //bubble routed event - RaiseTrayPopupOpenEvent(); + return; } + + // use absolute position, but place the popup centered above the icon + TrayPopupResolved.Placement = PlacementMode.AbsolutePoint; + TrayPopupResolved.HorizontalOffset = cursorPosition.X; + TrayPopupResolved.VerticalOffset = cursorPosition.Y; + + // open popup + TrayPopupResolved.IsOpen = true; + + IntPtr handle = IntPtr.Zero; + if (TrayPopupResolved.Child != null) + { + // try to get a handle on the popup itself (via its child) + HwndSource source = (HwndSource)PresentationSource.FromVisual(TrayPopupResolved.Child); + if (source != null) handle = source.Handle; + } + + // if we don't have a handle for the popup, fall back to the message sink + if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle; + + // activate either popup or message sink to track deactivation. + // otherwise, the popup does not close if the user clicks somewhere else + WinApi.SetForegroundWindow(handle); + + // raise attached event - item should never be null unless developers + // changed the CustomPopup directly... + if (TrayPopup != null) RaisePopupOpenedEvent(TrayPopup); + + // bubble routed event + RaiseTrayPopupOpenEvent(); } #endregion @@ -711,48 +721,49 @@ namespace Hardcodet.Wpf.TaskbarNotification #region Context Menu /// - /// Displays the if - /// it was set. + /// Displays the if it was set. /// private void ShowContextMenu(Point cursorPosition) { if (IsDisposed) return; - //raise preview event no matter whether context menu is currently set - //or not (enables client to set it on demand) + // raise preview event no matter whether context menu is currently set + // or not (enables client to set it on demand) var args = RaisePreviewTrayContextMenuOpenEvent(); if (args.Handled) return; - if (ContextMenu != null) + if (ContextMenu == null) { - //use absolute positioning. We need to set the coordinates, or a delayed opening - //(e.g. when left-clicked) opens the context menu at the wrong place if the mouse - //is moved! - ContextMenu.Placement = PlacementMode.AbsolutePoint; - ContextMenu.HorizontalOffset = cursorPosition.X; - ContextMenu.VerticalOffset = cursorPosition.Y; - ContextMenu.IsOpen = true; - - IntPtr handle = IntPtr.Zero; - - //try to get a handle on the context itself - HwndSource source = (HwndSource) PresentationSource.FromVisual(ContextMenu); - if (source != null) - { - handle = source.Handle; - } - - //if we don't have a handle for the popup, fall back to the message sink - if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle; - - //activate the context menu or the message window to track deactivation - otherwise, the context menu - //does not close if the user clicks somewhere else. With the message window - //fallback, the context menu can't receive keyboard events - should not happen though - WinApi.SetForegroundWindow(handle); - - //bubble event - RaiseTrayContextMenuOpenEvent(); + return; } + + // use absolute positioning. We need to set the coordinates, or a delayed opening + // (e.g. when left-clicked) opens the context menu at the wrong place if the mouse + // is moved! + ContextMenu.Placement = PlacementMode.AbsolutePoint; + ContextMenu.HorizontalOffset = cursorPosition.X; + ContextMenu.VerticalOffset = cursorPosition.Y; + ContextMenu.IsOpen = true; + + IntPtr handle = IntPtr.Zero; + + // try to get a handle on the context itself + HwndSource source = (HwndSource)PresentationSource.FromVisual(ContextMenu); + if (source != null) + { + handle = source.Handle; + } + + // if we don't have a handle for the popup, fall back to the message sink + if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle; + + // activate the context menu or the message window to track deactivation - otherwise, the context menu + // does not close if the user clicks somewhere else. With the message window + // fallback, the context menu can't receive keyboard events - should not happen though + WinApi.SetForegroundWindow(handle); + + // bubble event + RaiseTrayContextMenuOpenEvent(); } #endregion @@ -786,7 +797,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// A symbol that indicates the severity. public void ShowBalloonTip(string title, string message, BalloonIcon symbol) { - lock (this) + lock (lockObject) { ShowBalloonTip(title, message, symbol.GetBalloonFlag(), IntPtr.Zero); } @@ -804,14 +815,17 @@ namespace Hardcodet.Wpf.TaskbarNotification /// is a null reference. public void ShowBalloonTip(string title, string message, Icon customIcon, bool largeIcon = false) { - if (customIcon == null) throw new ArgumentNullException("customIcon"); + if (customIcon == null) throw new ArgumentNullException(nameof(customIcon)); - lock (this) + lock (lockObject) { var flags = BalloonFlags.User; if (largeIcon) + { + // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags flags |= BalloonFlags.LargeIcon; + } ShowBalloonTip(title, message, flags, customIcon.Handle); } @@ -831,8 +845,8 @@ namespace Hardcodet.Wpf.TaskbarNotification { EnsureNotDisposed(); - iconData.BalloonText = message ?? String.Empty; - iconData.BalloonTitle = title ?? String.Empty; + iconData.BalloonText = message ?? string.Empty; + iconData.BalloonTitle = title ?? string.Empty; iconData.BalloonFlags = flags; iconData.CustomBalloonIconHandle = balloonIconHandle; @@ -847,8 +861,8 @@ namespace Hardcodet.Wpf.TaskbarNotification { EnsureNotDisposed(); - //reset balloon by just setting the info to an empty string - iconData.BalloonText = iconData.BalloonTitle = String.Empty; + // reset balloon by just setting the info to an empty string + iconData.BalloonText = iconData.BalloonTitle = string.Empty; Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Info); } @@ -865,14 +879,14 @@ namespace Hardcodet.Wpf.TaskbarNotification { if (IsDisposed) return; - //run action + // run action Action action = singleClickTimerAction; if (action != null) { - //cleanup action + // cleanup action singleClickTimerAction = null; - //switch to UI thread + // switch to UI thread this.GetDispatcher().Invoke(action); } } @@ -886,18 +900,18 @@ namespace Hardcodet.Wpf.TaskbarNotification /// private void SetVersion() { - iconData.VersionOrTimeout = (uint) NotifyIconVersion.Vista; + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Vista; bool status = WinApi.Shell_NotifyIcon(NotifyCommand.SetVersion, ref iconData); if (!status) { - iconData.VersionOrTimeout = (uint) NotifyIconVersion.Win2000; + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Win2000; status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); } if (!status) { - iconData.VersionOrTimeout = (uint) NotifyIconVersion.Win95; + iconData.VersionOrTimeout = (uint)NotifyIconVersion.Win95; status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); } @@ -928,31 +942,33 @@ namespace Hardcodet.Wpf.TaskbarNotification /// private void CreateTaskbarIcon() { - lock (this) + lock (lockObject) { - if (!IsTaskbarIconCreated) + if (IsTaskbarIconCreated) { - const IconDataMembers members = IconDataMembers.Message - | IconDataMembers.Icon - | IconDataMembers.Tip; - - //write initial configuration - var status = Util.WriteIconData(ref iconData, NotifyCommand.Add, members); - if (!status) - { - //couldn't create the icon - we can assume this is because explorer is not running (yet!) - //-> try a bit later again rather than throwing an exception. Typically, if the windows - // shell is being loaded later, this method is being reinvoked from OnTaskbarCreated - // (we could also retry after a delay, but that's currently YAGNI) - return; - } - - //set to most recent version - SetVersion(); - messageSink.Version = (NotifyIconVersion) iconData.VersionOrTimeout; - - IsTaskbarIconCreated = true; + return; } + + const IconDataMembers members = IconDataMembers.Message + | IconDataMembers.Icon + | IconDataMembers.Tip; + + //write initial configuration + var status = Util.WriteIconData(ref iconData, NotifyCommand.Add, members); + if (!status) + { + // couldn't create the icon - we can assume this is because explorer is not running (yet!) + // -> try a bit later again rather than throwing an exception. Typically, if the windows + // shell is being loaded later, this method is being re-invoked from OnTaskbarCreated + // (we could also retry after a delay, but that's currently YAGNI) + return; + } + + //set to most recent version + SetVersion(); + messageSink.Version = (NotifyIconVersion)iconData.VersionOrTimeout; + + IsTaskbarIconCreated = true; } } @@ -961,15 +977,17 @@ namespace Hardcodet.Wpf.TaskbarNotification /// private void RemoveTaskbarIcon() { - lock (this) + lock (lockObject) { - //make sure we didn't schedule a creation + // make sure we didn't schedule a creation - if (IsTaskbarIconCreated) + if (!IsTaskbarIconCreated) { - Util.WriteIconData(ref iconData, NotifyCommand.Delete, IconDataMembers.Message); - IsTaskbarIconCreated = false; + return; } + + Util.WriteIconData(ref iconData, NotifyCommand.Delete, IconDataMembers.Message); + IsTaskbarIconCreated = false; } } @@ -1010,8 +1028,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// method does not get called. This gives this base class the /// opportunity to finalize. /// - /// Important: Do not provide destructors in types derived from - /// this class. + /// Important: Do not provide destructor in types derived from this class. /// /// ~TaskbarIcon() @@ -1031,7 +1048,7 @@ namespace Hardcodet.Wpf.TaskbarNotification Dispose(true); // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to + // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. @@ -1056,27 +1073,27 @@ namespace Hardcodet.Wpf.TaskbarNotification /// the method has already been called. private void Dispose(bool disposing) { - //don't do anything if the component is already disposed + // don't do anything if the component is already disposed if (IsDisposed || !disposing) return; - lock (this) + lock (lockObject) { IsDisposed = true; - //deregister application event listener + // de-register application event listener if (Application.Current != null) { Application.Current.Exit -= OnExit; } - //stop timers + // stop timers singleClickTimer.Dispose(); balloonCloseTimer.Dispose(); - //dispose message sink + // dispose message sink messageSink.Dispose(); - //remove icon + // remove icon RemoveTaskbarIcon(); } } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Util.cs b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Util.cs index b7db32a..5e753f6 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Util.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/NotifyIconWpf/Util.cs @@ -175,7 +175,7 @@ namespace Hardcodet.Wpf.TaskbarNotification if (streamInfo == null) { string msg = "The supplied image source '{0}' could not be resolved."; - msg = String.Format(msg, imageSource); + msg = string.Format(msg, imageSource); throw new ArgumentException(msg); } @@ -277,7 +277,7 @@ namespace Hardcodet.Wpf.TaskbarNotification /// /// Returns a dispatcher for multi-threaded scenarios /// - /// + /// Dispatcher internal static Dispatcher GetDispatcher(this DispatcherObject source) { //use the application's dispatcher by default @@ -286,7 +286,7 @@ namespace Hardcodet.Wpf.TaskbarNotification //fallback for WinForms environments if (source.Dispatcher != null) return source.Dispatcher; - //ultimatively use the thread's dispatcher + // ultimately use the thread's dispatcher return Dispatcher.CurrentDispatcher; } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/App.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/App.xaml.cs index 51b78ac..9b6d915 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/App.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/App.xaml.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Windows; -using Hardcodet.Wpf.TaskbarNotification; +using System.Windows; namespace Samples { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Commands/CommandBase.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Commands/CommandBase.cs index ed0ae3b..040a21b 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Commands/CommandBase.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Commands/CommandBase.cs @@ -62,7 +62,7 @@ namespace Samples.Commands /// public virtual bool CanExecute(object parameter) { - return IsDesignMode ? false : true; + return !IsDesignMode; } @@ -82,12 +82,12 @@ namespace Samples.Commands /// Resolves the window that owns the TaskbarIcon class. /// /// - /// + /// Window protected Window GetTaskbarWindow(object commandParameter) { if (IsDesignMode) return null; - //get the showcase window off the taskbaricon + // get the showcase window off the taskbar icon var tb = commandParameter as TaskbarIcon; return tb == null ? null : TryFindParent(tb); } @@ -97,14 +97,13 @@ namespace Samples.Commands /// /// Finds a parent of a given item on the visual tree. /// - /// The type of the queried item. + /// The type of the queried item. /// A direct or indirect child of the /// queried item. /// The first parent item that matches the submitted /// type parameter. If not matching item can be found, a null /// reference is being returned. - public static T TryFindParent(DependencyObject child) - where T : DependencyObject + public static TParent TryFindParent(DependencyObject child) where TParent : DependencyObject { //get parent item DependencyObject parentObject = GetParentObject(child); @@ -113,16 +112,13 @@ namespace Samples.Commands if (parentObject == null) return null; //check if the parent matches the type we're looking for - T parent = parentObject as T; - if (parent != null) + if (parentObject is TParent parent) { return parent; } - else - { - //use recursion to proceed with next level - return TryFindParent(parentObject); - } + + //use recursion to proceed with next level + return TryFindParent(parentObject); } /// @@ -137,15 +133,14 @@ namespace Samples.Commands public static DependencyObject GetParentObject(DependencyObject child) { if (child == null) return null; - ContentElement contentElement = child as ContentElement; - if (contentElement != null) + if (child is ContentElement contentElement) { DependencyObject parent = ContentOperations.GetParent(contentElement); if (parent != null) return parent; FrameworkContentElement fce = contentElement as FrameworkContentElement; - return fce != null ? fce.Parent : null; + return fce?.Parent; } //if it's not a ContentElement, rely on VisualTreeHelper diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Main.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Main.xaml.cs index c00ead9..a58ae06 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Main.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Main.xaml.cs @@ -82,17 +82,19 @@ namespace Samples ShowDialog(new DataBoundToolTipWindow()); } - private void btnMvvm_Click(object sender, System.Windows.RoutedEventArgs e) + private void btnMvvm_Click(object sender, RoutedEventArgs e) { ShowDialog(new MvvmSampleWindow()); } private void btnMainSample_Click(object sender, RoutedEventArgs e) { - var sampleWindow = new ShowcaseWindow(); + var sampleWindow = new ShowcaseWindow + { + Owner = this, + WindowStartupLocation = WindowStartupLocation.CenterScreen + }; - sampleWindow.Owner = this; - sampleWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; sampleWindow.ShowDialog(); } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Properties/AssemblyInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Properties/AssemblyInfo.cs index 7390bf8..4aa37aa 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Properties/AssemblyInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Properties/AssemblyInfo.cs @@ -1,7 +1,4 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Windows; // Setting ComVisible to false makes the types in this assembly not visible diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyBalloon.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyBalloon.xaml.cs index 8c72752..b124b89 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyBalloon.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyBalloon.xaml.cs @@ -1,18 +1,8 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using Hardcodet.Wpf.TaskbarNotification; namespace Samples @@ -30,10 +20,10 @@ namespace Samples /// Description /// public static readonly DependencyProperty BalloonTextProperty = - DependencyProperty.Register("BalloonText", + DependencyProperty.Register(nameof(BalloonText), typeof (string), typeof (FancyBalloon), - new FrameworkPropertyMetadata("")); + new FrameworkPropertyMetadata(string.Empty)); /// /// A property wrapper for the diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyPopup.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyPopup.xaml.cs index d29c5de..32e99b2 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyPopup.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyPopup.xaml.cs @@ -14,7 +14,7 @@ namespace Samples /// The number of clicks on the popup button. /// public static readonly DependencyProperty ClickCountProperty = - DependencyProperty.Register("ClickCount", + DependencyProperty.Register(nameof(ClickCount), typeof (int), typeof (FancyPopup), new FrameworkPropertyMetadata(0)); diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyToolTip.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyToolTip.xaml.cs index f8757e2..b6fa3bb 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyToolTip.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/FancyToolTip.xaml.cs @@ -1,16 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; -using Hardcodet.Wpf.TaskbarNotification; +using System.Windows; namespace Samples { @@ -25,10 +13,10 @@ namespace Samples /// The tooltip details. /// public static readonly DependencyProperty InfoTextProperty = - DependencyProperty.Register("InfoText", + DependencyProperty.Register(nameof(InfoText), typeof (string), typeof (FancyToolTip), - new FrameworkPropertyMetadata("")); + new FrameworkPropertyMetadata(string.Empty)); /// /// A property wrapper for the @@ -45,7 +33,7 @@ namespace Samples public FancyToolTip() { - this.InitializeComponent(); + InitializeComponent(); } } } \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/WelcomeBalloon.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/WelcomeBalloon.xaml.cs index 90682de..23d7034 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/WelcomeBalloon.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Showcase/WelcomeBalloon.xaml.cs @@ -1,16 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows.Controls; namespace Samples { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/InlineToolTipWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/InlineToolTipWindow.xaml.cs index a953b19..886de01 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/InlineToolTipWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/InlineToolTipWindow.xaml.cs @@ -1,15 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using System.Windows; namespace Samples.Tutorials.ToolTips { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/SimpleUserControl.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/SimpleUserControl.xaml.cs index 56af7f1..0cc3bbf 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/SimpleUserControl.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/SimpleUserControl.xaml.cs @@ -1,16 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows.Controls; namespace Samples.Tutorials.ToolTips { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/UserControlToolTipWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/UserControlToolTipWindow.xaml.cs index b6da22a..7f4cc6e 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/UserControlToolTipWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/02 - ToolTips/UserControlToolTipWindow.xaml.cs @@ -1,15 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using System.Windows; namespace Samples.Tutorials.ToolTips { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/03 - Popups/InlinePopupWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/03 - Popups/InlinePopupWindow.xaml.cs index b08a4f2..712dabc 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/03 - Popups/InlinePopupWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/03 - Popups/InlinePopupWindow.xaml.cs @@ -1,15 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using System.Windows; namespace Samples.Tutorials.Popups { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/04 - ContextMenus/InlineContextMenuWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/04 - ContextMenus/InlineContextMenuWindow.xaml.cs index 5fa550d..166b31e 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/04 - ContextMenus/InlineContextMenuWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/04 - ContextMenus/InlineContextMenuWindow.xaml.cs @@ -1,7 +1,4 @@ -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; +using System.Windows; namespace Samples.Tutorials.ContextMenus { @@ -24,12 +21,12 @@ namespace Samples.Tutorials.ContextMenus base.OnClosing(e); } - private void MyNotifyIcon_TrayContextMenuOpen(object sender, System.Windows.RoutedEventArgs e) + private void MyNotifyIcon_TrayContextMenuOpen(object sender, RoutedEventArgs e) { OpenEventCounter.Text = (int.Parse(OpenEventCounter.Text) + 1).ToString(); } - private void MyNotifyIcon_PreviewTrayContextMenuOpen(object sender, System.Windows.RoutedEventArgs e) + private void MyNotifyIcon_PreviewTrayContextMenuOpen(object sender, RoutedEventArgs e) { //marking the event as handled suppresses the context menu e.Handled = (bool) SuppressContextMenu.IsChecked; diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/05 - Balloons/BalloonSampleWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/05 - Balloons/BalloonSampleWindow.xaml.cs index 5e663cb..63c855e 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/05 - Balloons/BalloonSampleWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/05 - Balloons/BalloonSampleWindow.xaml.cs @@ -1,17 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; +using System.Windows; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; -using Hardcodet.Wpf.TaskbarNotification; namespace Samples.Tutorials.Balloons { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/06 - Commands/CommandWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/06 - Commands/CommandWindow.xaml.cs index b83705d..a7515a4 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/06 - Commands/CommandWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/06 - Commands/CommandWindow.xaml.cs @@ -1,15 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using System.Windows; namespace Samples.Tutorials.Commands { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/09 - MVVM/ClockPopup.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/09 - MVVM/ClockPopup.xaml.cs index 063d0b6..4918c2b 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/09 - MVVM/ClockPopup.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Sample Project/Tutorials/09 - MVVM/ClockPopup.xaml.cs @@ -9,7 +9,7 @@ namespace Samples.Tutorials.MvvmSample { public ClockPopup() { - this.InitializeComponent(); + InitializeComponent(); } } } \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/DelegateCommand.cs b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/DelegateCommand.cs new file mode 100644 index 0000000..16cd4d5 --- /dev/null +++ b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/DelegateCommand.cs @@ -0,0 +1,30 @@ +using System; +using System.Windows.Input; + +namespace Windowless_Sample +{ + /// + /// Simplistic delegate command for the demo. + /// + public class DelegateCommand : ICommand + { + public Action CommandAction { get; set; } + public Func CanExecuteFunc { get; set; } + + public void Execute(object parameter) + { + CommandAction(); + } + + public bool CanExecute(object parameter) + { + return CanExecuteFunc == null || CanExecuteFunc(); + } + + public event EventHandler CanExecuteChanged + { + add { CommandManager.RequerySuggested += value; } + remove { CommandManager.RequerySuggested -= value; } + } + } +} \ No newline at end of file diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/MainWindow.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/MainWindow.xaml.cs index f934e1d..09c7058 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/MainWindow.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/MainWindow.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows; namespace Windowless_Sample { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/NotifyIconViewModel.cs b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/NotifyIconViewModel.cs index 9a9790f..22968b2 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/NotifyIconViewModel.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/NotifyIconViewModel.cs @@ -1,5 +1,4 @@ -using System; -using System.Windows; +using System.Windows; using System.Windows.Input; namespace Windowless_Sample @@ -57,30 +56,4 @@ namespace Windowless_Sample } } } - - - /// - /// Simplistic delegate command for the demo. - /// - public class DelegateCommand : ICommand - { - public Action CommandAction { get; set; } - public Func CanExecuteFunc { get; set; } - - public void Execute(object parameter) - { - CommandAction(); - } - - public bool CanExecute(object parameter) - { - return CanExecuteFunc == null || CanExecuteFunc(); - } - - public event EventHandler CanExecuteChanged - { - add { CommandManager.RequerySuggested += value; } - remove { CommandManager.RequerySuggested -= value; } - } - } } diff --git a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/Properties/AssemblyInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/Properties/AssemblyInfo.cs index c509387..a6f008c 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/Properties/AssemblyInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/Windowless Sample/Properties/AssemblyInfo.cs @@ -1,7 +1,4 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using System.Windows; // Setting ComVisible to false makes the types in this assembly not visible diff --git a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/FancyPopup.xaml.cs b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/FancyPopup.xaml.cs index 2a8fcaa..55fbb4b 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/FancyPopup.xaml.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/FancyPopup.xaml.cs @@ -13,7 +13,7 @@ namespace Samples /// The number of clicks on the popup button. /// public static readonly DependencyProperty ClickCountProperty = - DependencyProperty.Register("ClickCount", + DependencyProperty.Register(nameof(ClickCount), typeof (int), typeof (FancyPopup), new FrameworkPropertyMetadata(0)); diff --git a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Program.cs b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Program.cs index 026aaa3..83a4358 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Program.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Program.cs @@ -1,6 +1,5 @@ using System; using System.Windows.Forms; -using Samples; namespace WindowsFormsSample { diff --git a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Properties/AssemblyInfo.cs b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Properties/AssemblyInfo.cs index 1b323e9..f763bc7 100644 --- a/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Properties/AssemblyInfo.cs +++ b/Hardcodet.NotifyIcon.Wpf/Source/WindowsFormsSample/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from