CHG Reformatting code (NTFY-20).

git-svn-id: https://svn.evolvesoftware.ch/repos/evolve.net/WPF/NotifyIcon@192 9f600761-6f11-4665-b6dc-0185e9171623
This commit is contained in:
Philipp Sumi
2013-11-18 00:03:09 +00:00
parent 1be7b176a9
commit 7014294506
64 changed files with 3832 additions and 3636 deletions

View File

@@ -24,26 +24,29 @@
namespace Hardcodet.Wpf.TaskbarNotification namespace Hardcodet.Wpf.TaskbarNotification
{ {
///<summary> ///<summary>
/// Supported icons for the tray's balloon messages. /// Supported icons for the tray's balloon messages.
///</summary> ///</summary>
public enum BalloonIcon public enum BalloonIcon
{ {
/// <summary> /// <summary>
/// The balloon message is displayed without an icon. /// The balloon message is displayed without an icon.
/// </summary> /// </summary>
None, None,
/// <summary>
/// An information is displayed. /// <summary>
/// </summary> /// An information is displayed.
Info, /// </summary>
/// <summary> Info,
/// A warning is displayed.
/// </summary> /// <summary>
Warning, /// A warning is displayed.
/// <summary> /// </summary>
/// An error is displayed. Warning,
/// </summary>
Error /// <summary>
} /// An error is displayed.
/// </summary>
Error
}
} }

View File

@@ -1,55 +1,61 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Flags that define the icon that is shown on a balloon
/// tooltip.
/// </summary>
public enum BalloonFlags
{
/// <summary> /// <summary>
/// No icon is displayed. /// Flags that define the icon that is shown on a balloon
/// tooltip.
/// </summary> /// </summary>
None = 0x00, public enum BalloonFlags
/// <summary> {
/// An information icon is displayed. /// <summary>
/// </summary> /// No icon is displayed.
Info = 0x01, /// </summary>
/// <summary> None = 0x00,
/// A warning icon is displayed.
/// </summary> /// <summary>
Warning = 0x02, /// An information icon is displayed.
/// <summary> /// </summary>
/// An error icon is displayed. Info = 0x01,
/// </summary>
Error = 0x03, /// <summary>
/// <summary> /// A warning icon is displayed.
/// Windows XP Service Pack 2 (SP2) and later. /// </summary>
/// Use a custom icon as the title icon. Warning = 0x02,
/// </summary>
User = 0x04, /// <summary>
/// <summary> /// An error icon is displayed.
/// Windows XP (Shell32.dll version 6.0) and later. /// </summary>
/// Do not play the associated sound. Applies only to balloon ToolTips. Error = 0x03,
/// </summary>
NoSound = 0x10, /// <summary>
/// <summary> /// Windows XP Service Pack 2 (SP2) and later.
/// Windows Vista (Shell32.dll version 6.0.6) and later. The large version /// Use a custom icon as the title icon.
/// of the icon should be used as the balloon icon. This corresponds to the /// </summary>
/// icon with dimensions SM_CXICON x SM_CYICON. If this flag is not set, User = 0x04,
/// the icon with dimensions XM_CXSMICON x SM_CYSMICON is used.<br/>
/// - This flag can be used with all stock icons.<br/> /// <summary>
/// - Applications that use older customized icons (NIIF_USER with hIcon) must /// Windows XP (Shell32.dll version 6.0) and later.
/// provide a new SM_CXICON x SM_CYICON version in the tray icon (hIcon). These /// Do not play the associated sound. Applies only to balloon ToolTips.
/// icons are scaled down when they are displayed in the System Tray or /// </summary>
/// System Control Area (SCA).<br/> NoSound = 0x10,
/// - New customized icons (NIIF_USER with hBalloonIcon) must supply an
/// SM_CXICON x SM_CYICON version in the supplied icon (hBalloonIcon). /// <summary>
/// </summary> /// Windows Vista (Shell32.dll version 6.0.6) and later. The large version
LargeIcon = 0x20, /// of the icon should be used as the balloon icon. This corresponds to the
/// <summary> /// icon with dimensions SM_CXICON x SM_CYICON. If this flag is not set,
/// Windows 7 and later. /// the icon with dimensions XM_CXSMICON x SM_CYSMICON is used.<br/>
/// </summary> /// - This flag can be used with all stock icons.<br/>
RespectQuietTime = 0x80 /// - Applications that use older customized icons (NIIF_USER with hIcon) must
/// provide a new SM_CXICON x SM_CYICON version in the tray icon (hIcon). These
} /// icons are scaled down when they are displayed in the System Tray or
/// System Control Area (SCA).<br/>
/// - New customized icons (NIIF_USER with hBalloonIcon) must supply an
/// SM_CXICON x SM_CYICON version in the supplied icon (hBalloonIcon).
/// </summary>
LargeIcon = 0x20,
/// <summary>
/// Windows 7 and later.
/// </summary>
RespectQuietTime = 0x80
}
} }

View File

@@ -2,66 +2,70 @@ using System;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Indicates which members of a <see cref="NotifyIconData"/> structure
/// were set, and thus contain valid data or provide additional information
/// to the ToolTip as to how it should display.
/// </summary>
[Flags]
public enum IconDataMembers
{
/// <summary> /// <summary>
/// The message ID is set. /// Indicates which members of a <see cref="NotifyIconData"/> structure
/// were set, and thus contain valid data or provide additional information
/// to the ToolTip as to how it should display.
/// </summary> /// </summary>
Message = 0x01, [Flags]
/// <summary> public enum IconDataMembers
/// The notification icon is set. {
/// </summary> /// <summary>
Icon = 0x02, /// The message ID is set.
/// <summary> /// </summary>
/// The tooltip is set. Message = 0x01,
/// </summary>
Tip = 0x04,
/// <summary>
/// State information (<see cref="IconState"/>) is set. This
/// applies to both <see cref="NotifyIconData.IconState"/> and
/// <see cref="NotifyIconData.StateMask"/>.
/// </summary>
State = 0x08,
/// <summary>
/// The balloon ToolTip is set. Accordingly, the following
/// members are set: <see cref="NotifyIconData.BalloonText"/>,
/// <see cref="NotifyIconData.BalloonTitle"/>, <see cref="NotifyIconData.BalloonFlags"/>,
/// and <see cref="NotifyIconData.VersionOrTimeout"/>.
/// </summary>
Info = 0x10,
/// <summary>
/// Internal identifier is set. Reserved, thus commented out.
/// </summary>
//Guid = 0x20,
/// <summary> /// <summary>
/// Windows Vista (Shell32.dll version 6.0.6) and later. If the ToolTip /// The notification icon is set.
/// cannot be displayed immediately, discard it.<br/> /// </summary>
/// Use this flag for ToolTips that represent real-time information which Icon = 0x02,
/// would be meaningless or misleading if displayed at a later time.
/// For example, a message that states "Your telephone is ringing."<br/> /// <summary>
/// This modifies and must be combined with the <see cref="Info"/> flag. /// The tooltip is set.
/// </summary> /// </summary>
Realtime = 0x40, Tip = 0x04,
/// <summary>
/// Windows Vista (Shell32.dll version 6.0.6) and later. /// <summary>
/// Use the standard ToolTip. Normally, when uVersion is set /// State information (<see cref="IconState"/>) is set. This
/// to NOTIFYICON_VERSION_4, the standard ToolTip is replaced /// applies to both <see cref="NotifyIconData.IconState"/> and
/// by the application-drawn pop-up user interface (UI). /// <see cref="NotifyIconData.StateMask"/>.
/// If the application wants to show the standard tooltip /// </summary>
/// in that case, regardless of whether the on-hover UI is showing, State = 0x08,
/// it can specify NIF_SHOWTIP to indicate the standard tooltip
/// should still be shown.<br/> /// <summary>
/// Note that the NIF_SHOWTIP flag is effective until the next call /// The balloon ToolTip is set. Accordingly, the following
/// to Shell_NotifyIcon. /// members are set: <see cref="NotifyIconData.BalloonText"/>,
/// </summary> /// <see cref="NotifyIconData.BalloonTitle"/>, <see cref="NotifyIconData.BalloonFlags"/>,
UseLegacyToolTips = 0x80 /// and <see cref="NotifyIconData.VersionOrTimeout"/>.
} /// </summary>
Info = 0x10,
/// <summary>
/// Internal identifier is set. Reserved, thus commented out.
/// </summary>
//Guid = 0x20,
/// <summary>
/// Windows Vista (Shell32.dll version 6.0.6) and later. If the ToolTip
/// cannot be displayed immediately, discard it.<br/>
/// Use this flag for ToolTips that represent real-time information which
/// would be meaningless or misleading if displayed at a later time.
/// For example, a message that states "Your telephone is ringing."<br/>
/// This modifies and must be combined with the <see cref="Info"/> flag.
/// </summary>
Realtime = 0x40,
/// <summary>
/// Windows Vista (Shell32.dll version 6.0.6) and later.
/// Use the standard ToolTip. Normally, when uVersion is set
/// to NOTIFYICON_VERSION_4, the standard ToolTip is replaced
/// by the application-drawn pop-up user interface (UI).
/// If the application wants to show the standard tooltip
/// in that case, regardless of whether the on-hover UI is showing,
/// it can specify NIF_SHOWTIP to indicate the standard tooltip
/// should still be shown.<br/>
/// Note that the NIF_SHOWTIP flag is effective until the next call
/// to Shell_NotifyIcon.
/// </summary>
UseLegacyToolTips = 0x80
}
} }

View File

@@ -1,23 +1,24 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// The state of the icon - can be set to
/// hide the icon.
/// </summary>
public enum IconState
{
/// <summary> /// <summary>
/// The icon is visible. /// The state of the icon - can be set to
/// hide the icon.
/// </summary> /// </summary>
Visible = 0x00, public enum IconState
/// <summary> {
/// Hide the icon. /// <summary>
/// </summary> /// The icon is visible.
Hidden = 0x01, /// </summary>
Visible = 0x00,
/// <summary> /// <summary>
/// The icon is shared - currently not supported, thus commented out. /// Hide the icon.
/// </summary> /// </summary>
//Shared = 0x02 Hidden = 0x01,
}
/// <summary>
/// The icon is shared - currently not supported, thus commented out.
/// </summary>
//Shared = 0x02
}
} }

View File

@@ -1,48 +1,54 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop
namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Event flags for clicked events.
/// </summary>
public enum MouseEvent
{
/// <summary> /// <summary>
/// The mouse was moved withing the /// Event flags for clicked events.
/// taskbar icon's area.
/// </summary> /// </summary>
MouseMove, public enum MouseEvent
/// <summary> {
/// The right mouse button was clicked. /// <summary>
/// </summary> /// The mouse was moved withing the
IconRightMouseDown, /// taskbar icon's area.
/// <summary> /// </summary>
/// The left mouse button was clicked. MouseMove,
/// </summary>
IconLeftMouseDown, /// <summary>
/// <summary> /// The right mouse button was clicked.
/// The right mouse button was released. /// </summary>
/// </summary> IconRightMouseDown,
IconRightMouseUp,
/// <summary> /// <summary>
/// The left mouse button was released. /// The left mouse button was clicked.
/// </summary> /// </summary>
IconLeftMouseUp, IconLeftMouseDown,
/// <summary>
/// The middle mouse button was clicked. /// <summary>
/// </summary> /// The right mouse button was released.
IconMiddleMouseDown, /// </summary>
/// <summary> IconRightMouseUp,
/// The middle mouse button was released.
/// </summary> /// <summary>
IconMiddleMouseUp, /// The left mouse button was released.
/// <summary> /// </summary>
/// The taskbar icon was double clicked. IconLeftMouseUp,
/// </summary>
IconDoubleClick, /// <summary>
/// <summary> /// The middle mouse button was clicked.
/// The balloon tip was clicked. /// </summary>
/// </summary> IconMiddleMouseDown,
BalloonToolTipClicked
} /// <summary>
} /// The middle mouse button was released.
/// </summary>
IconMiddleMouseUp,
/// <summary>
/// The taskbar icon was double clicked.
/// </summary>
IconDoubleClick,
/// <summary>
/// The balloon tip was clicked.
/// </summary>
BalloonToolTipClicked
}
}

View File

@@ -1,39 +1,41 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Main operations performed on the
/// <see cref="WinApi.Shell_NotifyIcon"/> function.
/// </summary>
public enum NotifyCommand
{
/// <summary> /// <summary>
/// The taskbar icon is being created. /// Main operations performed on the
/// <see cref="WinApi.Shell_NotifyIcon"/> function.
/// </summary> /// </summary>
Add = 0x00, public enum NotifyCommand
/// <summary> {
/// The settings of the taskbar icon are being updated. /// <summary>
/// </summary> /// The taskbar icon is being created.
Modify = 0x01, /// </summary>
/// <summary> Add = 0x00,
/// The taskbar icon is deleted.
/// </summary> /// <summary>
Delete = 0x02, /// The settings of the taskbar icon are being updated.
/// <summary> /// </summary>
/// Focus is returned to the taskbar icon. Currently not in use. Modify = 0x01,
/// </summary>
SetFocus = 0x03, /// <summary>
/// <summary> /// The taskbar icon is deleted.
/// Shell32.dll version 5.0 and later only. Instructs the taskbar /// </summary>
/// to behave according to the version number specified in the Delete = 0x02,
/// uVersion member of the structure pointed to by lpdata.
/// This message allows you to specify whether you want the version /// <summary>
/// 5.0 behavior found on Microsoft Windows 2000 systems, or the /// Focus is returned to the taskbar icon. Currently not in use.
/// behavior found on earlier Shell versions. The default value for /// </summary>
/// uVersion is zero, indicating that the original Windows 95 notify SetFocus = 0x03,
/// icon behavior should be used.
/// </summary> /// <summary>
SetVersion = 0x04 /// Shell32.dll version 5.0 and later only. Instructs the taskbar
} /// to behave according to the version number specified in the
/// uVersion member of the structure pointed to by lpdata.
/// This message allows you to specify whether you want the version
/// 5.0 behavior found on Microsoft Windows 2000 systems, or the
/// behavior found on earlier Shell versions. The default value for
/// uVersion is zero, indicating that the original Windows 95 notify
/// icon behavior should be used.
/// </summary>
SetVersion = 0x04
}
} }

View File

@@ -3,163 +3,163 @@ using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// A struct that is submitted in order to configure
/// the taskbar icon. Provides various members that
/// can be configured partially, according to the
/// values of the <see cref="IconDataMembers"/>
/// that were defined.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct NotifyIconData
{
/// <summary> /// <summary>
/// Size of this structure, in bytes. /// A struct that is submitted in order to configure
/// the taskbar icon. Provides various members that
/// can be configured partially, according to the
/// values of the <see cref="IconDataMembers"/>
/// that were defined.
/// </summary> /// </summary>
public uint cbSize; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct NotifyIconData
/// <summary>
/// Handle to the window that receives notification messages associated with an icon in the
/// taskbar status area. The Shell uses hWnd and uID to identify which icon to operate on
/// when Shell_NotifyIcon is invoked.
/// </summary>
public IntPtr WindowHandle;
/// <summary>
/// Application-defined identifier of the taskbar icon. The Shell uses hWnd and uID to identify
/// which icon to operate on when Shell_NotifyIcon is invoked. You can have multiple icons
/// associated with a single hWnd by assigning each a different uID. This feature, however
/// is currently not used.
/// </summary>
public uint TaskbarIconId;
/// <summary>
/// Flags that indicate which of the other members contain valid data. This member can be
/// a combination of the NIF_XXX constants.
/// </summary>
public IconDataMembers ValidMembers;
/// <summary>
/// Application-defined message identifier. The system uses this identifier to send
/// notifications to the window identified in hWnd.
/// </summary>
public uint CallbackMessageId;
/// <summary>
/// A handle to the icon that should be displayed. Just
/// <c>Icon.Handle</c>.
/// </summary>
public IntPtr IconHandle;
/// <summary>
/// String with the text for a standard ToolTip. It can have a maximum of 64 characters including
/// the terminating NULL. For Version 5.0 and later, szTip can have a maximum of
/// 128 characters, including the terminating NULL.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string ToolTipText;
/// <summary>
/// State of the icon. Remember to also set the <see cref="StateMask"/>.
/// </summary>
public IconState IconState;
/// <summary>
/// A value that specifies which bits of the state member are retrieved or modified.
/// For example, setting this member to <see cref="Interop.IconState.Hidden"/>
/// causes only the item's hidden
/// state to be retrieved.
/// </summary>
public IconState StateMask;
/// <summary>
/// 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.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string BalloonText;
/// <summary>
/// Mainly used to set the version when <see cref="WinApi.Shell_NotifyIcon"/> is invoked
/// with <see cref="NotifyCommand.SetVersion"/>. However, for legacy operations,
/// the same member is also used to set timouts for balloon ToolTips.
/// </summary>
public uint VersionOrTimeout;
/// <summary>
/// String containing a title for a balloon ToolTip. This title appears in boldface
/// above the text. It can have a maximum of 63 characters.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string BalloonTitle;
/// <summary>
/// Adds an icon to a balloon ToolTip, which is placed to the left of the title. If the
/// <see cref="BalloonTitle"/> member is zero-length, the icon is not shown.
/// </summary>
public BalloonFlags BalloonFlags;
/// <summary>
/// Windows XP (Shell32.dll version 6.0) and later.<br/>
/// - Windows 7 and later: A registered GUID that identifies the icon.
/// This value overrides uID and is the recommended method of identifying the icon.<br/>
/// - Windows XP through Windows Vista: Reserved.
/// </summary>
public Guid TaskbarIconGuid;
/// <summary>
/// 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 <see cref="Interop.BalloonFlags.User"/>
/// flag is set, this icon is used as the balloon icon.<br/>
/// If this member is NULL, the legacy behavior is carried out.
/// </summary>
public IntPtr CustomBalloonIconHandle;
/// <summary>
/// Creates a default data structure that provides
/// a hidden taskbar icon without the icon being set.
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public static NotifyIconData CreateDefault(IntPtr handle)
{ {
var data = new NotifyIconData(); /// <summary>
/// Size of this structure, in bytes.
/// </summary>
public uint cbSize;
if (Environment.OSVersion.Version.Major >= 6) /// <summary>
{ /// Handle to the window that receives notification messages associated with an icon in the
//use the current size /// taskbar status area. The Shell uses hWnd and uID to identify which icon to operate on
data.cbSize = (uint)Marshal.SizeOf(data); /// when Shell_NotifyIcon is invoked.
} /// </summary>
else public IntPtr WindowHandle;
{
//we need to set another size on xp/2003- otherwise certain
//features (e.g. balloon tooltips) don't work.
data.cbSize = 952; // NOTIFYICONDATAW_V3_SIZE
//set to fixed timeout /// <summary>
data.VersionOrTimeout = 10; /// Application-defined identifier of the taskbar icon. The Shell uses hWnd and uID to identify
} /// which icon to operate on when Shell_NotifyIcon is invoked. You can have multiple icons
/// associated with a single hWnd by assigning each a different uID. This feature, however
/// is currently not used.
/// </summary>
public uint TaskbarIconId;
data.WindowHandle = handle; /// <summary>
data.TaskbarIconId = 0x0; /// Flags that indicate which of the other members contain valid data. This member can be
data.CallbackMessageId = WindowMessageSink.CallbackMessageId; /// a combination of the NIF_XXX constants.
data.VersionOrTimeout = (uint) NotifyIconVersion.Win95; /// </summary>
public IconDataMembers ValidMembers;
data.IconHandle = IntPtr.Zero; /// <summary>
/// Application-defined message identifier. The system uses this identifier to send
/// notifications to the window identified in hWnd.
/// </summary>
public uint CallbackMessageId;
//hide initially /// <summary>
data.IconState = IconState.Hidden; /// A handle to the icon that should be displayed. Just
data.StateMask = IconState.Hidden; /// <c>Icon.Handle</c>.
/// </summary>
public IntPtr IconHandle;
//set flags /// <summary>
data.ValidMembers = IconDataMembers.Message /// String with the text for a standard ToolTip. It can have a maximum of 64 characters including
| IconDataMembers.Icon /// the terminating NULL. For Version 5.0 and later, szTip can have a maximum of
| IconDataMembers.Tip; /// 128 characters, including the terminating NULL.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string ToolTipText;
//reset strings
data.ToolTipText = data.BalloonText = data.BalloonTitle = String.Empty;
return data; /// <summary>
/// State of the icon. Remember to also set the <see cref="StateMask"/>.
/// </summary>
public IconState IconState;
/// <summary>
/// A value that specifies which bits of the state member are retrieved or modified.
/// For example, setting this member to <see cref="Interop.IconState.Hidden"/>
/// causes only the item's hidden
/// state to be retrieved.
/// </summary>
public IconState StateMask;
/// <summary>
/// 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.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string BalloonText;
/// <summary>
/// Mainly used to set the version when <see cref="WinApi.Shell_NotifyIcon"/> is invoked
/// with <see cref="NotifyCommand.SetVersion"/>. However, for legacy operations,
/// the same member is also used to set timouts for balloon ToolTips.
/// </summary>
public uint VersionOrTimeout;
/// <summary>
/// String containing a title for a balloon ToolTip. This title appears in boldface
/// above the text. It can have a maximum of 63 characters.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string BalloonTitle;
/// <summary>
/// Adds an icon to a balloon ToolTip, which is placed to the left of the title. If the
/// <see cref="BalloonTitle"/> member is zero-length, the icon is not shown.
/// </summary>
public BalloonFlags BalloonFlags;
/// <summary>
/// Windows XP (Shell32.dll version 6.0) and later.<br/>
/// - Windows 7 and later: A registered GUID that identifies the icon.
/// This value overrides uID and is the recommended method of identifying the icon.<br/>
/// - Windows XP through Windows Vista: Reserved.
/// </summary>
public Guid TaskbarIconGuid;
/// <summary>
/// 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 <see cref="Interop.BalloonFlags.User"/>
/// flag is set, this icon is used as the balloon icon.<br/>
/// If this member is NULL, the legacy behavior is carried out.
/// </summary>
public IntPtr CustomBalloonIconHandle;
/// <summary>
/// Creates a default data structure that provides
/// a hidden taskbar icon without the icon being set.
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public static NotifyIconData CreateDefault(IntPtr handle)
{
var data = new NotifyIconData();
if (Environment.OSVersion.Version.Major >= 6)
{
//use the current size
data.cbSize = (uint) Marshal.SizeOf(data);
}
else
{
//we need to set another size on xp/2003- otherwise certain
//features (e.g. balloon tooltips) don't work.
data.cbSize = 952; // NOTIFYICONDATAW_V3_SIZE
//set to fixed timeout
data.VersionOrTimeout = 10;
}
data.WindowHandle = handle;
data.TaskbarIconId = 0x0;
data.CallbackMessageId = WindowMessageSink.CallbackMessageId;
data.VersionOrTimeout = (uint) NotifyIconVersion.Win95;
data.IconHandle = IntPtr.Zero;
//hide initially
data.IconState = IconState.Hidden;
data.StateMask = IconState.Hidden;
//set flags
data.ValidMembers = IconDataMembers.Message
| IconDataMembers.Icon
| IconDataMembers.Tip;
//reset strings
data.ToolTipText = data.BalloonText = data.BalloonTitle = String.Empty;
return data;
}
} }
}
} }

View File

@@ -1,25 +1,27 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// The notify icon version that is used. The higher
/// the version, the more capabilities are available.
/// </summary>
public enum NotifyIconVersion
{
/// <summary> /// <summary>
/// Default behavior (legacy Win95). Expects /// The notify icon version that is used. The higher
/// a <see cref="NotifyIconData"/> size of 488. /// the version, the more capabilities are available.
/// </summary> /// </summary>
Win95 = 0x0, public enum NotifyIconVersion
/// <summary> {
/// Behavior representing Win2000 an higher. Expects /// <summary>
/// a <see cref="NotifyIconData"/> size of 504. /// Default behavior (legacy Win95). Expects
/// </summary> /// a <see cref="NotifyIconData"/> size of 488.
Win2000 = 0x3, /// </summary>
/// <summary> Win95 = 0x0,
/// Extended tooltip support, which is available
/// for Vista and later. /// <summary>
/// </summary> /// Behavior representing Win2000 an higher. Expects
Vista = 0x4 /// a <see cref="NotifyIconData"/> size of 504.
} /// </summary>
Win2000 = 0x3,
/// <summary>
/// Extended tooltip support, which is available
/// for Vista and later.
/// </summary>
Vista = 0x4
}
} }

View File

@@ -2,13 +2,13 @@
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary> /// <summary>
/// Win API struct providing coordinates for a single point. /// Win API struct providing coordinates for a single point.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct Point public struct Point
{ {
public int X; public int X;
public int Y; public int Y;
} }
} }

View File

@@ -7,165 +7,158 @@ using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Resolves the current tray position.
/// </summary>
public static class TrayInfo
{
/// <summary> /// <summary>
/// Gets the position of the system tray. /// Resolves the current tray position.
/// </summary> /// </summary>
/// <returns>Tray coordinates.</returns> public static class TrayInfo
public static Point GetTrayLocation()
{ {
var info = new AppBarInfo(); /// <summary>
info.GetSystemTaskBarPosition(); /// Gets the position of the system tray.
/// </summary>
Rectangle rcWorkArea = info.WorkArea; /// <returns>Tray coordinates.</returns>
public static Point GetTrayLocation()
int x = 0, y = 0;
if (info.Edge == AppBarInfo.ScreenEdge.Left)
{
x = rcWorkArea.Left + 2;
y = rcWorkArea.Bottom;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
{
x = rcWorkArea.Right;
y = rcWorkArea.Bottom;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Top)
{
x = rcWorkArea.Right;
y = rcWorkArea.Top;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Right)
{
x = rcWorkArea.Right;
y = rcWorkArea.Bottom;
}
return new Point { X = x, Y = y};
}
}
internal 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
{
Int32 bResult = 0;
var rc = new RECT();
IntPtr rawRect = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
bResult = SystemParametersInfo(SPI_GETWORKAREA, 0, rawRect, 0);
rc = (RECT) Marshal.PtrToStructure(rawRect, rc.GetType());
if (bResult == 1)
{ {
Marshal.FreeHGlobal(rawRect); var info = new AppBarInfo();
return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); info.GetSystemTaskBarPosition();
Rectangle rcWorkArea = info.WorkArea;
int x = 0, y = 0;
if (info.Edge == AppBarInfo.ScreenEdge.Left)
{
x = rcWorkArea.Left + 2;
y = rcWorkArea.Bottom;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
{
x = rcWorkArea.Right;
y = rcWorkArea.Bottom;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Top)
{
x = rcWorkArea.Right;
y = rcWorkArea.Top;
}
else if (info.Edge == AppBarInfo.ScreenEdge.Right)
{
x = rcWorkArea.Right;
y = rcWorkArea.Bottom;
}
return new Point {X = x, Y = y};
}
}
internal 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; }
} }
return new Rectangle(0, 0, 0, 0);
}
}
public Rectangle WorkArea
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"); get
{
Int32 bResult = 0;
var rc = new RECT();
IntPtr rawRect = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
bResult = SystemParametersInfo(SPI_GETWORKAREA, 0, rawRect, 0);
rc = (RECT) Marshal.PtrToStructure(rawRect, rc.GetType());
if (bResult == 1)
{
Marshal.FreeHGlobal(rawRect);
return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
return new Rectangle(0, 0, 0, 0);
}
}
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;
} }
}
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;
}
}
} }

View File

@@ -3,85 +3,85 @@ using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Win32 API imports.
/// </summary>
internal static class WinApi
{
/// <summary> /// <summary>
/// Creates, updates or deletes the taskbar icon. /// Win32 API imports.
/// </summary> /// </summary>
[DllImport("shell32.Dll", CharSet = CharSet.Unicode)] internal static class WinApi
public static extern bool Shell_NotifyIcon(NotifyCommand cmd, [In]ref NotifyIconData data); {
/// <summary>
/// Creates, updates or deletes the taskbar icon.
/// </summary>
[DllImport("shell32.Dll", CharSet = CharSet.Unicode)]
public static extern bool Shell_NotifyIcon(NotifyCommand cmd, [In] ref NotifyIconData data);
/// <summary> /// <summary>
/// Creates the helper window that receives messages from the taskar icon. /// Creates the helper window that receives messages from the taskar icon.
/// </summary> /// </summary>
[DllImport("USER32.DLL", EntryPoint = "CreateWindowExW", SetLastError = true)] [DllImport("USER32.DLL", EntryPoint = "CreateWindowExW", SetLastError = true)]
public static extern IntPtr CreateWindowEx(int dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, public static extern IntPtr CreateWindowEx(int dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
[MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, int dwStyle, int x, int y, [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, int dwStyle, int x, int y,
int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance,
IntPtr lpParam); IntPtr lpParam);
/// <summary> /// <summary>
/// Processes a default windows procedure. /// Processes a default windows procedure.
/// </summary> /// </summary>
[DllImport("USER32.DLL")] [DllImport("USER32.DLL")]
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wparam, IntPtr lparam); public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wparam, IntPtr lparam);
/// <summary>
/// Registers the helper window class.
/// </summary>
[DllImport("USER32.DLL", EntryPoint = "RegisterClassW", SetLastError = true)]
public static extern short RegisterClass(ref WindowClass lpWndClass);
/// <summary> /// <summary>
/// Registers a listener for a window message. /// Registers the helper window class.
/// </summary> /// </summary>
/// <param name="lpString"></param> [DllImport("USER32.DLL", EntryPoint = "RegisterClassW", SetLastError = true)]
/// <returns></returns> public static extern short RegisterClass(ref WindowClass lpWndClass);
[DllImport("User32.Dll", EntryPoint = "RegisterWindowMessageW")]
public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString);
/// <summary> /// <summary>
/// Used to destroy the hidden helper window that receives messages from the /// Registers a listener for a window message.
/// taskbar icon. /// </summary>
/// </summary> /// <param name="lpString"></param>
/// <param name="hWnd"></param> /// <returns></returns>
/// <returns></returns> [DllImport("User32.Dll", EntryPoint = "RegisterWindowMessageW")]
[DllImport("USER32.DLL", SetLastError = true)] public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString);
public static extern bool DestroyWindow(IntPtr hWnd);
/// <summary>
/// Used to destroy the hidden helper window that receives messages from the
/// taskbar icon.
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("USER32.DLL", SetLastError = true)]
public static extern bool DestroyWindow(IntPtr hWnd);
/// <summary> /// <summary>
/// Gives focus to a given window. /// Gives focus to a given window.
/// </summary> /// </summary>
/// <param name="hWnd"></param> /// <param name="hWnd"></param>
/// <returns></returns> /// <returns></returns>
[DllImport("USER32.DLL")] [DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd); public static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary> /// <summary>
/// Gets the maximum number of milliseconds that can elapse between a /// Gets the maximum number of milliseconds that can elapse between a
/// first click and a second click for the OS to consider the /// first click and a second click for the OS to consider the
/// mouse action a double-click. /// mouse action a double-click.
/// </summary> /// </summary>
/// <returns>The maximum amount of time, in milliseconds, that can /// <returns>The maximum amount of time, in milliseconds, that can
/// elapse between a first click and a second click for the OS to /// elapse between a first click and a second click for the OS to
/// consider the mouse action a double-click.</returns> /// consider the mouse action a double-click.</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetDoubleClickTime(); public static extern int GetDoubleClickTime();
/// <summary> /// <summary>
/// Gets the screen coordinates of the current mouse position. /// Gets the screen coordinates of the current mouse position.
/// </summary> /// </summary>
/// <param name="lpPoint"></param> /// <param name="lpPoint"></param>
/// <returns></returns> /// <returns></returns>
[DllImport("USER32.DLL", SetLastError = true)] [DllImport("USER32.DLL", SetLastError = true)]
public static extern bool GetCursorPos(ref Point lpPoint); public static extern bool GetCursorPos(ref Point lpPoint);
} }
} }

View File

@@ -3,29 +3,29 @@ using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary> /// <summary>
/// Callback delegate which is used by the Windows API to /// Callback delegate which is used by the Windows API to
/// submit window messages. /// submit window messages.
/// </summary> /// </summary>
public delegate IntPtr WindowProcedureHandler(IntPtr hwnd, uint uMsg, IntPtr wparam, IntPtr lparam); public delegate IntPtr WindowProcedureHandler(IntPtr hwnd, uint uMsg, IntPtr wparam, IntPtr lparam);
/// <summary> /// <summary>
/// Win API WNDCLASS struct - represents a single window. /// Win API WNDCLASS struct - represents a single window.
/// Used to receive window messages. /// Used to receive window messages.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct WindowClass public struct WindowClass
{ {
public uint style; public uint style;
public WindowProcedureHandler lpfnWndProc; public WindowProcedureHandler lpfnWndProc;
public int cbClsExtra; public int cbClsExtra;
public int cbWndExtra; public int cbWndExtra;
public IntPtr hInstance; public IntPtr hInstance;
public IntPtr hIcon; public IntPtr hIcon;
public IntPtr hCursor; public IntPtr hCursor;
public IntPtr hbrBackground; public IntPtr hbrBackground;
[MarshalAs(UnmanagedType.LPWStr)] public string lpszMenuName; [MarshalAs(UnmanagedType.LPWStr)] public string lpszMenuName;
[MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName; [MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName;
} }
} }

View File

@@ -22,7 +22,6 @@
// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE // THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
@@ -30,345 +29,340 @@ using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
{ {
/// <summary>
/// Receives messages from the taskbar icon through
/// window messages of an underlying helper window.
/// </summary>
public class WindowMessageSink : IDisposable
{
#region members
/// <summary> /// <summary>
/// The ID of messages that are received from the the /// Receives messages from the taskbar icon through
/// taskbar icon. /// window messages of an underlying helper window.
/// </summary> /// </summary>
public const int CallbackMessageId = 0x400; public class WindowMessageSink : IDisposable
/// <summary>
/// The ID of the message that is being received if the
/// taskbar is (re)started.
/// </summary>
private uint taskbarRestartMessageId;
/// <summary>
/// Used to track whether a mouse-up event is just
/// the aftermath of a double-click and therefore needs
/// to be suppressed.
/// </summary>
private bool isDoubleClick;
/// <summary>
/// A delegate that processes messages of the hidden
/// native window that receives window messages. Storing
/// this reference makes sure we don't loose our reference
/// to the message window.
/// </summary>
private WindowProcedureHandler messageHandler;
/// <summary>
/// Window class ID.
/// </summary>
internal string WindowId { get; private set; }
/// <summary>
/// Handle for the message window.
/// </summary
internal IntPtr MessageWindowHandle { get; private set; }
/// <summary>
/// The version of the underlying icon. Defines how
/// incoming messages are interpreted.
/// </summary>
public NotifyIconVersion Version { get; set; }
#endregion
#region events
/// <summary>
/// The custom tooltip should be closed or hidden.
/// </summary>
public event Action<bool> ChangeToolTipStateRequest;
/// <summary>
/// Fired in case the user clicked or moved within
/// the taskbar icon area.
/// </summary>
public event Action<MouseEvent> MouseEventReceived;
/// <summary>
/// Fired if a balloon ToolTip was either displayed
/// or closed (indicated by the boolean flag).
/// </summary>
public event Action<bool> BalloonToolTipChanged;
/// <summary>
/// Fired if the taskbar was created or restarted. Requires the taskbar
/// icon to be reset.
/// </summary>
public event Action TaskbarCreated;
#endregion
#region construction
/// <summary>
/// Creates a new message sink that receives message from
/// a given taskbar icon.
/// </summary>
/// <param name="version"></param>
public WindowMessageSink(NotifyIconVersion version)
{ {
Version = version; #region members
CreateMessageWindow();
} /// <summary>
/// The ID of messages that are received from the the
/// taskbar icon.
/// </summary>
public const int CallbackMessageId = 0x400;
/// <summary>
/// The ID of the message that is being received if the
/// taskbar is (re)started.
/// </summary>
private uint taskbarRestartMessageId;
/// <summary>
/// Used to track whether a mouse-up event is just
/// the aftermath of a double-click and therefore needs
/// to be suppressed.
/// </summary>
private bool isDoubleClick;
/// <summary>
/// A delegate that processes messages of the hidden
/// native window that receives window messages. Storing
/// this reference makes sure we don't loose our reference
/// to the message window.
/// </summary>
private WindowProcedureHandler messageHandler;
/// <summary>
/// Window class ID.
/// </summary>
internal string WindowId { get; private set; }
/// <summary>
/// Handle for the message window.
/// </summary
internal IntPtr MessageWindowHandle { get; private set; }
/// <summary>
/// The version of the underlying icon. Defines how
/// incoming messages are interpreted.
/// </summary>
public NotifyIconVersion Version { get; set; }
#endregion
#region events
/// <summary>
/// The custom tooltip should be closed or hidden.
/// </summary>
public event Action<bool> ChangeToolTipStateRequest;
/// <summary>
/// Fired in case the user clicked or moved within
/// the taskbar icon area.
/// </summary>
public event Action<MouseEvent> MouseEventReceived;
/// <summary>
/// Fired if a balloon ToolTip was either displayed
/// or closed (indicated by the boolean flag).
/// </summary>
public event Action<bool> BalloonToolTipChanged;
/// <summary>
/// Fired if the taskbar was created or restarted. Requires the taskbar
/// icon to be reset.
/// </summary>
public event Action TaskbarCreated;
#endregion
#region construction
/// <summary>
/// Creates a new message sink that receives message from
/// a given taskbar icon.
/// </summary>
/// <param name="version"></param>
public WindowMessageSink(NotifyIconVersion version)
{
Version = version;
CreateMessageWindow();
}
private WindowMessageSink() private WindowMessageSink()
{ {
} }
/// <summary> /// <summary>
/// Creates a dummy instance that provides an empty /// Creates a dummy instance that provides an empty
/// pointer rather than a real window handler.<br/> /// pointer rather than a real window handler.<br/>
/// Used at design time. /// Used at design time.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal static WindowMessageSink CreateEmpty() internal static WindowMessageSink CreateEmpty()
{ {
return new WindowMessageSink return new WindowMessageSink
{ {
MessageWindowHandle = IntPtr.Zero, MessageWindowHandle = IntPtr.Zero,
Version = NotifyIconVersion.Vista Version = NotifyIconVersion.Vista
}; };
} }
#endregion #endregion
#region CreateMessageWindow
#region CreateMessageWindow /// <summary>
/// Creates the helper message window that is used
/// to receive messages from the taskbar icon.
/// </summary>
private void CreateMessageWindow()
{
//generate a unique ID for the window
WindowId = "WPFTaskbarIcon_" + DateTime.Now.Ticks;
/// <summary> //register window message handler
/// Creates the helper message window that is used messageHandler = OnWindowMessageReceived;
/// to receive messages from the taskbar icon.
/// </summary>
private void CreateMessageWindow()
{
//generate a unique ID for the window
WindowId = "WPFTaskbarIcon_" + DateTime.Now.Ticks;
//register window message handler // Create a simple window class which is reference through
messageHandler = OnWindowMessageReceived; //the messageHandler delegate
WindowClass wc;
// Create a simple window class which is reference through wc.style = 0;
//the messageHandler delegate wc.lpfnWndProc = messageHandler;
WindowClass wc; wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = IntPtr.Zero;
wc.hIcon = IntPtr.Zero;
wc.hCursor = IntPtr.Zero;
wc.hbrBackground = IntPtr.Zero;
wc.lpszMenuName = "";
wc.lpszClassName = WindowId;
wc.style = 0; // Register the window class
wc.lpfnWndProc = messageHandler; WinApi.RegisterClass(ref wc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = IntPtr.Zero;
wc.hIcon = IntPtr.Zero;
wc.hCursor = IntPtr.Zero;
wc.hbrBackground = IntPtr.Zero;
wc.lpszMenuName = "";
wc.lpszClassName = WindowId;
// Register the window class // Get the message used to indicate the taskbar has been restarted
WinApi.RegisterClass(ref wc); // This is used to re-add icons when the taskbar restarts
taskbarRestartMessageId = WinApi.RegisterWindowMessage("TaskbarCreated");
// Get the message used to indicate the taskbar has been restarted // Create the message window
// This is used to re-add icons when the taskbar restarts MessageWindowHandle = WinApi.CreateWindowEx(0, WindowId, "", 0, 0, 0, 1, 1, IntPtr.Zero, IntPtr.Zero,
taskbarRestartMessageId = WinApi.RegisterWindowMessage("TaskbarCreated"); IntPtr.Zero, IntPtr.Zero);
// Create the message window if (MessageWindowHandle == IntPtr.Zero)
MessageWindowHandle = WinApi.CreateWindowEx(0, WindowId, "", 0, 0, 0, 1, 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); {
if (MessageWindowHandle == IntPtr.Zero)
{
#if SILVERLIGHT #if SILVERLIGHT
throw new Exception("Message window handle was not a valid pointer."); throw new Exception("Message window handle was not a valid pointer.");
#else #else
throw new Win32Exception("Message window handle was not a valid pointer"); throw new Win32Exception("Message window handle was not a valid pointer");
#endif #endif
} }
}
#endregion
#region Handle Window Messages
/// <summary>
/// Callback method that receives messages from the taskbar area.
/// </summary>
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)
TaskbarCreated();
}
//forward message
ProcessWindowMessage(messageId, wparam, lparam);
// Pass the message to the default window procedure
return WinApi.DefWindowProc(hwnd, messageId, wparam, lparam);
}
/// <summary>
/// Processes incoming system messages.
/// </summary>
/// <param name="msg">Callback ID.</param>
/// <param name="wParam">If the version is <see cref="NotifyIconVersion.Vista"/>
/// or higher, this parameter can be used to resolve mouse coordinates.
/// Currently not in use.</param>
/// <param name="lParam">Provides information about the event.</param>
private void ProcessWindowMessage(uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg != CallbackMessageId) return;
switch (lParam.ToInt32())
{
case 0x200:
MouseEventReceived(MouseEvent.MouseMove);
break;
case 0x201:
MouseEventReceived(MouseEvent.IconLeftMouseDown);
break;
case 0x202:
if (!isDoubleClick)
{
MouseEventReceived(MouseEvent.IconLeftMouseUp);
}
isDoubleClick = false;
break;
case 0x203:
isDoubleClick = true;
MouseEventReceived(MouseEvent.IconDoubleClick);
break;
case 0x204:
MouseEventReceived(MouseEvent.IconRightMouseDown);
break;
case 0x205:
MouseEventReceived(MouseEvent.IconRightMouseUp);
break;
case 0x206:
//double click with right mouse button - do not trigger event
break;
case 0x207:
MouseEventReceived(MouseEvent.IconMiddleMouseDown);
break;
case 520:
MouseEventReceived(MouseEvent.IconMiddleMouseUp);
break;
case 0x209:
//double click with middle mouse button - do not trigger event
break;
case 0x402:
BalloonToolTipChanged(true);
break;
case 0x403:
case 0x404:
BalloonToolTipChanged(false);
break;
case 0x405:
MouseEventReceived(MouseEvent.BalloonToolTipClicked);
break;
case 0x406:
ChangeToolTipStateRequest(true);
break;
case 0x407:
ChangeToolTipStateRequest(false);
break;
default:
Debug.WriteLine("Unhandled NotifyIcon message ID: " + lParam);
break;
}
}
#endregion
#region Dispose
/// <summary>
/// Set to true as soon as <see cref="Dispose"/>
/// has been invoked.
/// </summary>
public bool IsDisposed { get; private set; }
/// <summary>
/// Disposes the object.
/// </summary>
/// <remarks>This method is not virtual by design. Derived classes
/// should override <see cref="Dispose(bool)"/>.
/// </remarks>
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <summary>
/// This destructor will run only if the <see cref="Dispose()"/>
/// method does not get called. This gives this base class the
/// opportunity to finalize.
/// <para>
/// Important: Do not provide destructors in types derived from
/// this class.
/// </para>
/// </summary>
~WindowMessageSink()
{
Dispose(false);
}
/// <summary>
/// Removes the windows hook that receives window
/// messages and closes the underlying helper window.
/// </summary>
private void Dispose(bool disposing)
{
//don't do anything if the component is already disposed
if (IsDisposed) return;
IsDisposed = true;
//always destroy the unmanaged handle (even if called from the GC)
WinApi.DestroyWindow(MessageWindowHandle);
messageHandler = null;
}
#endregion
} }
#endregion
#region Handle Window Messages
/// <summary>
/// Callback method that receives messages from the taskbar area.
/// </summary>
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)
TaskbarCreated();
}
//forward message
ProcessWindowMessage(messageId, wparam, lparam);
// Pass the message to the default window procedure
return WinApi.DefWindowProc(hwnd, messageId, wparam, lparam);
}
/// <summary>
/// Processes incoming system messages.
/// </summary>
/// <param name="msg">Callback ID.</param>
/// <param name="wParam">If the version is <see cref="NotifyIconVersion.Vista"/>
/// or higher, this parameter can be used to resolve mouse coordinates.
/// Currently not in use.</param>
/// <param name="lParam">Provides information about the event.</param>
private void ProcessWindowMessage(uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg != CallbackMessageId) return;
switch (lParam.ToInt32())
{
case 0x200:
MouseEventReceived(MouseEvent.MouseMove); break;
case 0x201:
MouseEventReceived(MouseEvent.IconLeftMouseDown);
break;
case 0x202:
if (!isDoubleClick)
{
MouseEventReceived(MouseEvent.IconLeftMouseUp);
}
isDoubleClick = false;
break;
case 0x203:
isDoubleClick = true;
MouseEventReceived(MouseEvent.IconDoubleClick);
break;
case 0x204:
MouseEventReceived(MouseEvent.IconRightMouseDown);
break;
case 0x205:
MouseEventReceived(MouseEvent.IconRightMouseUp);
break;
case 0x206:
//double click with right mouse button - do not trigger event
break;
case 0x207:
MouseEventReceived(MouseEvent.IconMiddleMouseDown);
break;
case 520:
MouseEventReceived(MouseEvent.IconMiddleMouseUp);
break;
case 0x209:
//double click with middle mouse button - do not trigger event
break;
case 0x402:
BalloonToolTipChanged(true);
break;
case 0x403:
case 0x404:
BalloonToolTipChanged(false);
break;
case 0x405:
MouseEventReceived(MouseEvent.BalloonToolTipClicked);
break;
case 0x406:
ChangeToolTipStateRequest(true);
break;
case 0x407:
ChangeToolTipStateRequest(false);
break;
default:
Debug.WriteLine("Unhandled NotifyIcon message ID: " + lParam);
break;
}
}
#endregion
#region Dispose
/// <summary>
/// Set to true as soon as <see cref="Dispose"/>
/// has been invoked.
/// </summary>
public bool IsDisposed { get; private set; }
/// <summary>
/// Disposes the object.
/// </summary>
/// <remarks>This method is not virtual by design. Derived classes
/// should override <see cref="Dispose(bool)"/>.
/// </remarks>
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <summary>
/// This destructor will run only if the <see cref="Dispose()"/>
/// method does not get called. This gives this base class the
/// opportunity to finalize.
/// <para>
/// Important: Do not provide destructors in types derived from
/// this class.
/// </para>
/// </summary>
~WindowMessageSink()
{
Dispose(false);
}
/// <summary>
/// Removes the windows hook that receives window
/// messages and closes the underlying helper window.
/// </summary>
private void Dispose(bool disposing)
{
//don't do anything if the component is already disposed
if (IsDisposed) return;
IsDisposed = true;
//always destroy the unmanaged handle (even if called from the GC)
WinApi.DestroyWindow(MessageWindowHandle);
messageHandler = null;
}
#endregion
}
} }

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -10,11 +10,11 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Hardcodet.Wpf.TaskbarNotification</RootNamespace> <RootNamespace>Hardcodet.Wpf.TaskbarNotification</RootNamespace>
<AssemblyName>Hardcodet.Wpf.TaskbarNotification</AssemblyName> <AssemblyName>Hardcodet.Wpf.TaskbarNotification</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<TargetFrameworkSubset>Client</TargetFrameworkSubset> <TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -25,6 +25,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@@ -34,6 +35,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Hardcodet.Wpf.TaskbarNotification.xml</DocumentationFile> <DocumentationFile>bin\Release\Hardcodet.Wpf.TaskbarNotification.xml</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@@ -41,6 +43,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />

View File

@@ -24,46 +24,52 @@
namespace Hardcodet.Wpf.TaskbarNotification namespace Hardcodet.Wpf.TaskbarNotification
{ {
/// <summary>
/// Defines flags that define when a popup
/// is being displyed.
/// </summary>
public enum PopupActivationMode
{
/// <summary> /// <summary>
/// The item is displayed if the user clicks the /// Defines flags that define when a popup
/// tray icon with the left mouse button. /// is being displyed.
/// </summary> /// </summary>
LeftClick, public enum PopupActivationMode
/// <summary> {
/// The item is displayed if the user clicks the /// <summary>
/// tray icon with the right mouse button. /// The item is displayed if the user clicks the
/// </summary> /// tray icon with the left mouse button.
RightClick, /// </summary>
/// <summary> LeftClick,
/// The item is displayed if the user double-clicks the
/// tray icon. /// <summary>
/// </summary> /// The item is displayed if the user clicks the
DoubleClick, /// tray icon with the right mouse button.
/// <summary> /// </summary>
/// The item is displayed if the user clicks the RightClick,
/// tray icon with the left or the right mouse button.
/// </summary> /// <summary>
LeftOrRightClick, /// The item is displayed if the user double-clicks the
/// <summary> /// tray icon.
/// The item is displayed if the user clicks the /// </summary>
/// tray icon with the left mouse button or if a DoubleClick,
/// double-click is being performed.
/// </summary> /// <summary>
LeftOrDoubleClick, /// The item is displayed if the user clicks the
/// <summary> /// tray icon with the left or the right mouse button.
/// The item is displayed if the user clicks the /// </summary>
/// tray icon with the middle mouse button. LeftOrRightClick,
/// </summary>
MiddleClick, /// <summary>
/// <summary> /// The item is displayed if the user clicks the
/// The item is displayed whenever a click occurs. /// tray icon with the left mouse button or if a
/// </summary> /// double-click is being performed.
All /// </summary>
} LeftOrDoubleClick,
}
/// <summary>
/// The item is displayed if the user clicks the
/// tray icon with the middle mouse button.
/// </summary>
MiddleClick,
/// <summary>
/// The item is displayed whenever a click occurs.
/// </summary>
All
}
}

View File

@@ -6,21 +6,25 @@ using System.Windows.Markup;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("NotifyIcon for WPF")] [assembly: AssemblyTitle("NotifyIcon for WPF")]
[assembly: AssemblyDescription("NotifyIcon Implementation for the WPF platform.")] [assembly: AssemblyDescription("NotifyIcon implementation for the WPF platform.")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("hardcodet.net")] [assembly: AssemblyCompany("hardcodet.net")]
[assembly: AssemblyProduct("NotifyIcon WPF")] [assembly: AssemblyProduct("NotifyIcon WPF")]
[assembly: AssemblyCopyright("Copyright © Philipp Sumi 2009")] [assembly: AssemblyCopyright("Copyright © Philipp Sumi 2046")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
//provides simplified declaration //provides simplified declaration
[assembly: XmlnsPrefix("http://www.hardcodet.net/taskbar", "tb")]
[assembly: XmlnsDefinition("http://www.hardcodet.net/taskbar", "Hardcodet.Wpf.TaskbarNotification")] [assembly: XmlnsDefinition("http://www.hardcodet.net/taskbar", "Hardcodet.Wpf.TaskbarNotification")]
// Setting ComVisible to false makes the types in this assembly not visible // 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 // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
//In order to begin building localizable applications, set //In order to begin building localizable applications, set
@@ -35,12 +39,12 @@ using System.Windows.Markup;
[assembly: ThemeInfo( [assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// or application resource dictionaries) // or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries) // app, or any theme specific resource dictionaries)
)] )]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
@@ -53,5 +57,6 @@ using System.Windows.Markup;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:2.0.50727.3053 // Runtime Version:4.0.30319.18408
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -19,7 +19,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Properties {
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources { internal class Resources {
@@ -60,6 +60,9 @@ namespace Hardcodet.Wpf.TaskbarNotification.Properties {
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon DefaultTrayIcon { internal static System.Drawing.Icon DefaultTrayIcon {
get { get {
object obj = ResourceManager.GetObject("DefaultTrayIcon", resourceCulture); object obj = ResourceManager.GetObject("DefaultTrayIcon", resourceCulture);

View File

@@ -3,79 +3,79 @@ using System.Windows;
namespace Hardcodet.Wpf.TaskbarNotification namespace Hardcodet.Wpf.TaskbarNotification
{ {
/// <summary>
/// Helper class used by routed events of the
/// <see cref="TaskbarIcon"/> class.
/// </summary>
internal static class RoutedEventHelper
{
#region RoutedEvent Helper Methods
/// <summary> /// <summary>
/// A static helper method to raise a routed event on a target UIElement or ContentElement. /// Helper class used by routed events of the
/// <see cref="TaskbarIcon"/> class.
/// </summary> /// </summary>
/// <param name="target">UIElement or ContentElement on which to raise the event</param> internal static class RoutedEventHelper
/// <param name="args">RoutedEventArgs to use when raising the event</param>
internal static void RaiseEvent(DependencyObject target, RoutedEventArgs args)
{ {
if (target is UIElement) #region RoutedEvent Helper Methods
{
(target as UIElement).RaiseEvent(args);
}
else if (target is ContentElement)
{
(target as ContentElement).RaiseEvent(args);
}
}
/// <summary> /// <summary>
/// A static helper method that adds a handler for a routed event /// A static helper method to raise a routed event on a target UIElement or ContentElement.
/// to a target UIElement or ContentElement. /// </summary>
/// </summary> /// <param name="target">UIElement or ContentElement on which to raise the event</param>
/// <param name="element">UIElement or ContentElement that listens to the event</param> /// <param name="args">RoutedEventArgs to use when raising the event</param>
/// <param name="routedEvent">Event that will be handled</param> internal static void RaiseEvent(DependencyObject target, RoutedEventArgs args)
/// <param name="handler">Event handler to be added</param>
internal static void AddHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler)
{
UIElement uie = element as UIElement;
if (uie != null)
{
uie.AddHandler(routedEvent, handler);
}
else
{
ContentElement ce = element as ContentElement;
if (ce != null)
{ {
ce.AddHandler(routedEvent, handler); if (target is UIElement)
{
(target as UIElement).RaiseEvent(args);
}
else if (target is ContentElement)
{
(target as ContentElement).RaiseEvent(args);
}
} }
}
}
/// <summary> /// <summary>
/// A static helper method that removes a handler for a routed event /// A static helper method that adds a handler for a routed event
/// from a target UIElement or ContentElement. /// to a target UIElement or ContentElement.
/// </summary> /// </summary>
/// <param name="element">UIElement or ContentElement that listens to the event</param> /// <param name="element">UIElement or ContentElement that listens to the event</param>
/// <param name="routedEvent">Event that will no longer be handled</param> /// <param name="routedEvent">Event that will be handled</param>
/// <param name="handler">Event handler to be removed</param> /// <param name="handler">Event handler to be added</param>
internal static void RemoveHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler) internal static void AddHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler)
{
UIElement uie = element as UIElement;
if (uie != null)
{
uie.RemoveHandler(routedEvent, handler);
}
else
{
ContentElement ce = element as ContentElement;
if (ce != null)
{ {
ce.RemoveHandler(routedEvent, handler); UIElement uie = element as UIElement;
if (uie != null)
{
uie.AddHandler(routedEvent, handler);
}
else
{
ContentElement ce = element as ContentElement;
if (ce != null)
{
ce.AddHandler(routedEvent, handler);
}
}
} }
}
}
#endregion /// <summary>
} /// A static helper method that removes a handler for a routed event
} /// from a target UIElement or ContentElement.
/// </summary>
/// <param name="element">UIElement or ContentElement that listens to the event</param>
/// <param name="routedEvent">Event that will no longer be handled</param>
/// <param name="handler">Event handler to be removed</param>
internal static void RemoveHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler)
{
UIElement uie = element as UIElement;
if (uie != null)
{
uie.RemoveHandler(routedEvent, handler);
}
else
{
ContentElement ce = element as ContentElement;
if (ce != null)
{
ce.RemoveHandler(routedEvent, handler);
}
}
}
#endregion
}
}

View File

@@ -705,7 +705,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
IntPtr handle = IntPtr.Zero; IntPtr handle = IntPtr.Zero;
//try to get a handle on the context itself //try to get a handle on the context itself
HwndSource source = (HwndSource)PresentationSource.FromVisual(ContextMenu); HwndSource source = (HwndSource) PresentationSource.FromVisual(ContextMenu);
if (source != null) if (source != null)
{ {
handle = source.Handle; handle = source.Handle;

View File

@@ -34,275 +34,276 @@ using Hardcodet.Wpf.TaskbarNotification.Interop;
namespace Hardcodet.Wpf.TaskbarNotification namespace Hardcodet.Wpf.TaskbarNotification
{ {
/// <summary>
/// Util and extension methods.
/// </summary>
internal static class Util
{
public static readonly object SyncRoot = new object();
#region IsDesignMode
private static readonly bool isDesignMode;
/// <summary> /// <summary>
/// Checks whether the application is currently in design mode. /// Util and extension methods.
/// </summary> /// </summary>
public static bool IsDesignMode internal static class Util
{ {
get { return isDesignMode; } public static readonly object SyncRoot = new object();
#region IsDesignMode
private static readonly bool isDesignMode;
/// <summary>
/// Checks whether the application is currently in design mode.
/// </summary>
public static bool IsDesignMode
{
get { return isDesignMode; }
}
#endregion
#region construction
static Util()
{
isDesignMode =
(bool)
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
typeof (FrameworkElement))
.Metadata.DefaultValue;
}
#endregion
#region CreateHelperWindow
/// <summary>
/// Creates an transparent window without dimension that
/// can be used to temporarily obtain focus and/or
/// be used as a window message sink.
/// </summary>
/// <returns>Empty window.</returns>
public static Window CreateHelperWindow()
{
return new Window
{
Width = 0,
Height = 0,
ShowInTaskbar = false,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Opacity = 0
};
}
#endregion
#region WriteIconData
/// <summary>
/// Updates the taskbar icons with data provided by a given
/// <see cref="NotifyIconData"/> instance.
/// </summary>
/// <param name="data">Configuration settings for the NotifyIcon.</param>
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
/// <returns>True if the data was successfully written.</returns>
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
{
return WriteIconData(ref data, command, data.ValidMembers);
}
/// <summary>
/// Updates the taskbar icons with data provided by a given
/// <see cref="NotifyIconData"/> instance.
/// </summary>
/// <param name="data">Configuration settings for the NotifyIcon.</param>
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
/// <param name="flags">Defines which members of the <paramref name="data"/>
/// structure are set.</param>
/// <returns>True if the data was successfully written.</returns>
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
{
//do nothing if in design mode
if (IsDesignMode) return true;
data.ValidMembers = flags;
lock (SyncRoot)
{
return WinApi.Shell_NotifyIcon(command, ref data);
}
}
#endregion
#region GetBalloonFlag
/// <summary>
/// Gets a <see cref="BalloonFlags"/> enum value that
/// matches a given <see cref="BalloonIcon"/>.
/// </summary>
public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
{
switch (icon)
{
case BalloonIcon.None:
return BalloonFlags.None;
case BalloonIcon.Info:
return BalloonFlags.Info;
case BalloonIcon.Warning:
return BalloonFlags.Warning;
case BalloonIcon.Error:
return BalloonFlags.Error;
default:
throw new ArgumentOutOfRangeException("icon");
}
}
#endregion
#region ImageSource to Icon
/// <summary>
/// Reads a given image resource into a WinForms icon.
/// </summary>
/// <param name="imageSource">Image source pointing to
/// an icon file (*.ico).</param>
/// <returns>An icon object that can be used with the
/// taskbar area.</returns>
public static Icon ToIcon(this ImageSource imageSource)
{
if (imageSource == null) return null;
Uri uri = new Uri(imageSource.ToString());
StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
if (streamInfo == null)
{
string msg = "The supplied image source '{0}' could not be resolved.";
msg = String.Format(msg, imageSource);
throw new ArgumentException(msg);
}
return new Icon(streamInfo.Stream);
}
#endregion
#region evaluate listings
/// <summary>
/// Checks a list of candidates for equality to a given
/// reference value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The evaluated value.</param>
/// <param name="candidates">A liste of possible values that are
/// regarded valid.</param>
/// <returns>True if one of the submitted <paramref name="candidates"/>
/// matches the evaluated value. If the <paramref name="candidates"/>
/// parameter itself is null, too, the method returns false as well,
/// which allows to check with null values, too.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
/// is a null reference.</exception>
public static bool Is<T>(this T value, params T[] candidates)
{
if (candidates == null) return false;
foreach (var t in candidates)
{
if (value.Equals(t)) return true;
}
return false;
}
#endregion
#region match MouseEvent to PopupActivation
/// <summary>
/// Checks if a given <see cref="PopupActivationMode"/> is a match for
/// an effectively pressed mouse button.
/// </summary>
public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
{
switch (activationMode)
{
case PopupActivationMode.LeftClick:
return me == MouseEvent.IconLeftMouseUp;
case PopupActivationMode.RightClick:
return me == MouseEvent.IconRightMouseUp;
case PopupActivationMode.LeftOrRightClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
case PopupActivationMode.LeftOrDoubleClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
case PopupActivationMode.DoubleClick:
return me.Is(MouseEvent.IconDoubleClick);
case PopupActivationMode.MiddleClick:
return me == MouseEvent.IconMiddleMouseUp;
case PopupActivationMode.All:
//return true for everything except mouse movements
return me != MouseEvent.MouseMove;
default:
throw new ArgumentOutOfRangeException("activationMode");
}
}
#endregion
#region execute command
/// <summary>
/// Executes a given command if its <see cref="ICommand.CanExecute"/> method
/// indicates it can run.
/// </summary>
/// <param name="command">The command to be executed, or a null reference.</param>
/// <param name="commandParameter">An optional parameter that is associated with
/// the command.</param>
/// <param name="target">The target element on which to raise the command.</param>
public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
{
if (command == null) return;
RoutedCommand rc = command as RoutedCommand;
if (rc != null)
{
//routed commands work on a target
if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
}
else if (command.CanExecute(commandParameter))
{
command.Execute(commandParameter);
}
}
#endregion
/// <summary>
/// Returns a dispatcher for multi-threaded scenarios
/// </summary>
/// <returns></returns>
internal static Dispatcher GetDispatcher(this DispatcherObject source)
{
//use the application's dispatcher by default
if (Application.Current != null) return Application.Current.Dispatcher;
//fallback for WinForms environments
if (source.Dispatcher != null) return source.Dispatcher;
//ultimatively use the thread's dispatcher
return Dispatcher.CurrentDispatcher;
}
/// <summary>
/// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
/// is bound or not.
/// </summary>
/// <param name="element">The element to be checked.</param>
/// <returns>True if the data context property is being managed by a
/// binding expression.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="element"/>
/// is a null reference.</exception>
public static bool IsDataContextDataBound(this FrameworkElement element)
{
if (element == null) throw new ArgumentNullException("element");
return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
}
} }
#endregion
#region construction
static Util()
{
isDesignMode =
(bool)
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof (FrameworkElement))
.Metadata.DefaultValue;
}
#endregion
#region CreateHelperWindow
/// <summary>
/// Creates an transparent window without dimension that
/// can be used to temporarily obtain focus and/or
/// be used as a window message sink.
/// </summary>
/// <returns>Empty window.</returns>
public static Window CreateHelperWindow()
{
return new Window
{
Width = 0,
Height = 0,
ShowInTaskbar = false,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Opacity = 0
};
}
#endregion
#region WriteIconData
/// <summary>
/// Updates the taskbar icons with data provided by a given
/// <see cref="NotifyIconData"/> instance.
/// </summary>
/// <param name="data">Configuration settings for the NotifyIcon.</param>
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
/// <returns>True if the data was successfully written.</returns>
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
{
return WriteIconData(ref data, command, data.ValidMembers);
}
/// <summary>
/// Updates the taskbar icons with data provided by a given
/// <see cref="NotifyIconData"/> instance.
/// </summary>
/// <param name="data">Configuration settings for the NotifyIcon.</param>
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
/// <param name="flags">Defines which members of the <paramref name="data"/>
/// structure are set.</param>
/// <returns>True if the data was successfully written.</returns>
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
{
//do nothing if in design mode
if (IsDesignMode) return true;
data.ValidMembers = flags;
lock (SyncRoot)
{
return WinApi.Shell_NotifyIcon(command, ref data);
}
}
#endregion
#region GetBalloonFlag
/// <summary>
/// Gets a <see cref="BalloonFlags"/> enum value that
/// matches a given <see cref="BalloonIcon"/>.
/// </summary>
public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
{
switch (icon)
{
case BalloonIcon.None:
return BalloonFlags.None;
case BalloonIcon.Info:
return BalloonFlags.Info;
case BalloonIcon.Warning:
return BalloonFlags.Warning;
case BalloonIcon.Error:
return BalloonFlags.Error;
default:
throw new ArgumentOutOfRangeException("icon");
}
}
#endregion
#region ImageSource to Icon
/// <summary>
/// Reads a given image resource into a WinForms icon.
/// </summary>
/// <param name="imageSource">Image source pointing to
/// an icon file (*.ico).</param>
/// <returns>An icon object that can be used with the
/// taskbar area.</returns>
public static Icon ToIcon(this ImageSource imageSource)
{
if (imageSource == null) return null;
Uri uri = new Uri(imageSource.ToString());
StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
if (streamInfo == null)
{
string msg = "The supplied image source '{0}' could not be resolved.";
msg = String.Format(msg, imageSource);
throw new ArgumentException(msg);
}
return new Icon(streamInfo.Stream);
}
#endregion
#region evaluate listings
/// <summary>
/// Checks a list of candidates for equality to a given
/// reference value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The evaluated value.</param>
/// <param name="candidates">A liste of possible values that are
/// regarded valid.</param>
/// <returns>True if one of the submitted <paramref name="candidates"/>
/// matches the evaluated value. If the <paramref name="candidates"/>
/// parameter itself is null, too, the method returns false as well,
/// which allows to check with null values, too.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
/// is a null reference.</exception>
public static bool Is<T>(this T value, params T[] candidates)
{
if (candidates == null) return false;
foreach (var t in candidates)
{
if (value.Equals(t)) return true;
}
return false;
}
#endregion
#region match MouseEvent to PopupActivation
/// <summary>
/// Checks if a given <see cref="PopupActivationMode"/> is a match for
/// an effectively pressed mouse button.
/// </summary>
public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
{
switch (activationMode)
{
case PopupActivationMode.LeftClick:
return me == MouseEvent.IconLeftMouseUp;
case PopupActivationMode.RightClick:
return me == MouseEvent.IconRightMouseUp;
case PopupActivationMode.LeftOrRightClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
case PopupActivationMode.LeftOrDoubleClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
case PopupActivationMode.DoubleClick:
return me.Is(MouseEvent.IconDoubleClick);
case PopupActivationMode.MiddleClick:
return me == MouseEvent.IconMiddleMouseUp;
case PopupActivationMode.All:
//return true for everything except mouse movements
return me != MouseEvent.MouseMove;
default:
throw new ArgumentOutOfRangeException("activationMode");
}
}
#endregion
#region execute command
/// <summary>
/// Executes a given command if its <see cref="ICommand.CanExecute"/> method
/// indicates it can run.
/// </summary>
/// <param name="command">The command to be executed, or a null reference.</param>
/// <param name="commandParameter">An optional parameter that is associated with
/// the command.</param>
/// <param name="target">The target element on which to raise the command.</param>
public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
{
if (command == null) return;
RoutedCommand rc = command as RoutedCommand;
if (rc != null)
{
//routed commands work on a target
if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
}
else if (command.CanExecute(commandParameter))
{
command.Execute(commandParameter);
}
}
#endregion
/// <summary>
/// Returns a dispatcher for multi-threaded scenarios
/// </summary>
/// <returns></returns>
internal static Dispatcher GetDispatcher(this DispatcherObject source)
{
//use the application's dispatcher by default
if (Application.Current != null) return Application.Current.Dispatcher;
//fallback for WinForms environments
if (source.Dispatcher != null) return source.Dispatcher;
//ultimatively use the thread's dispatcher
return Dispatcher.CurrentDispatcher;
}
/// <summary>
/// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
/// is bound or not.
/// </summary>
/// <param name="element">The element to be checked.</param>
/// <returns>True if the data context property is being managed by a
/// binding expression.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="element"/>
/// is a null reference.</exception>
public static bool IsDataContextDataBound(this FrameworkElement element)
{
if (element == null) throw new ArgumentNullException("element");
return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
}
}
} }

View File

@@ -8,11 +8,10 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples namespace Samples
{ {
/// <summary> /// <summary>
/// Interaction logic for App.xaml /// Interaction logic for App.xaml
/// </summary> /// </summary>
public partial class App : Application public partial class App : Application
{ {
}
} }
}

View File

@@ -8,151 +8,150 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples.Commands namespace Samples.Commands
{ {
/// <summary>
/// Basic implementation of the <see cref="ICommand"/>
/// interface, which is also accessible as a markup
/// extension.
/// </summary>
public abstract class CommandBase<T> : MarkupExtension, ICommand
where T : class, ICommand, new()
{
/// <summary> /// <summary>
/// A singleton instance. /// Basic implementation of the <see cref="ICommand"/>
/// interface, which is also accessible as a markup
/// extension.
/// </summary> /// </summary>
private static T command; public abstract class CommandBase<T> : MarkupExtension, ICommand
where T : class, ICommand, new()
/// <summary>
/// Gets a shared command instance.
/// </summary>
public override object ProvideValue(IServiceProvider serviceProvider)
{ {
if (command == null) command = new T(); /// <summary>
return command; /// A singleton instance.
/// </summary>
private static T command;
/// <summary>
/// Gets a shared command instance.
/// </summary>
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (command == null) command = new T();
return command;
}
/// <summary>
/// Fires when changes occur that affect whether
/// or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command.
/// If the command does not require data to be passed,
/// this object can be set to null.
/// </param>
public abstract void Execute(object parameter);
/// <summary>
/// Defines the method that determines whether the command
/// can execute in its current state.
/// </summary>
/// <returns>
/// This default implementation always returns true.
/// </returns>
/// <param name="parameter">Data used by the command.
/// If the command does not require data to be passed,
/// this object can be set to null.
/// </param>
public virtual bool CanExecute(object parameter)
{
return IsDesignMode ? false : true;
}
public static bool IsDesignMode
{
get
{
return (bool)
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
typeof (FrameworkElement))
.Metadata.DefaultValue;
}
}
/// <summary>
/// Resolves the window that owns the TaskbarIcon class.
/// </summary>
/// <param name="commandParameter"></param>
/// <returns></returns>
protected Window GetTaskbarWindow(object commandParameter)
{
if (IsDesignMode) return null;
//get the showcase window off the taskbaricon
var tb = commandParameter as TaskbarIcon;
return tb == null ? null : TryFindParent<Window>(tb);
}
#region TryFindParent helper
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Keep in mind that for content element,
/// this method falls back to the logical tree of the element!
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(DependencyObject child)
{
if (child == null) return null;
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//if it's not a ContentElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
#endregion
} }
}
/// <summary>
/// Fires when changes occur that affect whether
/// or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command.
/// If the command does not require data to be passed,
/// this object can be set to null.
/// </param>
public abstract void Execute(object parameter);
/// <summary>
/// Defines the method that determines whether the command
/// can execute in its current state.
/// </summary>
/// <returns>
/// This default implementation always returns true.
/// </returns>
/// <param name="parameter">Data used by the command.
/// If the command does not require data to be passed,
/// this object can be set to null.
/// </param>
public virtual bool CanExecute(object parameter)
{
return IsDesignMode ? false : true;
}
public static bool IsDesignMode
{
get
{
return (bool)
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement))
.Metadata.DefaultValue;
}
}
/// <summary>
/// Resolves the window that owns the TaskbarIcon class.
/// </summary>
/// <param name="commandParameter"></param>
/// <returns></returns>
protected Window GetTaskbarWindow(object commandParameter)
{
if (IsDesignMode) return null;
//get the showcase window off the taskbaricon
var tb = commandParameter as TaskbarIcon;
return tb == null ? null : TryFindParent<Window>(tb);
}
#region TryFindParent helper
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Keep in mind that for content element,
/// this method falls back to the logical tree of the element!
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(DependencyObject child)
{
if (child == null) return null;
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//if it's not a ContentElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
#endregion
}
}

View File

@@ -3,25 +3,22 @@ using System.Windows.Input;
namespace Samples.Commands namespace Samples.Commands
{ {
/// <summary> /// <summary>
/// Hides the main window. /// Hides the main window.
/// </summary> /// </summary>
public class HideSampleWindowCommand : CommandBase<HideSampleWindowCommand> public class HideSampleWindowCommand : CommandBase<HideSampleWindowCommand>
{
public override void Execute(object parameter)
{ {
GetTaskbarWindow(parameter).Hide(); public override void Execute(object parameter)
CommandManager.InvalidateRequerySuggested(); {
GetTaskbarWindow(parameter).Hide();
CommandManager.InvalidateRequerySuggested();
}
public override bool CanExecute(object parameter)
{
Window win = GetTaskbarWindow(parameter);
return win != null && win.IsVisible;
}
} }
}
public override bool CanExecute(object parameter)
{
Window win = GetTaskbarWindow(parameter);
return win != null && win.IsVisible;
}
}
}

View File

@@ -3,22 +3,22 @@ using System.Windows.Input;
namespace Samples.Commands namespace Samples.Commands
{ {
/// <summary> /// <summary>
/// Shows the main window. /// Shows the main window.
/// </summary> /// </summary>
public class ShowSampleWindowCommand : CommandBase<ShowSampleWindowCommand> public class ShowSampleWindowCommand : CommandBase<ShowSampleWindowCommand>
{
public override void Execute(object parameter)
{ {
GetTaskbarWindow(parameter).Show(); public override void Execute(object parameter)
CommandManager.InvalidateRequerySuggested(); {
} GetTaskbarWindow(parameter).Show();
CommandManager.InvalidateRequerySuggested();
}
public override bool CanExecute(object parameter) public override bool CanExecute(object parameter)
{ {
Window win = GetTaskbarWindow(parameter); Window win = GetTaskbarWindow(parameter);
return win != null && !win.IsVisible; return win != null && !win.IsVisible;
}
} }
}
} }

View File

@@ -1,210 +1,227 @@
<Window <Window
x:Class="Samples.Main" x:Class="Samples.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="NotifyIcon Samples" Title="NotifyIcon Samples"
Height="563" Height="563"
Width="703" Width="703"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid <Grid
Hyperlink.RequestNavigate="OnNavigationRequest"> Hyperlink.RequestNavigate="OnNavigationRequest">
<Grid.Background> <Grid.Background>
<LinearGradientBrush <LinearGradientBrush
EndPoint="0.673,0.95" EndPoint="0.673,0.95"
StartPoint="0.274,0.137"> StartPoint="0.274,0.137">
<GradientStop <GradientStop
Color="#FFFFFFFF" Color="#FFFFFFFF"
Offset="0" /> Offset="0" />
<GradientStop <GradientStop
Color="#FFB4C6D8" Color="#FFB4C6D8"
Offset="0.982" /> Offset="0.982" />
</LinearGradientBrush> </LinearGradientBrush>
</Grid.Background> </Grid.Background>
<TextBlock <TextBlock
HorizontalAlignment="Left" HorizontalAlignment="Left"
Margin="10,10,0,0" Margin="10,10,0,0"
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="14" FontSize="14"
FontStyle="Italic" FontStyle="Italic"
FontWeight="Bold" FontWeight="Bold"
TextWrapping="Wrap"><Run TextWrapping="Wrap">
Text="WPF NotifyIcon 1.0.4 - Samples" /></TextBlock> <Run
<Button Text="WPF NotifyIcon 1.0.4 - Samples" />
HorizontalAlignment="Left"
Margin="10,133,0,0"
VerticalAlignment="Top"
Width="164"
Height="27"
Content="NotifyIcon Declaration"
x:Name="btnDeclaration"
Click="btnDeclaration_Click" />
<TextBlock
HorizontalAlignment="Left"
Margin="10,50,0,0"
VerticalAlignment="Top"
FontWeight="Bold"
TextWrapping="Wrap"><Run
Text="Tutorials:" /></TextBlock>
<TextBlock
HorizontalAlignment="Left"
Margin="10,75.96,0,0"
VerticalAlignment="Top"
TextWrapping="Wrap"
Width="224.31"
Height="47.04"
d:LayoutOverrides="HorizontalAlignment"><Run
Text="Tutorials follow the contents of the CodeProject article. Check the &quot;Tutorials&quot; folder for the source code." /></TextBlock>
<Button
HorizontalAlignment="Left"
Margin="10,170,0,0"
Width="164"
Content="ToolTips - Inline Declaration"
VerticalAlignment="Top"
Height="27"
x:Name="btnInlineToolTip"
Click="btnInlineToolTip_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,244,0,0"
Width="164"
Content="Popups"
VerticalAlignment="Top"
Height="27"
x:Name="btnPopups"
Click="btnPopups_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,281,0,0"
Width="164"
Content="Context Menus"
VerticalAlignment="Top"
Height="27"
x:Name="btnContextMenus"
Click="btnContextMenus_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,318,0,0"
Width="164"
Content="Balloon Tips"
VerticalAlignment="Top"
Height="27"
x:Name="btnBalloons"
Click="btnBalloons_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,355,0,0"
Width="164"
Content="Commands"
VerticalAlignment="Top"
Height="27"
x:Name="btnCommands"
Click="btnCommands_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,207,0,0"
Width="164"
Content="ToolTip User Control"
Height="27"
VerticalAlignment="Top"
x:Name="btnToolTipControl"
Click="btnToolTipControl_Click" />
<TextBlock
Margin="0,50,328.76,0"
VerticalAlignment="Top"
FontWeight="Bold"
TextWrapping="Wrap"
HorizontalAlignment="Right"
d:LayoutOverrides="HorizontalAlignment, Width"><Run
Text="Showcase Sample:" /></TextBlock>
<TextBlock
Margin="255.31,75.96,145.38,0"
VerticalAlignment="Top"
TextWrapping="Wrap"
Height="47.04"><Run
Text="An interactive sample that shows off most features on a single NotifyIcon." /></TextBlock>
<Button
Margin="255.31,133,0,0"
VerticalAlignment="Top"
Height="27"
Content="Open Sample Window"
x:Name="btnMainSample"
Click="btnMainSample_Click"
Width="164"
HorizontalAlignment="Left" />
<Path
Fill="#FFFFFFFF"
Stretch="Fill"
Stroke="#FF60758A"
HorizontalAlignment="Left"
Margin="244.31,50,0,66"
Width="1"
Data="M269,57 L269,390.18163" Opacity="0.325" />
<TextBlock
Margin="255.31,191,10,0"
TextWrapping="Wrap"
VerticalAlignment="Top">
<Run Text="The latest news related to the component can be found on the project page:"/>
<LineBreak/>
<Hyperlink NavigateUri="http://www.hardcodet.net/wpf-notifyicon">
<Run Text="http://www.hardcodet.net/wpf-notifyicon"/>
</Hyperlink>
<LineBreak/>
<LineBreak/>
<Run Text="Critical feedback is appreciated - please post bug reports, requests, questions etc. to the CodeProject forum"/>
<Run Language="de-ch" Text=":"/>
<LineBreak/>
<Hyperlink NavigateUri="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx">
<Run Text="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx"/>
</Hyperlink>
<LineBreak/>
<LineBreak/>
<LineBreak/>
<TextBlock>
<Run Text="Love it or hate it? Please let me know and "/>
<Hyperlink NavigateUri="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx">
<Run FontWeight="Bold" Text="rate the project"/>
</Hyperlink>
<Run Text=" - thanks!" />
</TextBlock> </TextBlock>
<Button
</TextBlock> HorizontalAlignment="Left"
<TextBlock Margin="10,133,0,0"
Margin="10,0,10,10" VerticalAlignment="Top"
VerticalAlignment="Bottom" Width="164"
Height="22.42" Height="27"
TextWrapping="Wrap" Content="NotifyIcon Declaration"
FontWeight="Bold"><Run x:Name="btnDeclaration"
Text="WPF NotifyIcon is free software, released under the" /><Run Click="btnDeclaration_Click" />
Text=" " /><Hyperlink <TextBlock
NavigateUri="http://www.codeproject.com/info/cpol10.aspx"><Run HorizontalAlignment="Left"
Text="CodeProject Open License" /></Hyperlink></TextBlock> Margin="10,50,0,0"
<Path VerticalAlignment="Top"
Fill="#FFFFFFFF" FontWeight="Bold"
Stretch="Fill" TextWrapping="Wrap">
Stroke="#FF60758A" <Run
Margin="11,0,17.926,41" Text="Tutorials:" />
VerticalAlignment="Bottom" </TextBlock>
Height="1" <TextBlock
Data="M11,517 L561.07363,517" Opacity="0.33" /> HorizontalAlignment="Left"
<Button Margin="10,75.96,0,0"
Margin="11,429,0,0" VerticalAlignment="Top"
Content="Events" TextWrapping="Wrap"
VerticalAlignment="Top" Width="224.31"
Height="27" Height="47.04"
x:Name="btnEvents" d:LayoutOverrides="HorizontalAlignment">
Click="btnEvents_Click" Width="164" HorizontalAlignment="Left" /> <Run
<Button Text="Tutorials follow the contents of the CodeProject article. Check the &quot;Tutorials&quot; folder for the source code." />
HorizontalAlignment="Left" </TextBlock>
Margin="10,392,0,0" <Button
Width="164" HorizontalAlignment="Left"
Content="Data Binding" Margin="10,170,0,0"
VerticalAlignment="Top" Width="164"
Height="27" Content="ToolTips - Inline Declaration"
x:Name="btnDataBinding" VerticalAlignment="Top"
Click="btnDataBinding_Click" /> Height="27"
x:Name="btnInlineToolTip"
Click="btnInlineToolTip_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,244,0,0"
Width="164"
Content="Popups"
VerticalAlignment="Top"
Height="27"
x:Name="btnPopups"
Click="btnPopups_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,281,0,0"
Width="164"
Content="Context Menus"
VerticalAlignment="Top"
Height="27"
x:Name="btnContextMenus"
Click="btnContextMenus_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,318,0,0"
Width="164"
Content="Balloon Tips"
VerticalAlignment="Top"
Height="27"
x:Name="btnBalloons"
Click="btnBalloons_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,355,0,0"
Width="164"
Content="Commands"
VerticalAlignment="Top"
Height="27"
x:Name="btnCommands"
Click="btnCommands_Click" />
<Button
HorizontalAlignment="Left"
Margin="10,207,0,0"
Width="164"
Content="ToolTip User Control"
Height="27"
VerticalAlignment="Top"
x:Name="btnToolTipControl"
Click="btnToolTipControl_Click" />
<TextBlock
Margin="0,50,328.76,0"
VerticalAlignment="Top"
FontWeight="Bold"
TextWrapping="Wrap"
HorizontalAlignment="Right"
d:LayoutOverrides="HorizontalAlignment, Width">
<Run
Text="Showcase Sample:" />
</TextBlock>
<TextBlock
Margin="255.31,75.96,145.38,0"
VerticalAlignment="Top"
TextWrapping="Wrap"
Height="47.04">
<Run
Text="An interactive sample that shows off most features on a single NotifyIcon." />
</TextBlock>
<Button
Margin="255.31,133,0,0"
VerticalAlignment="Top"
Height="27"
Content="Open Sample Window"
x:Name="btnMainSample"
Click="btnMainSample_Click"
Width="164"
HorizontalAlignment="Left" />
<Path
Fill="#FFFFFFFF"
Stretch="Fill"
Stroke="#FF60758A"
HorizontalAlignment="Left"
Margin="244.31,50,0,66"
Width="1"
Data="M269,57 L269,390.18163" Opacity="0.325" />
<TextBlock
Margin="255.31,191,10,0"
TextWrapping="Wrap"
VerticalAlignment="Top">
<Run Text="The latest news related to the component can be found on the project page:" />
<LineBreak />
<Hyperlink NavigateUri="http://www.hardcodet.net/wpf-notifyicon">
<Run Text="http://www.hardcodet.net/wpf-notifyicon" />
</Hyperlink>
<LineBreak />
<LineBreak />
<Run
Text="Critical feedback is appreciated - please post bug reports, requests, questions etc. to the CodeProject forum" />
<Run Language="de-ch" Text=":" />
<LineBreak />
<Hyperlink NavigateUri="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx">
<Run Text="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx" />
</Hyperlink>
<LineBreak />
<LineBreak />
<LineBreak />
<TextBlock>
<Run Text="Love it or hate it? Please let me know and " />
<Hyperlink NavigateUri="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx">
<Run FontWeight="Bold" Text="rate the project" />
</Hyperlink>
<Run Text=" - thanks!" />
</TextBlock>
</Grid> </TextBlock>
</Window> <TextBlock
Margin="10,0,10,10"
VerticalAlignment="Bottom"
Height="22.42"
TextWrapping="Wrap"
FontWeight="Bold">
<Run
Text="WPF NotifyIcon is free software, released under the" />
<Run
Text=" " />
<Hyperlink
NavigateUri="http://www.codeproject.com/info/cpol10.aspx">
<Run
Text="CodeProject Open License" />
</Hyperlink>
</TextBlock>
<Path
Fill="#FFFFFFFF"
Stretch="Fill"
Stroke="#FF60758A"
Margin="11,0,17.926,41"
VerticalAlignment="Bottom"
Height="1"
Data="M11,517 L561.07363,517" Opacity="0.33" />
<Button
Margin="11,429,0,0"
Content="Events"
VerticalAlignment="Top"
Height="27"
x:Name="btnEvents"
Click="btnEvents_Click" Width="164" HorizontalAlignment="Left" />
<Button
HorizontalAlignment="Left"
Margin="10,392,0,0"
Width="164"
Content="Data Binding"
VerticalAlignment="Top"
Height="27"
x:Name="btnDataBinding"
Click="btnDataBinding_Click" />
</Grid>
</Window>

View File

@@ -11,90 +11,90 @@ using Samples.Tutorials.ToolTips;
namespace Samples namespace Samples
{ {
/// <summary>
/// Interaction logic for Main.xaml
/// </summary>
public partial class Main : Window
{
public Main()
{
InitializeComponent();
}
/// <summary> /// <summary>
/// Sets <see cref="Window.WindowStartupLocation"/> and /// Interaction logic for Main.xaml
/// <see cref="Window.Owner"/> properties of a dialog that
/// is about to be displayed.
/// </summary> /// </summary>
/// <param name="window">The processed window.</param> public partial class Main : Window
private void ShowDialog(Window window)
{ {
window.Owner = this; public Main()
window.WindowStartupLocation = WindowStartupLocation.CenterOwner; {
window.ShowDialog(); InitializeComponent();
}
/// <summary>
/// Sets <see cref="Window.WindowStartupLocation"/> and
/// <see cref="Window.Owner"/> properties of a dialog that
/// is about to be displayed.
/// </summary>
/// <param name="window">The processed window.</param>
private void ShowDialog(Window window)
{
window.Owner = this;
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
window.ShowDialog();
}
private void btnDeclaration_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new SimpleWindowWithNotifyIcon());
}
private void btnInlineToolTip_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlineToolTipWindow());
}
private void btnToolTipControl_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new UserControlToolTipWindow());
}
private void btnPopups_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlinePopupWindow());
}
private void btnContextMenus_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlineContextMenuWindow());
}
private void btnBalloons_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new BalloonSampleWindow());
}
private void btnCommands_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new CommandWindow());
}
private void btnEvents_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new EventVisualizerWindow());
}
private void btnDataBinding_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new DataBoundToolTipWindow());
}
private void btnMainSample_Click(object sender, RoutedEventArgs e)
{
var sampleWindow = new ShowcaseWindow();
sampleWindow.Owner = this;
sampleWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
sampleWindow.ShowDialog();
}
private void OnNavigationRequest(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
} }
private void btnDeclaration_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new SimpleWindowWithNotifyIcon());
}
private void btnInlineToolTip_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlineToolTipWindow());
}
private void btnToolTipControl_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new UserControlToolTipWindow());
}
private void btnPopups_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlinePopupWindow());
}
private void btnContextMenus_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new InlineContextMenuWindow());
}
private void btnBalloons_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new BalloonSampleWindow());
}
private void btnCommands_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new CommandWindow());
}
private void btnEvents_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new EventVisualizerWindow());
}
private void btnDataBinding_Click(object sender, RoutedEventArgs e)
{
ShowDialog(new DataBoundToolTipWindow());
}
private void btnMainSample_Click(object sender, RoutedEventArgs e)
{
var sampleWindow = new ShowcaseWindow();
sampleWindow.Owner = this;
sampleWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
sampleWindow.ShowDialog();
}
private void OnNavigationRequest(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
}
} }

View File

@@ -7,6 +7,7 @@ using System.Windows;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Sample Project")] [assembly: AssemblyTitle("Sample Project")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -19,6 +20,7 @@ using System.Windows;
// Setting ComVisible to false makes the types in this assembly not visible // 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 // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
//In order to begin building localizable applications, set //In order to begin building localizable applications, set
@@ -33,12 +35,12 @@ using System.Windows;
[assembly: ThemeInfo( [assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// or application resource dictionaries) // or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries) // app, or any theme specific resource dictionaries)
)] )]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
@@ -51,5 +53,6 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> <SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles> <Profiles>
<Profile Name="(Default)" /> <Profile Name="(Default)" />

View File

@@ -115,9 +115,13 @@
<TextBlock Margin="72,49.2,10,0" <TextBlock Margin="72,49.2,10,0"
VerticalAlignment="Top" VerticalAlignment="Top"
Foreground="#FFECAD25" Foreground="#FFECAD25"
TextWrapping="Wrap"><Run Text="This is a user control. The animation uses the attached "/><Run FontStyle="Italic" TextWrapping="Wrap">
FontWeight="Bold" <Run Text="This is a user control. The animation uses the attached " />
Text="BalloonShowing "/><Run Text="event."/></TextBlock> <Run FontStyle="Italic"
FontWeight="Bold"
Text="BalloonShowing " />
<Run Text="event." />
</TextBlock>
<Path Fill="#FFFFFFFF" <Path Fill="#FFFFFFFF"
Stretch="Fill" Stretch="Fill"
Margin="72,38.2,34,0" Margin="72,38.2,34,0"
@@ -155,4 +159,4 @@
MouseDown="imgClose_MouseDown" /> MouseDown="imgClose_MouseDown" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -17,92 +17,91 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples namespace Samples
{ {
/// <summary>
/// Interaction logic for FancyBalloon.xaml
/// </summary>
public partial class FancyBalloon : UserControl
{
private bool isClosing = false;
#region BalloonText dependency property
/// <summary> /// <summary>
/// Description /// Interaction logic for FancyBalloon.xaml
/// </summary> /// </summary>
public static readonly DependencyProperty BalloonTextProperty = public partial class FancyBalloon : UserControl
DependencyProperty.Register("BalloonText",
typeof (string),
typeof (FancyBalloon),
new FrameworkPropertyMetadata(""));
/// <summary>
/// A property wrapper for the <see cref="BalloonTextProperty"/>
/// dependency property:<br/>
/// Description
/// </summary>
public string BalloonText
{ {
get { return (string) GetValue(BalloonTextProperty); } private bool isClosing = false;
set { SetValue(BalloonTextProperty, value); }
#region BalloonText dependency property
/// <summary>
/// Description
/// </summary>
public static readonly DependencyProperty BalloonTextProperty =
DependencyProperty.Register("BalloonText",
typeof (string),
typeof (FancyBalloon),
new FrameworkPropertyMetadata(""));
/// <summary>
/// A property wrapper for the <see cref="BalloonTextProperty"/>
/// dependency property:<br/>
/// Description
/// </summary>
public string BalloonText
{
get { return (string) GetValue(BalloonTextProperty); }
set { SetValue(BalloonTextProperty, value); }
}
#endregion
public FancyBalloon()
{
InitializeComponent();
TaskbarIcon.AddBalloonClosingHandler(this, OnBalloonClosing);
}
/// <summary>
/// By subscribing to the <see cref="TaskbarIcon.BalloonClosingEvent"/>
/// and setting the "Handled" property to true, we suppress the popup
/// from being closed in order to display the custom fade-out animation.
/// </summary>
private void OnBalloonClosing(object sender, RoutedEventArgs e)
{
e.Handled = true; //suppresses the popup from being closed immediately
isClosing = true;
}
/// <summary>
/// Resolves the <see cref="TaskbarIcon"/> that displayed
/// the balloon and requests a close action.
/// </summary>
private void imgClose_MouseDown(object sender, MouseButtonEventArgs e)
{
//the tray icon assigned this attached property to simplify access
TaskbarIcon taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.CloseBalloon();
}
/// <summary>
/// If the users hovers over the balloon, we don't close it.
/// </summary>
private void grid_MouseEnter(object sender, MouseEventArgs e)
{
//if we're already running the fade-out animation, do not interrupt anymore
//(makes things too complicated for the sample)
if (isClosing) return;
//the tray icon assigned this attached property to simplify access
TaskbarIcon taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.ResetBalloonCloseTimer();
}
/// <summary>
/// Closes the popup once the fade-out animation completed.
/// The animation was triggered in XAML through the attached
/// BalloonClosing event.
/// </summary>
private void OnFadeOutCompleted(object sender, EventArgs e)
{
Popup pp = (Popup) Parent;
pp.IsOpen = false;
}
} }
}
#endregion
public FancyBalloon()
{
InitializeComponent();
TaskbarIcon.AddBalloonClosingHandler(this, OnBalloonClosing);
}
/// <summary>
/// By subscribing to the <see cref="TaskbarIcon.BalloonClosingEvent"/>
/// and setting the "Handled" property to true, we suppress the popup
/// from being closed in order to display the custom fade-out animation.
/// </summary>
private void OnBalloonClosing(object sender, RoutedEventArgs e)
{
e.Handled = true; //suppresses the popup from being closed immediately
isClosing = true;
}
/// <summary>
/// Resolves the <see cref="TaskbarIcon"/> that displayed
/// the balloon and requests a close action.
/// </summary>
private void imgClose_MouseDown(object sender, MouseButtonEventArgs e)
{
//the tray icon assigned this attached property to simplify access
TaskbarIcon taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.CloseBalloon();
}
/// <summary>
/// If the users hovers over the balloon, we don't close it.
/// </summary>
private void grid_MouseEnter(object sender, MouseEventArgs e)
{
//if we're already running the fade-out animation, do not interrupt anymore
//(makes things too complicated for the sample)
if (isClosing) return;
//the tray icon assigned this attached property to simplify access
TaskbarIcon taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.ResetBalloonCloseTimer();
}
/// <summary>
/// Closes the popup once the fade-out animation completed.
/// The animation was triggered in XAML through the attached
/// BalloonClosing event.
/// </summary>
private void OnFadeOutCompleted(object sender, EventArgs e)
{
Popup pp = (Popup)Parent;
pp.IsOpen = false;
}
}
}

View File

@@ -3,44 +3,44 @@ using System.Windows.Controls;
namespace Samples namespace Samples
{ {
/// <summary>
/// Interaction logic for FancyPopup.xaml
/// </summary>
public partial class FancyPopup : UserControl
{
#region ClickCount dependency property
/// <summary> /// <summary>
/// The number of clicks on the popup button. /// Interaction logic for FancyPopup.xaml
/// </summary> /// </summary>
public static readonly DependencyProperty ClickCountProperty = public partial class FancyPopup : UserControl
DependencyProperty.Register("ClickCount",
typeof (int),
typeof (FancyPopup),
new FrameworkPropertyMetadata(0));
/// <summary>
/// A property wrapper for the <see cref="ClickCountProperty"/>
/// dependency property:<br/>
/// The number of clicks on the popup button.
/// </summary>
public int ClickCount
{ {
get { return (int) GetValue(ClickCountProperty); } #region ClickCount dependency property
set { SetValue(ClickCountProperty, value); }
}
#endregion /// <summary>
/// The number of clicks on the popup button.
/// </summary>
public static readonly DependencyProperty ClickCountProperty =
DependencyProperty.Register("ClickCount",
typeof (int),
typeof (FancyPopup),
new FrameworkPropertyMetadata(0));
public FancyPopup() /// <summary>
{ /// A property wrapper for the <see cref="ClickCountProperty"/>
InitializeComponent(); /// dependency property:<br/>
} /// The number of clicks on the popup button.
/// </summary>
public int ClickCount
{
get { return (int) GetValue(ClickCountProperty); }
set { SetValue(ClickCountProperty, value); }
}
private void OnButtonClick(object sender, RoutedEventArgs e) #endregion
{
//just increment a counter - will be displayed on screen public FancyPopup()
ClickCount++; {
InitializeComponent();
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
//just increment a counter - will be displayed on screen
ClickCount++;
}
} }
}
} }

View File

@@ -14,41 +14,38 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples namespace Samples
{ {
/// <summary> /// <summary>
/// Interaction logic for FancyToolTip.xaml /// Interaction logic for FancyToolTip.xaml
/// </summary> /// </summary>
public partial class FancyToolTip public partial class FancyToolTip
{ {
#region InfoText dependency property #region InfoText dependency property
/// <summary> /// <summary>
/// The tooltip details. /// The tooltip details.
/// </summary> /// </summary>
public static readonly DependencyProperty InfoTextProperty = public static readonly DependencyProperty InfoTextProperty =
DependencyProperty.Register("InfoText", DependencyProperty.Register("InfoText",
typeof (string), typeof (string),
typeof (FancyToolTip), typeof (FancyToolTip),
new FrameworkPropertyMetadata("")); new FrameworkPropertyMetadata(""));
/// <summary> /// <summary>
/// A property wrapper for the <see cref="InfoTextProperty"/> /// A property wrapper for the <see cref="InfoTextProperty"/>
/// dependency property:<br/> /// dependency property:<br/>
/// The tooltip details. /// The tooltip details.
/// </summary> /// </summary>
public string InfoText public string InfoText
{ {
get { return (string) GetValue(InfoTextProperty); } get { return (string) GetValue(InfoTextProperty); }
set { SetValue(InfoTextProperty, value); } set { SetValue(InfoTextProperty, value); }
} }
#endregion #endregion
public FancyToolTip()
{
public FancyToolTip() this.InitializeComponent();
{ }
this.InitializeComponent(); }
}
}
} }

View File

@@ -22,9 +22,10 @@
<Border Background="{DynamicResource MenuBackground}" <Border Background="{DynamicResource MenuBackground}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}" <ScrollViewer
Uid="ScrollViewer_9" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"
CanContentScroll="True"> Uid="ScrollViewer_9"
CanContentScroll="True">
<ItemsPresenter Margin="{TemplateBinding Padding}" <ItemsPresenter Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.DirectionalNavigation="Cycle" /> KeyboardNavigation.DirectionalNavigation="Cycle" />

File diff suppressed because it is too large Load Diff

View File

@@ -6,88 +6,87 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples namespace Samples
{ {
/// <summary>
/// Interaction logic for ShowcaseWindow.xaml
/// </summary>
public partial class ShowcaseWindow : Window
{
public ShowcaseWindow()
{
InitializeComponent();
Loaded += delegate
{
//show balloon at startup
var balloon = new WelcomeBalloon();
tb.ShowCustomBalloon(balloon, PopupAnimation.Slide, 12000);
};
}
/// <summary> /// <summary>
/// Displays a balloon tip. /// Interaction logic for ShowcaseWindow.xaml
/// </summary> /// </summary>
private void showBalloonTip_Click(object sender, RoutedEventArgs e) public partial class ShowcaseWindow : Window
{ {
string title = txtBalloonTitle.Text; public ShowcaseWindow()
string message = txtBalloonText.Text; {
InitializeComponent();
if (rbCustomIcon.IsChecked == true)
{ Loaded += delegate
//just display the icon on the tray {
var icon = tb.Icon; //show balloon at startup
tb.ShowBalloonTip(title, message, icon); var balloon = new WelcomeBalloon();
} tb.ShowCustomBalloon(balloon, PopupAnimation.Slide, 12000);
else };
{ }
BalloonIcon bi = rbInfo.IsChecked == true ? BalloonIcon.Info : BalloonIcon.Error;
tb.ShowBalloonTip(title, message, bi);
} /// <summary>
/// Displays a balloon tip.
/// </summary>
private void showBalloonTip_Click(object sender, RoutedEventArgs e)
{
string title = txtBalloonTitle.Text;
string message = txtBalloonText.Text;
if (rbCustomIcon.IsChecked == true)
{
//just display the icon on the tray
var icon = tb.Icon;
tb.ShowBalloonTip(title, message, icon);
}
else
{
BalloonIcon bi = rbInfo.IsChecked == true ? BalloonIcon.Info : BalloonIcon.Error;
tb.ShowBalloonTip(title, message, bi);
}
}
private void hideBalloonTip_Click(object sender, RoutedEventArgs e)
{
tb.HideBalloonTip();
}
/// <summary>
/// Resets the tooltip.
/// </summary>
private void removeToolTip_Click(object sender, RoutedEventArgs e)
{
tb.TrayToolTip = null;
}
private void showCustomBalloon_Click(object sender, RoutedEventArgs e)
{
FancyBalloon balloon = new FancyBalloon();
balloon.BalloonText = customBalloonTitle.Text;
//show and close after 2.5 seconds
tb.ShowCustomBalloon(balloon, PopupAnimation.Slide, 5000);
}
private void hideCustomBalloon_Click(object sender, RoutedEventArgs e)
{
tb.CloseBalloon();
}
private void OnNavigationRequest(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
tb.Dispose();
base.OnClosing(e);
}
} }
private void hideBalloonTip_Click(object sender, RoutedEventArgs e)
{
tb.HideBalloonTip();
}
/// <summary>
/// Resets the tooltip.
/// </summary>
private void removeToolTip_Click(object sender, RoutedEventArgs e)
{
tb.TrayToolTip = null;
}
private void showCustomBalloon_Click(object sender, RoutedEventArgs e)
{
FancyBalloon balloon = new FancyBalloon();
balloon.BalloonText = customBalloonTitle.Text;
//show and close after 2.5 seconds
tb.ShowCustomBalloon(balloon, PopupAnimation.Slide, 5000);
}
private void hideCustomBalloon_Click(object sender, RoutedEventArgs e)
{
tb.CloseBalloon();
}
private void OnNavigationRequest(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
tb.Dispose();
base.OnClosing(e);
}
}
} }

View File

@@ -1,93 +1,105 @@
<UserControl <UserControl
x:Class="Samples.WelcomeBalloon" x:Class="Samples.WelcomeBalloon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="130" Height="130"
Width="283" Width="283"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
x:Name="me"> x:Name="me">
<UserControl.Resources> <UserControl.Resources>
<Storyboard <Storyboard
x:Key="FadeInAndOut"> x:Key="FadeInAndOut">
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="grid" Storyboard.TargetName="grid"
Storyboard.TargetProperty="(UIElement.Opacity)"> Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="0" /> Value="0" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:01" KeyTime="00:00:01"
Value="0.895" /> Value="0.895" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:10" KeyTime="00:00:10"
Value="0.895" /> Value="0.895" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:11.6000000" KeyTime="00:00:11.6000000"
Value="0" /> Value="0" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
</Storyboard> </Storyboard>
</UserControl.Resources> </UserControl.Resources>
<UserControl.Triggers> <UserControl.Triggers>
<EventTrigger <EventTrigger
RoutedEvent="tb:TaskbarIcon.BalloonShowing"> RoutedEvent="tb:TaskbarIcon.BalloonShowing">
<BeginStoryboard <BeginStoryboard
Storyboard="{StaticResource FadeInAndOut}" Storyboard="{StaticResource FadeInAndOut}"
x:Name="FadeInAndOut_BeginStoryboard" /> x:Name="FadeInAndOut_BeginStoryboard" />
</EventTrigger> </EventTrigger>
</UserControl.Triggers> </UserControl.Triggers>
<Grid <Grid
x:Name="grid"> x:Name="grid">
<Border <Border
x:Name="border" x:Name="border"
CornerRadius="10,10,10,10" CornerRadius="10,10,10,10"
Margin="0,0,5,5"> Margin="0,0,5,5">
<Border.Background> <Border.Background>
<LinearGradientBrush <LinearGradientBrush
EndPoint="0.5,1" EndPoint="0.5,1"
StartPoint="0.5,0"> StartPoint="0.5,0">
<GradientStop <GradientStop
Color="#FFEEEEEE" Color="#FFEEEEEE"
Offset="1" /> Offset="1" />
<GradientStop <GradientStop
Color="#FFFB6B42" Color="#FFFB6B42"
Offset="0" /> Offset="0" />
</LinearGradientBrush> </LinearGradientBrush>
</Border.Background> </Border.Background>
<Border.Effect> <Border.Effect>
<DropShadowEffect /> <DropShadowEffect />
</Border.Effect> </Border.Effect>
</Border> </Border>
<TextBlock <TextBlock
Margin="10,10,15,0" Margin="10,10,15,0"
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="14" FontSize="14"
FontWeight="Bold" FontWeight="Bold"
TextWrapping="Wrap" TextWrapping="Wrap"
HorizontalAlignment="Center"><Run HorizontalAlignment="Center">
Text="WPF NotifyIcon - Sample Application" <Run
Language="de-ch" /></TextBlock> Text="WPF NotifyIcon - Sample Application"
<TextBlock Language="de-ch" />
Margin="10,38.62,10,0" </TextBlock>
VerticalAlignment="Top" <TextBlock
TextWrapping="Wrap" Margin="10,38.62,10,0"
HorizontalAlignment="Left"><Run VerticalAlignment="Top"
Text="You should see this icon in your system tray:" /><Run TextWrapping="Wrap"
Text=" " /><InlineUIContainer> HorizontalAlignment="Left">
<Image <Run
Source="{Binding Path=IconSource}" Text="You should see this icon in your system tray:" />
Width="16" <Run
Height="16" /> Text=" " />
</InlineUIContainer><LineBreak /><Run <InlineUIContainer>
Text="This is your NotifyIcon." /><LineBreak /><Run <Image
Text="" /><LineBreak /><Run Source="{Binding Path=IconSource}"
FontSize="10" Width="16"
FontStyle="Italic" Height="16" />
Text="You can change the displayed icon by selecting another image in the sample window." /></TextBlock> </InlineUIContainer>
<LineBreak />
<Run
Text="This is your NotifyIcon." />
<LineBreak />
<Run
Text="" />
<LineBreak />
<Run
FontSize="10"
FontStyle="Italic"
Text="You can change the displayed icon by selecting another image in the sample window." />
</TextBlock>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -14,14 +14,14 @@ using System.Windows.Shapes;
namespace Samples namespace Samples
{ {
/// <summary> /// <summary>
/// Interaction logic for WelcomeBalloon.xaml /// Interaction logic for WelcomeBalloon.xaml
/// </summary> /// </summary>
public partial class WelcomeBalloon : UserControl public partial class WelcomeBalloon : UserControl
{
public WelcomeBalloon()
{ {
InitializeComponent(); public WelcomeBalloon()
{
InitializeComponent();
}
} }
} }
}

View File

@@ -1,19 +1,21 @@
<Window <Window
x:Class="Samples.Tutorials.SimpleWindowWithNotifyIcon" x:Class="Samples.Tutorials.SimpleWindowWithNotifyIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="300"> Width="300">
<Grid> <Grid>
<!-- in order to declare a NotifyIcon, all you need is the <!-- in order to declare a NotifyIcon, all you need is the
namespace declaration (see above on line 5) and a single line --> namespace declaration (see above on line 5) and a single line -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon" x:Name="MyNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="hello world" /> ToolTipText="hello world" />
<TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap"><Run Text="You should see an icon in the tray." Language="de-ch"/></TextBlock> <TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap">
<Run Text="You should see an icon in the tray." Language="de-ch" />
</TextBlock>
</Grid> </Grid>
</Window> </Window>

View File

@@ -2,22 +2,22 @@
namespace Samples.Tutorials namespace Samples.Tutorials
{ {
/// <summary> /// <summary>
/// Interaction logic for SimpleWindowWithNotifyIcon.xaml /// Interaction logic for SimpleWindowWithNotifyIcon.xaml
/// </summary> /// </summary>
public partial class SimpleWindowWithNotifyIcon : Window public partial class SimpleWindowWithNotifyIcon : Window
{
public SimpleWindowWithNotifyIcon()
{ {
InitializeComponent(); public SimpleWindowWithNotifyIcon()
} {
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{ {
//clean up notifyicon (would otherwise stay open until application finishes) //clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose(); MyNotifyIcon.Dispose();
base.OnClosing(e); base.OnClosing(e);
}
} }
}
} }

View File

@@ -1,40 +1,41 @@
<Window <Window
x:Class="Samples.Tutorials.ToolTips.InlineToolTipWindow" x:Class="Samples.Tutorials.ToolTips.InlineToolTipWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="300"> Width="300">
<Grid> <Grid>
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon" x:Name="MyNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="hello world"> ToolTipText="hello world">
<!-- <!--
We can use arbitrary UI elements as ToolTips. We can use arbitrary UI elements as ToolTips.
Let's use a semi-transparent border. Let's use a semi-transparent border.
--> -->
<tb:TaskbarIcon.TrayToolTip> <tb:TaskbarIcon.TrayToolTip>
<Border <Border
Background="White" Background="White"
BorderBrush="Orange" BorderBrush="Orange"
BorderThickness="2" BorderThickness="2"
CornerRadius="4" CornerRadius="4"
Opacity="0.8" Opacity="0.8"
Width="160" Width="160"
Height="40"> Height="40">
<TextBlock <TextBlock
Text="hello world" Text="hello world"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center" />
/> </Border>
</Border> </tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon>
<TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap"><Run Text="Move mouse over NotifyIcon to show ToolTip" Language="de-ch"/></TextBlock>
</Grid> </tb:TaskbarIcon>
</Window> <TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap">
<Run Text="Move mouse over NotifyIcon to show ToolTip" Language="de-ch" />
</TextBlock>
</Grid>
</Window>

View File

@@ -13,22 +13,22 @@ using System.Windows.Shapes;
namespace Samples.Tutorials.ToolTips namespace Samples.Tutorials.ToolTips
{ {
/// <summary> /// <summary>
/// Interaction logic for Window1.xaml /// Interaction logic for Window1.xaml
/// </summary> /// </summary>
public partial class InlineToolTipWindow : Window public partial class InlineToolTipWindow : Window
{
public InlineToolTipWindow()
{ {
InitializeComponent(); public InlineToolTipWindow()
} {
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{ {
//clean up notifyicon (would otherwise stay open until application finishes) //clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose(); MyNotifyIcon.Dispose();
base.OnClosing(e); base.OnClosing(e);
}
} }
} }
}

View File

@@ -1,22 +1,21 @@
<UserControl <UserControl
x:Class="Samples.Tutorials.ToolTips.SimpleUserControl" x:Class="Samples.Tutorials.ToolTips.SimpleUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
>
<!-- a simple user control which displays a fixed text within a border --> <!-- a simple user control which displays a fixed text within a border -->
<Border <Border
Background="White" Background="White"
BorderBrush="Orange" BorderBrush="Orange"
BorderThickness="2" BorderThickness="2"
CornerRadius="4" CornerRadius="4"
Opacity="0.8" Opacity="0.8"
Width="160" Width="160"
Height="40"> Height="40">
<TextBlock <TextBlock
Text="hello world" Text="hello world"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</Border> </Border>
</UserControl> </UserControl>

View File

@@ -14,14 +14,14 @@ using System.Windows.Shapes;
namespace Samples.Tutorials.ToolTips namespace Samples.Tutorials.ToolTips
{ {
/// <summary> /// <summary>
/// Interaction logic for SimpleUserControl.xaml /// Interaction logic for SimpleUserControl.xaml
/// </summary> /// </summary>
public partial class SimpleUserControl : UserControl public partial class SimpleUserControl : UserControl
{
public SimpleUserControl()
{ {
InitializeComponent(); public SimpleUserControl()
{
InitializeComponent();
}
} }
} }
}

View File

@@ -1,25 +1,27 @@
<Window <Window
x:Class="Samples.Tutorials.ToolTips.UserControlToolTipWindow" x:Class="Samples.Tutorials.ToolTips.UserControlToolTipWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:local="clr-namespace:Samples.Tutorials.ToolTips" xmlns:local="clr-namespace:Samples.Tutorials.ToolTips"
Height="300" Height="300"
Width="300"> Width="300">
<Grid> <Grid>
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon" x:Name="MyNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="hello world"> ToolTipText="hello world">
<!-- assign user control as ToolTip --> <!-- assign user control as ToolTip -->
<tb:TaskbarIcon.TrayToolTip> <tb:TaskbarIcon.TrayToolTip>
<local:SimpleUserControl /> <local:SimpleUserControl />
</tb:TaskbarIcon.TrayToolTip> </tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon> </tb:TaskbarIcon>
<TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap"><Run Text="Move mouse over NotifyIcon to show ToolTip" Language="de-ch"/></TextBlock> <TextBlock Margin="26,26,24,0" VerticalAlignment="Top" FontWeight="Bold" TextWrapping="Wrap">
<Run Text="Move mouse over NotifyIcon to show ToolTip" Language="de-ch" />
</TextBlock>
</Grid> </Grid>
</Window> </Window>

View File

@@ -13,22 +13,22 @@ using System.Windows.Shapes;
namespace Samples.Tutorials.ToolTips namespace Samples.Tutorials.ToolTips
{ {
/// <summary> /// <summary>
/// Interaction logic for UserControlToolTipWindow.xaml /// Interaction logic for UserControlToolTipWindow.xaml
/// </summary> /// </summary>
public partial class UserControlToolTipWindow : Window public partial class UserControlToolTipWindow : Window
{
public UserControlToolTipWindow()
{ {
InitializeComponent(); public UserControlToolTipWindow()
} {
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{ {
//clean up notifyicon (would otherwise stay open until application finishes) //clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose(); MyNotifyIcon.Dispose();
base.OnClosing(e); base.OnClosing(e);
}
} }
} }
}

View File

@@ -1,58 +1,58 @@
<Window <Window
x:Class="Samples.Tutorials.Popups.InlinePopupWindow" x:Class="Samples.Tutorials.Popups.InlinePopupWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="300"> Width="300">
<Grid> <Grid>
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon" x:Name="MyNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="hello world"> ToolTipText="hello world">
<!-- <!--
We can use arbitrary UI elements as Popups. We can use arbitrary UI elements as Popups.
Popups stay open if the user moves away from the tray area Popups stay open if the user moves away from the tray area
--> -->
<tb:TaskbarIcon.TrayPopup> <tb:TaskbarIcon.TrayPopup>
<Border <Border
Background="White" Background="White"
BorderBrush="Orange" BorderBrush="Orange"
BorderThickness="2" BorderThickness="2"
CornerRadius="4" CornerRadius="4"
Width="160"> Width="160">
<StackPanel> <StackPanel>
<TextBox <TextBox
x:Name="popupText" x:Name="popupText"
Margin="5,10,5,10" Margin="5,10,5,10"
Width="200" Width="200"
Height="24" Height="24"
Text="Enter Text..." /> Text="Enter Text..." />
<Button <Button
Content="Click Me!" Content="Click Me!"
Margin="5,0,5,10" Margin="5,0,5,10"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</StackPanel> </StackPanel>
</Border> </Border>
</tb:TaskbarIcon.TrayPopup> </tb:TaskbarIcon.TrayPopup>
</tb:TaskbarIcon> </tb:TaskbarIcon>
<TextBlock <TextBlock
Margin="26,26,24,0" Margin="26,26,24,0"
VerticalAlignment="Top" VerticalAlignment="Top"
FontWeight="Bold" FontWeight="Bold"
Text="Left-Click NotifyIcon to open popup." /> Text="Left-Click NotifyIcon to open popup." />
<TextBlock
Text="Text on Popup: "
Margin="26,66,24,0"
VerticalAlignment="Top">
<TextBlock Foreground="Red"
Text="{Binding ElementName=popupText, Path=Text}" />
</TextBlock>
</Grid> <TextBlock
Text="Text on Popup: "
Margin="26,66,24,0"
VerticalAlignment="Top">
<TextBlock Foreground="Red"
Text="{Binding ElementName=popupText, Path=Text}" />
</TextBlock>
</Grid>
</Window> </Window>

View File

@@ -13,22 +13,22 @@ using System.Windows.Shapes;
namespace Samples.Tutorials.Popups namespace Samples.Tutorials.Popups
{ {
/// <summary> /// <summary>
/// Interaction logic for InlinePopupWindow.xaml /// Interaction logic for InlinePopupWindow.xaml
/// </summary> /// </summary>
public partial class InlinePopupWindow : Window public partial class InlinePopupWindow : Window
{
public InlinePopupWindow()
{ {
InitializeComponent(); public InlinePopupWindow()
} {
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{ {
//clean up notifyicon (would otherwise stay open until application finishes) //clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose(); MyNotifyIcon.Dispose();
base.OnClosing(e); base.OnClosing(e);
}
} }
} }
}

View File

@@ -46,8 +46,10 @@
<TextBlock Margin="26,26,24,0" <TextBlock Margin="26,26,24,0"
VerticalAlignment="Top" VerticalAlignment="Top"
FontWeight="Bold" FontWeight="Bold"
TextWrapping="Wrap"><Run Language="de-ch" TextWrapping="Wrap">
Text="Right-click on NotifyIcon to open Context Menu" /></TextBlock> <Run Language="de-ch"
Text="Right-click on NotifyIcon to open Context Menu" />
</TextBlock>
<TextBlock HorizontalAlignment="Left" <TextBlock HorizontalAlignment="Left"
Margin="26,83,0,0" Margin="26,83,0,0"
TextWrapping="Wrap" TextWrapping="Wrap"

View File

@@ -32,7 +32,7 @@ namespace Samples.Tutorials.ContextMenus
private void MyNotifyIcon_PreviewTrayContextMenuOpen(object sender, System.Windows.RoutedEventArgs e) private void MyNotifyIcon_PreviewTrayContextMenuOpen(object sender, System.Windows.RoutedEventArgs e)
{ {
//marking the event as handled suppresses the context menu //marking the event as handled suppresses the context menu
e.Handled = (bool)SuppressContextMenu.IsChecked; e.Handled = (bool) SuppressContextMenu.IsChecked;
PreviewOpenEventCounter.Text = (int.Parse(PreviewOpenEventCounter.Text) + 1).ToString(); PreviewOpenEventCounter.Text = (int.Parse(PreviewOpenEventCounter.Text) + 1).ToString();
} }

View File

@@ -1,54 +1,51 @@
<Window <Window
x:Class="Samples.Tutorials.Balloons.BalloonSampleWindow" x:Class="Samples.Tutorials.Balloons.BalloonSampleWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="300"> Width="300">
<Grid> <Grid>
<!-- the ToolTipText property is bound to the TextBox below --> <!-- the ToolTipText property is bound to the TextBox below -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon" x:Name="MyNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="Balloon Sample Icon" /> ToolTipText="Balloon Sample Icon" />
<Button <Button
x:Name="btnShowStandardBalloon" x:Name="btnShowStandardBalloon"
Click="btnShowStandardBalloon_Click" Click="btnShowStandardBalloon_Click"
Margin="26,74,29,0" Margin="26,74,29,0"
Content="Show Standard Balloon" Height="29" VerticalAlignment="Top" Content="Show Standard Balloon" Height="29" VerticalAlignment="Top" />
/> <Button
<Button x:Name="btnShowCustomBalloon"
x:Name="btnShowCustomBalloon" Click="btnShowCustomBalloon_Click"
Click="btnShowCustomBalloon_Click" Margin="26,0,29,49"
Margin="26,0,29,49" VerticalAlignment="Bottom"
VerticalAlignment="Bottom" Height="27"
Height="27" Content="Show Custom Balloon" />
Content="Show Custom Balloon" <TextBlock
/> Margin="26,26,24,0"
<TextBlock VerticalAlignment="Top"
Margin="26,26,24,0" FontWeight="Bold"
VerticalAlignment="Top" TextWrapping="Wrap">
FontWeight="Bold" <Run
TextWrapping="Wrap"><Run Language="de-ch"
Language="de-ch" Text="Clicking on buttons shows balloon tips" />
Text="Clicking on buttons shows balloon tips" /></TextBlock> </TextBlock>
<Button <Button
x:Name="btnHideStandardBalloon" x:Name="btnHideStandardBalloon"
Click="btnHideStandardBalloon_Click" Click="btnHideStandardBalloon_Click"
Margin="26,113,29,122" Margin="26,113,29,122"
Content="Hide Standard Balloon" Content="Hide Standard Balloon" />
/> <Button
<Button x:Name="btnCloseCustomBalloon"
x:Name="btnCloseCustomBalloon" Click="btnCloseCustomBalloon_Click"
Click="btnCloseCustomBalloon_Click" Margin="26,0,29,12"
Margin="26,0,29,12" VerticalAlignment="Bottom"
VerticalAlignment="Bottom" Height="27"
Height="27" Content="Close Custom Balloon" />
Content="Close Custom Balloon"
/>
</Grid>
</Grid> </Window>
</Window>

View File

@@ -15,53 +15,51 @@ using Hardcodet.Wpf.TaskbarNotification;
namespace Samples.Tutorials.Balloons namespace Samples.Tutorials.Balloons
{ {
/// <summary> /// <summary>
/// Interaction logic for BalloonSampleWindow.xaml /// Interaction logic for BalloonSampleWindow.xaml
/// </summary> /// </summary>
public partial class BalloonSampleWindow : Window public partial class BalloonSampleWindow : Window
{
public BalloonSampleWindow()
{ {
InitializeComponent(); public BalloonSampleWindow()
{
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose();
base.OnClosing(e);
}
private void btnShowCustomBalloon_Click(object sender, RoutedEventArgs e)
{
FancyBalloon balloon = new FancyBalloon();
balloon.BalloonText = "Custom Balloon";
//show balloon and close it after 4 seconds
MyNotifyIcon.ShowCustomBalloon(balloon, PopupAnimation.Slide, 4000);
}
private void btnHideStandardBalloon_Click(object sender, RoutedEventArgs e)
{
MyNotifyIcon.HideBalloonTip();
}
private void btnShowStandardBalloon_Click(object sender, RoutedEventArgs e)
{
string title = "WPF NotifyIcon";
string text = "This is a standard balloon";
MyNotifyIcon.ShowBalloonTip(title, text, MyNotifyIcon.Icon);
}
private void btnCloseCustomBalloon_Click(object sender, RoutedEventArgs e)
{
MyNotifyIcon.CloseBalloon();
}
} }
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon.Dispose();
base.OnClosing(e);
}
private void btnShowCustomBalloon_Click(object sender, RoutedEventArgs e)
{
FancyBalloon balloon = new FancyBalloon();
balloon.BalloonText = "Custom Balloon";
//show balloon and close it after 4 seconds
MyNotifyIcon.ShowCustomBalloon(balloon, PopupAnimation.Slide, 4000);
}
private void btnHideStandardBalloon_Click(object sender, RoutedEventArgs e)
{
MyNotifyIcon.HideBalloonTip();
}
private void btnShowStandardBalloon_Click(object sender, RoutedEventArgs e)
{
string title = "WPF NotifyIcon";
string text = "This is a standard balloon";
MyNotifyIcon.ShowBalloonTip(title, text, MyNotifyIcon.Icon);
}
private void btnCloseCustomBalloon_Click(object sender, RoutedEventArgs e)
{
MyNotifyIcon.CloseBalloon();
}
}
}

View File

@@ -1,58 +1,64 @@
<Window <Window
x:Class="Samples.Tutorials.Commands.CommandWindow" x:Class="Samples.Tutorials.Commands.CommandWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:local="clr-namespace:Samples.Tutorials.Commands" xmlns:local="clr-namespace:Samples.Tutorials.Commands"
Height="300" Height="300"
Width="300" Width="300"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Grid>
<!-- declare the command as a local resource --> <!-- declare the command as a local resource -->
<Grid.Resources> <Grid.Resources>
<local:ShowMessageCommand <local:ShowMessageCommand
x:Key="MessageCommand" /> x:Key="MessageCommand" />
</Grid.Resources> </Grid.Resources>
<!-- declare the NotifyIcon and configure commands with parameters --> <!-- declare the NotifyIcon and configure commands with parameters -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="CustomCommandNotifyIcon" x:Name="CustomCommandNotifyIcon"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
LeftClickCommand="{StaticResource MessageCommand}" LeftClickCommand="{StaticResource MessageCommand}"
LeftClickCommandParameter="Left mouse button was clicked" LeftClickCommandParameter="Left mouse button was clicked"
DoubleClickCommand="{StaticResource MessageCommand}" DoubleClickCommand="{StaticResource MessageCommand}"
DoubleClickCommandParameter="Double click on NotifyIcon" /> DoubleClickCommandParameter="Double click on NotifyIcon" />
<!-- declare the NotifyIcon and configure commands with targets --> <!-- declare the NotifyIcon and configure commands with targets -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="RoutedCommandNotifyIcon" x:Name="RoutedCommandNotifyIcon"
IconSource="/Icons/Inactive.ico" IconSource="/Icons/Inactive.ico"
LeftClickCommand="ApplicationCommands.Cut" LeftClickCommand="ApplicationCommands.Cut"
LeftClickCommandTarget="{Binding ElementName=txtInput}" LeftClickCommandTarget="{Binding ElementName=txtInput}"
DoubleClickCommand="ApplicationCommands.Paste" DoubleClickCommand="ApplicationCommands.Paste"
DoubleClickCommandTarget="{Binding ElementName=txtInput}" /> DoubleClickCommandTarget="{Binding ElementName=txtInput}" />
<TextBlock
Margin="26,26,24,0" <TextBlock
VerticalAlignment="Top" Margin="26,26,24,0"
FontWeight="Bold" VerticalAlignment="Top"
TextWrapping="Wrap"><Run FontWeight="Bold"
Language="de-ch" TextWrapping="Wrap">
Text="Left / Double clicks on red NotifyIcon executes simple custom commands." /></TextBlock> <Run
<TextBlock Language="de-ch"
Margin="26,112,24,80" Text="Left / Double clicks on red NotifyIcon executes simple custom commands." />
FontWeight="Bold" </TextBlock>
TextWrapping="Wrap"><Run Language="de-ch" Text="Left / Double clicks on grey NotifyIcon executes routed commands."/><LineBreak/><Run Language="de-ch" Text="Single click: Cuts selected text"/><LineBreak/><Run Language="de-ch" Text="Double click: Paste text from clipboard"/></TextBlock> <TextBlock
<TextBox Margin="26,112,24,80"
Margin="26,0,24,48" FontWeight="Bold"
VerticalAlignment="Bottom" TextWrapping="Wrap">
Height="22" <Run Language="de-ch" Text="Left / Double clicks on grey NotifyIcon executes routed commands." />
Text="hello world" <LineBreak /><Run Language="de-ch" Text="Single click: Cuts selected text" /><LineBreak />
TextWrapping="Wrap" <Run Language="de-ch" Text="Double click: Paste text from clipboard" />
x:Name="txtInput" /> </TextBlock>
</Grid> <TextBox
Margin="26,0,24,48"
VerticalAlignment="Bottom"
Height="22"
Text="hello world"
TextWrapping="Wrap"
x:Name="txtInput" />
</Grid>
</Window> </Window>

View File

@@ -13,24 +13,24 @@ using System.Windows.Shapes;
namespace Samples.Tutorials.Commands namespace Samples.Tutorials.Commands
{ {
/// <summary> /// <summary>
/// Interaction logic for CommandWindow.xaml /// Interaction logic for CommandWindow.xaml
/// </summary> /// </summary>
public partial class CommandWindow : Window public partial class CommandWindow : Window
{
public CommandWindow()
{ {
InitializeComponent(); public CommandWindow()
{
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
CustomCommandNotifyIcon.Dispose();
RoutedCommandNotifyIcon.Dispose();
base.OnClosing(e);
}
} }
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
CustomCommandNotifyIcon.Dispose();
RoutedCommandNotifyIcon.Dispose();
base.OnClosing(e);
}
}
}

View File

@@ -4,22 +4,22 @@ using System.Windows.Input;
namespace Samples.Tutorials.Commands namespace Samples.Tutorials.Commands
{ {
/// <summary> /// <summary>
/// A simple command that displays the command parameter as /// A simple command that displays the command parameter as
/// a dialog message. /// a dialog message.
/// </summary> /// </summary>
public class ShowMessageCommand : ICommand public class ShowMessageCommand : ICommand
{
public void Execute(object parameter)
{ {
MessageBox.Show(parameter.ToString()); public void Execute(object parameter)
} {
MessageBox.Show(parameter.ToString());
}
public bool CanExecute(object parameter) public bool CanExecute(object parameter)
{ {
return true; return true;
} }
public event EventHandler CanExecuteChanged; public event EventHandler CanExecuteChanged;
} }
} }

View File

@@ -1,259 +1,265 @@
<Window <Window
x:Class="Samples.Tutorials.Events.EventVisualizerWindow" x:Class="Samples.Tutorials.Events.EventVisualizerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="300"> Width="300">
<Window.Resources> <Window.Resources>
<Storyboard <Storyboard
x:Key="ShowMovement" x:Key="ShowMovement"
AutoReverse="True"> AutoReverse="True">
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="MoveIndicator" Storyboard.TargetName="MoveIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.1000000" KeyTime="00:00:00.1000000"
Value="1.2" /> Value="1.2" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="MoveIndicator" Storyboard.TargetName="MoveIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.1000000" KeyTime="00:00:00.1000000"
Value="1.2" /> Value="1.2" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
</Storyboard> </Storyboard>
<Storyboard <Storyboard
x:Key="ShowMouseUp" x:Key="ShowMouseUp"
AutoReverse="True"> AutoReverse="True">
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="LeftMouseIndicator" Storyboard.TargetName="LeftMouseIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.1000000" KeyTime="00:00:00.1000000"
Value="1.35" /> Value="1.35" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="LeftMouseIndicator" Storyboard.TargetName="LeftMouseIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.1000000" KeyTime="00:00:00.1000000"
Value="1.35" /> Value="1.35" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
</Storyboard> </Storyboard>
<Storyboard <Storyboard
x:Key="ShowToolTipOpened" x:Key="ShowToolTipOpened"
AutoReverse="True"> AutoReverse="True">
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="ToolTipIndicator" Storyboard.TargetName="ToolTipIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.2000000" KeyTime="00:00:00.2000000"
Value="1.4" /> Value="1.4" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames <DoubleAnimationUsingKeyFrames
BeginTime="00:00:00" BeginTime="00:00:00"
Storyboard.TargetName="ToolTipIndicator" Storyboard.TargetName="ToolTipIndicator"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00" KeyTime="00:00:00"
Value="1" /> Value="1" />
<SplineDoubleKeyFrame <SplineDoubleKeyFrame
KeyTime="00:00:00.2000000" KeyTime="00:00:00.2000000"
Value="1.4" /> Value="1.4" />
</DoubleAnimationUsingKeyFrames> </DoubleAnimationUsingKeyFrames>
</Storyboard> </Storyboard>
</Window.Resources> </Window.Resources>
<Window.Triggers> <Window.Triggers>
<EventTrigger <EventTrigger
RoutedEvent="tb:TaskbarIcon.TrayMouseMove" RoutedEvent="tb:TaskbarIcon.TrayMouseMove"
SourceName="notifyIcon"> SourceName="notifyIcon">
<BeginStoryboard <BeginStoryboard
Storyboard="{StaticResource ShowMovement}" /> Storyboard="{StaticResource ShowMovement}" />
</EventTrigger> </EventTrigger>
<EventTrigger <EventTrigger
RoutedEvent="tb:TaskbarIcon.TrayLeftMouseUp" RoutedEvent="tb:TaskbarIcon.TrayLeftMouseUp"
SourceName="notifyIcon"> SourceName="notifyIcon">
<BeginStoryboard <BeginStoryboard
Storyboard="{StaticResource ShowMouseUp}" Storyboard="{StaticResource ShowMouseUp}"
x:Name="ShowMouseUp_BeginStoryboard" /> x:Name="ShowMouseUp_BeginStoryboard" />
</EventTrigger> </EventTrigger>
<EventTrigger <EventTrigger
RoutedEvent="tb:TaskbarIcon.TrayToolTipOpen" RoutedEvent="tb:TaskbarIcon.TrayToolTipOpen"
SourceName="notifyIcon"> SourceName="notifyIcon">
<BeginStoryboard <BeginStoryboard
Storyboard="{StaticResource ShowToolTipOpened}" Storyboard="{StaticResource ShowToolTipOpened}"
x:Name="ShowToolTipOpened_BeginStoryboard" /> x:Name="ShowToolTipOpened_BeginStoryboard" />
</EventTrigger> </EventTrigger>
</Window.Triggers> </Window.Triggers>
<Grid> <Grid>
<!-- the NotifyIcon does not need to be configured here - animations were set up in Blend --> <!-- the NotifyIcon does not need to be configured here - animations were set up in Blend -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="notifyIcon" x:Name="notifyIcon"
ToolTipText="hello world" ToolTipText="hello world"
IconSource="/Icons/Error.ico" /> IconSource="/Icons/Error.ico" />
<Ellipse
HorizontalAlignment="Left"
Margin="24,62,0,0"
VerticalAlignment="Top"
Width="19"
Height="19"
Stroke="#FF549D2D"
x:Name="MoveIndicator"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform
ScaleX="1"
ScaleY="1" />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse
Stroke="#FF549D2D"
HorizontalAlignment="Left"
Margin="24,106,0,0"
VerticalAlignment="Top"
Width="19"
Height="19"
x:Name="LeftMouseIndicator"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse
Stroke="#FF549D2D"
HorizontalAlignment="Left"
Margin="24,0,0,94"
Width="19"
x:Name="ToolTipIndicator"
RenderTransformOrigin="0.5,0.5"
Height="19"
VerticalAlignment="Bottom">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform
ScaleX="1"
ScaleY="1" />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<TextBlock
Margin="63,62,91,0"
VerticalAlignment="Top"
Height="19"
TextWrapping="Wrap">
<Run
Language="de-ch"
Text="TrayMouseMove Event" />
</TextBlock>
<TextBlock
Margin="63,106,91,0"
VerticalAlignment="Top"
Height="19"
TextWrapping="Wrap">
<Run
Language="de-ch"
Text="TrayLeftMouseUp Event" />
</TextBlock>
<TextBlock
Margin="63,0,91,94"
TextWrapping="Wrap"
VerticalAlignment="Bottom"
Height="19">
<Run
Language="de-ch"
Text="TrayToolTipOpen Event" />
</TextBlock>
<TextBlock
Margin="10,10,10,0"
VerticalAlignment="Top"
Height="31"
TextWrapping="Wrap"
FontWeight="Bold">
<Run Language="de-ch" Text="The green ellipses are animated based on routed events of the NotifyIcon" />
</TextBlock>
</Grid>
<Ellipse
HorizontalAlignment="Left"
Margin="24,62,0,0"
VerticalAlignment="Top"
Width="19"
Height="19"
Stroke="#FF549D2D"
x:Name="MoveIndicator"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform
ScaleX="1"
ScaleY="1" />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse
Stroke="#FF549D2D"
HorizontalAlignment="Left"
Margin="24,106,0,0"
VerticalAlignment="Top"
Width="19"
Height="19"
x:Name="LeftMouseIndicator"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse
Stroke="#FF549D2D"
HorizontalAlignment="Left"
Margin="24,0,0,94"
Width="19"
x:Name="ToolTipIndicator"
RenderTransformOrigin="0.5,0.5"
Height="19"
VerticalAlignment="Bottom">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform
ScaleX="1"
ScaleY="1" />
<SkewTransform
AngleX="0"
AngleY="0" />
<RotateTransform
Angle="0" />
<TranslateTransform
X="0"
Y="0" />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush
EndPoint="0.528,0.694"
StartPoint="-0.056,-0.118">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FF65A135"
Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<TextBlock
Margin="63,62,91,0"
VerticalAlignment="Top"
Height="19"
TextWrapping="Wrap"><Run
Language="de-ch"
Text="TrayMouseMove Event" /></TextBlock>
<TextBlock
Margin="63,106,91,0"
VerticalAlignment="Top"
Height="19"
TextWrapping="Wrap"><Run
Language="de-ch"
Text="TrayLeftMouseUp Event" /></TextBlock>
<TextBlock
Margin="63,0,91,94"
TextWrapping="Wrap"
VerticalAlignment="Bottom"
Height="19"><Run
Language="de-ch"
Text="TrayToolTipOpen Event" /></TextBlock>
<TextBlock
Margin="10,10,10,0"
VerticalAlignment="Top"
Height="31"
TextWrapping="Wrap"
FontWeight="Bold"><Run Language="de-ch" Text="The green ellipses are animated based on routed events of the NotifyIcon"/></TextBlock>
</Grid>
</Window> </Window>

View File

@@ -2,23 +2,23 @@
namespace Samples.Tutorials.Events namespace Samples.Tutorials.Events
{ {
/// <summary> /// <summary>
/// Interaction logic for EventVisualizerWindow.xaml /// Interaction logic for EventVisualizerWindow.xaml
/// </summary> /// </summary>
public partial class EventVisualizerWindow : Window public partial class EventVisualizerWindow : Window
{
public EventVisualizerWindow()
{ {
InitializeComponent(); public EventVisualizerWindow()
{
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
notifyIcon.Dispose();
base.OnClosing(e);
}
} }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
notifyIcon.Dispose();
base.OnClosing(e);
}
}
} }

View File

@@ -1,97 +1,101 @@
<Window <Window
x:Class="Samples.Tutorials.DataBinding.DataBoundToolTipWindow" x:Class="Samples.Tutorials.DataBinding.DataBoundToolTipWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="300" Height="300"
Width="500"> Width="500">
<Grid> <Grid>
<!-- the ToolTipText property is bound to the TextBox below --> <!-- the ToolTipText property is bound to the TextBox below -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon1" x:Name="MyNotifyIcon1"
IconSource="/Icons/Error.ico" IconSource="/Icons/Error.ico"
ToolTipText="{Binding ElementName=txtToolTip, Path=Text}"> ToolTipText="{Binding ElementName=txtToolTip, Path=Text}">
<!-- <!--
The TextBlock bound to the ToolTipText property of the NotifyIcon The TextBlock bound to the ToolTipText property of the NotifyIcon
The binding is implicit (using DataContext) The binding is implicit (using DataContext)
--> -->
<tb:TaskbarIcon.TrayToolTip> <tb:TaskbarIcon.TrayToolTip>
<Border <Border
Background="White" Background="White"
BorderBrush="Orange" BorderBrush="Orange"
BorderThickness="2" BorderThickness="2"
CornerRadius="4" CornerRadius="4"
Opacity="0.8" Opacity="0.8"
Width="160" Width="160"
Height="40"> Height="40">
<TextBlock <TextBlock
Text="{Binding Path=ToolTipText}" Text="{Binding Path=ToolTipText}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</Border> </Border>
</tb:TaskbarIcon.TrayToolTip> </tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon> </tb:TaskbarIcon>
<!-- This NotifyIcon has its DataContext set (just the string "WPF FTW") - implicit binding is no longer possible --> <!-- This NotifyIcon has its DataContext set (just the string "WPF FTW") - implicit binding is no longer possible -->
<tb:TaskbarIcon <tb:TaskbarIcon
x:Name="MyNotifyIcon2" x:Name="MyNotifyIcon2"
DataContext="WPF FTW " DataContext="WPF FTW "
IconSource="/Icons/Inactive.ico" IconSource="/Icons/Inactive.ico"
ToolTipText="{Binding ElementName=txtToolTip, Path=Text}"> ToolTipText="{Binding ElementName=txtToolTip, Path=Text}">
<tb:TaskbarIcon.TrayToolTip> <tb:TaskbarIcon.TrayToolTip>
<!-- <!--
Important: The attached property is assigned to the border, but derived by all controls. Important: The attached property is assigned to the border, but derived by all controls.
The NotifyIcon does not touch the underlying controls. The NotifyIcon does not touch the underlying controls.
--> -->
<Border <Border
Background="White" Background="White"
BorderBrush="Orange" BorderBrush="Orange"
BorderThickness="2" BorderThickness="2"
CornerRadius="4" CornerRadius="4"
Opacity="0.8" Opacity="0.8"
Width="160" Width="160"
Height="40"> Height="40">
<!-- Implicitly access the DataContext (which is a string this time)--> <!-- Implicitly access the DataContext (which is a string this time)-->
<TextBlock Text="{Binding}"> <TextBlock Text="{Binding}">
<!-- Explicitly access the NotifyIcon, as it is an attached property --> <!-- Explicitly access the NotifyIcon, as it is an attached property -->
<TextBlock <TextBlock
Text="{Binding RelativeSource={RelativeSource Self}, Text="{Binding RelativeSource={RelativeSource Self},
Path=(tb:TaskbarIcon.ParentTaskbarIcon).ToolTipText}" Path=(tb:TaskbarIcon.ParentTaskbarIcon).ToolTipText}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</TextBlock> </TextBlock>
</Border> </Border>
</tb:TaskbarIcon.TrayToolTip> </tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon> </tb:TaskbarIcon>
<TextBlock
Margin="26,26,24,0"
VerticalAlignment="Top"
TextWrapping="Wrap"
FontWeight="Bold">
<Run Text="This sample shows data bound ToolTips in two flavors" /><LineBreak /><Run Text="" />
<LineBreak /><Run Text="- implicit binding via DataContext" /><LineBreak />
<Run Text="- explicit binding via ParentTaskbarIcon (attached property)" /><LineBreak /><Run Text="" />
<LineBreak /><Run Text="Move over NotifyIcons (grey / red) to show data bound ToolTip" />
</TextBlock>
<TextBox
Margin="26,0,24,10"
Text="hello world"
TextWrapping="Wrap"
x:Name="txtToolTip" Height="25" VerticalAlignment="Bottom" />
<TextBlock
Margin="26,0,125,45"
VerticalAlignment="Bottom"
Height="26"
TextWrapping="Wrap">
<Run
<TextBlock Text="ToolTipText:" />
Margin="26,26,24,0" </TextBlock>
VerticalAlignment="Top"
TextWrapping="Wrap"
FontWeight="Bold"><Run Text="This sample shows data bound ToolTips in two flavors"/><LineBreak/><Run Text=""/><LineBreak/><Run Text="- implicit binding via DataContext"/><LineBreak/><Run Text="- explicit binding via ParentTaskbarIcon (attached property)"/><LineBreak/><Run Text=""/><LineBreak/><Run Text="Move over NotifyIcons (grey / red) to show data bound ToolTip"/></TextBlock>
<TextBox
Margin="26,0,24,10"
Text="hello world"
TextWrapping="Wrap"
x:Name="txtToolTip" Height="25" VerticalAlignment="Bottom" />
<TextBlock
Margin="26,0,125,45"
VerticalAlignment="Bottom"
Height="26"
TextWrapping="Wrap"><Run
Text="ToolTipText:" /></TextBlock>
</Grid> </Grid>
</Window> </Window>

View File

@@ -2,24 +2,24 @@
namespace Samples.Tutorials.DataBinding namespace Samples.Tutorials.DataBinding
{ {
/// <summary> /// <summary>
/// Interaction logic for DataBoundToolTipWindow.xaml /// Interaction logic for DataBoundToolTipWindow.xaml
/// </summary> /// </summary>
public partial class DataBoundToolTipWindow : Window public partial class DataBoundToolTipWindow : Window
{
public DataBoundToolTipWindow()
{ {
InitializeComponent(); public DataBoundToolTipWindow()
{
InitializeComponent();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon1.Dispose();
MyNotifyIcon2.Dispose();
base.OnClosing(e);
}
} }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
//clean up notifyicon (would otherwise stay open until application finishes)
MyNotifyIcon1.Dispose();
MyNotifyIcon2.Dispose();
base.OnClosing(e);
}
}
} }

View File

@@ -1,114 +1,129 @@
<UserControl <UserControl
x:Class="Samples.FancyPopup" x:Class="Samples.FancyPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:tb="http://www.hardcodet.net/taskbar"
Height="215" Height="215"
Width="300" x:Name="me"> Width="300" x:Name="me">
<UserControl.Resources> <UserControl.Resources>
<Storyboard x:Key="RotateIcon"> <Storyboard x:Key="RotateIcon">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image"
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeySpline="0,0.284,0.39,1" KeyTime="00:00:01.4000000" Value="360"/> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
</DoubleAnimationUsingKeyFrames> <SplineDoubleKeyFrame KeySpline="0,0.284,0.39,1" KeyTime="00:00:01.4000000" Value="360" />
</Storyboard> </DoubleAnimationUsingKeyFrames>
</UserControl.Resources> </Storyboard>
<UserControl.Triggers> </UserControl.Resources>
<EventTrigger RoutedEvent="tb:TaskbarIcon.PopupOpened"> <UserControl.Triggers>
<BeginStoryboard Storyboard="{StaticResource RotateIcon}" x:Name="RotateIcon_BeginStoryboard"/> <EventTrigger RoutedEvent="tb:TaskbarIcon.PopupOpened">
</EventTrigger> <BeginStoryboard Storyboard="{StaticResource RotateIcon}" x:Name="RotateIcon_BeginStoryboard" />
</UserControl.Triggers> </EventTrigger>
<Grid> </UserControl.Triggers>
<Border <Grid>
HorizontalAlignment="Stretch" <Border
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Width="Auto" VerticalAlignment="Stretch"
Height="Auto" Width="Auto"
Margin="5,5,5,5" Height="Auto"
CornerRadius="10,10,10,10"> Margin="5,5,5,5"
<Border.Effect> CornerRadius="10,10,10,10">
<DropShadowEffect <Border.Effect>
Color="#FF474747" /> <DropShadowEffect
</Border.Effect> Color="#FF474747" />
<Border.Background> </Border.Effect>
<LinearGradientBrush <Border.Background>
EndPoint="0.5,1" <LinearGradientBrush
StartPoint="0.5,0"> EndPoint="0.5,1"
<GradientStop StartPoint="0.5,0">
Color="#FF58C2FF" <GradientStop
Offset="0" /> Color="#FF58C2FF"
<GradientStop Offset="0" />
Color="#FFFFFFFF" <GradientStop
Offset="1" /> Color="#FFFFFFFF"
</LinearGradientBrush> Offset="1" />
</Border.Background> </LinearGradientBrush>
</Border> </Border.Background>
<Image </Border>
HorizontalAlignment="Left" <Image
Margin="19,10,0,0" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="19,10,0,0"
Width="72" VerticalAlignment="Top"
Height="72" Width="72"
Source="/Images/Preferences.png" Height="72"
Stretch="Fill" x:Name="image" RenderTransformOrigin="0.5,0.5" > Source="/Images/Preferences.png"
<Image.RenderTransform> Stretch="Fill" x:Name="image" RenderTransformOrigin="0.5,0.5">
<TransformGroup> <Image.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/> <TransformGroup>
<SkewTransform AngleX="0" AngleY="0"/> <ScaleTransform ScaleX="1" ScaleY="1" />
<RotateTransform Angle="0"/> <SkewTransform AngleX="0" AngleY="0" />
<TranslateTransform X="0" Y="0"/> <RotateTransform Angle="0" />
</TransformGroup> <TranslateTransform X="0" Y="0" />
</Image.RenderTransform> </TransformGroup>
</Image> </Image.RenderTransform>
<TextBlock </Image>
Margin="107,10,20,0" <TextBlock
TextWrapping="Wrap" Margin="107,10,20,0"
Height="Auto" TextWrapping="Wrap"
VerticalAlignment="Top" Height="Auto"
FontSize="16" VerticalAlignment="Top"
FontWeight="Bold" FontSize="16"
Foreground="#FF575757" HorizontalAlignment="Right"><Run FontWeight="Bold"
Text="This is a fancy Popup..." Foreground="#FF575757" HorizontalAlignment="Right">
Language="de-ch" /></TextBlock> <Run
<Button Text="This is a fancy Popup..."
Click="OnButtonClick" Language="de-ch" />
ToolTip="{Binding Path=ToolTipText}" </TextBlock>
HorizontalAlignment="Right" <Button
VerticalAlignment="Bottom" Click="OnButtonClick"
Width="89" ToolTip="{Binding Path=ToolTipText}"
Height="29" HorizontalAlignment="Right"
Content="Click me" VerticalAlignment="Bottom"
Margin="0,0,20,20" Width="89"
BorderBrush="#FFFFFFFF"> Height="29"
<Button.Background> Content="Click me"
<LinearGradientBrush Margin="0,0,20,20"
EndPoint="0,1" BorderBrush="#FFFFFFFF">
StartPoint="0,0"> <Button.Background>
<GradientStop <LinearGradientBrush
Color="#FFFFFFFF" EndPoint="0,1"
Offset="1" /> StartPoint="0,0">
<GradientStop <GradientStop
Color="#FFFFD197" Color="#FFFFFFFF"
Offset="0.459" /> Offset="1" />
<GradientStop <GradientStop
Color="#FFFFDBAD" Color="#FFFFD197"
Offset="0" /> Offset="0.459" />
<GradientStop <GradientStop
Color="#FFF18E23" Color="#FFFFDBAD"
Offset="0.508" /> Offset="0" />
<GradientStop <GradientStop
Color="#FFF9D4AC" Color="#FFF18E23"
Offset="0.954" /> Offset="0.508" />
</LinearGradientBrush> <GradientStop
</Button.Background> Color="#FFF9D4AC"
</Button> Offset="0.954" />
<TextBlock </LinearGradientBrush>
Margin="19,92,10,49" </Button.Background>
TextWrapping="Wrap"><Run Text="This user control makes use of the " Language="de-ch"/><Run FontStyle="Italic" FontWeight="Bold" Text="PopupOpened " Language="de-ch"/><Run Text="attached routed event . Whenever the popup is opened, this attached event fires and triggers the rotation animation." Language="de-ch"/></TextBlock> </Button>
<TextBlock Margin="0,52,20,0" VerticalAlignment="Top" Height="Auto" TextWrapping="Wrap" FontWeight="Bold" FontSize="14" HorizontalAlignment="Right" Foreground="#FF575757"><Run Text="Clicks: " Language="de-ch"/><InlineUIContainer> <TextBlock
<TextBlock Width="Auto" Height="Auto" Text="{Binding Path=ClickCount, ElementName=me, Mode=Default}" TextWrapping="Wrap"/> Margin="19,92,10,49"
</InlineUIContainer></TextBlock> TextWrapping="Wrap">
<Image <Run Text="This user control makes use of the " Language="de-ch" />
Source="{Binding Path=IconSource}" Width="16" HorizontalAlignment="Left" Margin="19,0,0,23" Height="16" VerticalAlignment="Bottom" /> <Run FontStyle="Italic" FontWeight="Bold" Text="PopupOpened " Language="de-ch" />
<Run
Text="attached routed event . Whenever the popup is opened, this attached event fires and triggers the rotation animation."
Language="de-ch" />
</TextBlock>
<TextBlock Margin="0,52,20,0" VerticalAlignment="Top" Height="Auto" TextWrapping="Wrap" FontWeight="Bold"
FontSize="14" HorizontalAlignment="Right" Foreground="#FF575757">
<Run Text="Clicks: " Language="de-ch" />
<InlineUIContainer>
<TextBlock Width="Auto" Height="Auto" Text="{Binding Path=ClickCount, ElementName=me, Mode=Default}"
TextWrapping="Wrap" />
</InlineUIContainer>
</TextBlock>
<Image
Source="{Binding Path=IconSource}" Width="16" HorizontalAlignment="Left" Margin="19,0,0,23" Height="16"
VerticalAlignment="Bottom" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -2,44 +2,44 @@
namespace Samples namespace Samples
{ {
/// <summary>
/// Interaction logic for FancyPopup.xaml
/// </summary>
public partial class FancyPopup
{
#region ClickCount dependency property
/// <summary> /// <summary>
/// The number of clicks on the popup button. /// Interaction logic for FancyPopup.xaml
/// </summary> /// </summary>
public static readonly DependencyProperty ClickCountProperty = public partial class FancyPopup
DependencyProperty.Register("ClickCount",
typeof (int),
typeof (FancyPopup),
new FrameworkPropertyMetadata(0));
/// <summary>
/// A property wrapper for the <see cref="ClickCountProperty"/>
/// dependency property:<br/>
/// The number of clicks on the popup button.
/// </summary>
public int ClickCount
{ {
get { return (int) GetValue(ClickCountProperty); } #region ClickCount dependency property
set { SetValue(ClickCountProperty, value); }
}
#endregion /// <summary>
/// The number of clicks on the popup button.
/// </summary>
public static readonly DependencyProperty ClickCountProperty =
DependencyProperty.Register("ClickCount",
typeof (int),
typeof (FancyPopup),
new FrameworkPropertyMetadata(0));
public FancyPopup() /// <summary>
{ /// A property wrapper for the <see cref="ClickCountProperty"/>
InitializeComponent(); /// dependency property:<br/>
} /// The number of clicks on the popup button.
/// </summary>
public int ClickCount
{
get { return (int) GetValue(ClickCountProperty); }
set { SetValue(ClickCountProperty, value); }
}
private void OnButtonClick(object sender, RoutedEventArgs e) #endregion
{
//just increment a counter - will be displayed on screen public FancyPopup()
ClickCount++; {
InitializeComponent();
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
//just increment a counter - will be displayed on screen
ClickCount++;
}
} }
}
} }

View File

@@ -7,33 +7,33 @@ using WindowsFormsSample.Properties;
namespace WindowsFormsSample namespace WindowsFormsSample
{ {
public partial class Form1 : Form public partial class Form1 : Form
{
private TaskbarIcon notifyIcon;
public Form1()
{ {
InitializeComponent(); private TaskbarIcon notifyIcon;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
notifyIcon = new TaskbarIcon();
notifyIcon.Icon = Resources.Led;
notifyIcon.ToolTipText = "Left-click to open popup";
notifyIcon.Visibility = Visibility.Visible;
notifyIcon.TrayPopup = new FancyPopup();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
//the notify icon only closes automatically on WPF applications
//-> dispose the notify icon manually
notifyIcon.Dispose();
}
} }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
notifyIcon = new TaskbarIcon();
notifyIcon.Icon = Resources.Led;
notifyIcon.ToolTipText = "Left-click to open popup";
notifyIcon.Visibility = Visibility.Visible;
notifyIcon.TrayPopup = new FancyPopup();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
//the notify icon only closes automatically on WPF applications
//-> dispose the notify icon manually
notifyIcon.Dispose();
}
}
}

View File

@@ -4,17 +4,17 @@ using Samples;
namespace WindowsFormsSample namespace WindowsFormsSample
{ {
static class Program internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{ {
Application.EnableVisualStyles(); /// <summary>
Application.SetCompatibleTextRenderingDefault(false); /// The main entry point for the application.
Application.Run(new Form1()); /// </summary>
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
} }
} }
}

View File

@@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("WindowsFormsSample")] [assembly: AssemblyTitle("WindowsFormsSample")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -17,9 +18,11 @@ using System.Runtime.InteropServices;
// Setting ComVisible to false makes the types in this assembly not visible // 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 // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("072bbfa0-9b8b-48df-bf88-3e4806b3e3e8")] [assembly: Guid("072bbfa0-9b8b-48df-bf88-3e4806b3e3e8")]
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
@@ -32,5 +35,6 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,7 +1,8 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"> <SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles> <Profiles>
<Profile Name="(Default)" /> <Profile Name="(Default)" />
</Profiles> </Profiles>
<Settings /> <Settings />
</SettingsFile> </SettingsFile>