mirror of
https://github.com/ckaczor/wpf-notifyicon.git
synced 2026-02-06 09:45:40 -05:00
WPF NotifyIcon
--------------
FIX If a popup is opened, its window handle is now being set as the foreground.
This fixes an issue with certain controls being disabled on popups.
(thanks Andrew Smith for pointing me in the right direction!).
FIX Changed dispatcher access in order to work in WinForms scenarios, too.
ADD Added WinForms sample.
git-svn-id: https://svn.evolvesoftware.ch/repos/evolve.net/WPF/NotifyIcon@118 9f600761-6f11-4665-b6dc-0185e9171623
This commit is contained in:
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
{
|
||||
/// <summary>
|
||||
/// The notify icon version that is used. The higher
|
||||
|
||||
@@ -40,9 +40,7 @@
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
@@ -73,11 +71,6 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="TaskbarIcon.cs" />
|
||||
<Compile Include="TaskbarIcon.Declarations.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
@@ -86,10 +79,6 @@
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Diagrams\TaskbarIcon Overview.cd" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -53,5 +53,5 @@ using System.Windows.Markup;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.3.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.3.0")]
|
||||
[assembly: AssemblyVersion("1.0.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.4.0")]
|
||||
|
||||
26
Source/NotifyIconWpf/Properties/Settings.Designer.cs
generated
26
Source/NotifyIconWpf/Properties/Settings.Designer.cs
generated
@@ -1,26 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.3053
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Hardcodet.Wpf.TaskbarNotification.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -30,7 +30,7 @@ using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Threading;
|
||||
using Hardcodet.Wpf.TaskbarNotification.Interop;
|
||||
using Point=Hardcodet.Wpf.TaskbarNotification.Interop.Point;
|
||||
@@ -162,10 +162,11 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
/// is a null reference.</exception>
|
||||
public void ShowCustomBalloon(UIElement balloon, PopupAnimation animation, int? timeout)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
Dispatcher dispatcher = this.GetDispatcher();
|
||||
if (!dispatcher.CheckAccess())
|
||||
{
|
||||
var action = new Action(() => ShowCustomBalloon(balloon, animation, timeout));
|
||||
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, action);
|
||||
dispatcher.Invoke(DispatcherPriority.Normal, action);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,8 +230,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
//register timer to close the popup
|
||||
balloonCloseTimer.Change(timeout.Value, Timeout.Infinite);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,10 +260,11 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
Dispatcher dispatcher = this.GetDispatcher();
|
||||
if (!dispatcher.CheckAccess())
|
||||
{
|
||||
Action action = CloseBalloon;
|
||||
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, action);
|
||||
dispatcher.Invoke(DispatcherPriority.Normal, action);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
//switch to UI thread
|
||||
Action action = CloseBalloon;
|
||||
Application.Current.Dispatcher.Invoke(action);
|
||||
this.GetDispatcher().Invoke(action);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -637,9 +637,21 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
//open popup
|
||||
TrayPopupResolved.IsOpen = true;
|
||||
|
||||
//activate the message window to track deactivation - otherwise, the context menu
|
||||
//does not close if the user clicks somewhere else
|
||||
WinApi.SetForegroundWindow(messageSink.MessageWindowHandle);
|
||||
|
||||
IntPtr handle = IntPtr.Zero;
|
||||
if (TrayPopupResolved.Child != null)
|
||||
{
|
||||
//try to get a handle on the popup itself (via its child)
|
||||
HwndSource source = (HwndSource)PresentationSource.FromVisual(TrayPopupResolved.Child);
|
||||
if (source != null) handle = source.Handle;
|
||||
}
|
||||
|
||||
//if we don't have a handle for the popup, fall back to the message sink
|
||||
if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle;
|
||||
|
||||
//activate either popup or message sink to track deactivation.
|
||||
//otherwise, the popup does not close if the user clicks somewhere else
|
||||
WinApi.SetForegroundWindow(handle);
|
||||
|
||||
//raise attached event - item should never be null unless developers
|
||||
//changed the CustomPopup directly...
|
||||
@@ -797,7 +809,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
delayedTimerAction = null;
|
||||
|
||||
//switch to UI thread
|
||||
Application.Current.Dispatcher.Invoke(action);
|
||||
this.GetDispatcher().Invoke(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
|
||||
|
||||
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
@@ -30,6 +29,7 @@ using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Resources;
|
||||
using System.Windows.Threading;
|
||||
using Hardcodet.Wpf.TaskbarNotification.Interop;
|
||||
|
||||
namespace Hardcodet.Wpf.TaskbarNotification
|
||||
@@ -41,7 +41,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
{
|
||||
public static readonly object SyncRoot = new object();
|
||||
|
||||
|
||||
#region IsDesignMode
|
||||
|
||||
private static readonly bool isDesignMode;
|
||||
@@ -56,19 +55,18 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region construction
|
||||
|
||||
static Util()
|
||||
{
|
||||
isDesignMode =
|
||||
(bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement))
|
||||
.Metadata.DefaultValue;
|
||||
(bool)
|
||||
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof (FrameworkElement))
|
||||
.Metadata.DefaultValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region CreateHelperWindow
|
||||
|
||||
/// <summary>
|
||||
@@ -80,19 +78,18 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
public static Window CreateHelperWindow()
|
||||
{
|
||||
return new Window
|
||||
{
|
||||
Width = 0,
|
||||
Height = 0,
|
||||
ShowInTaskbar = false,
|
||||
WindowStyle = WindowStyle.None,
|
||||
AllowsTransparency = true,
|
||||
Opacity = 0
|
||||
};
|
||||
{
|
||||
Width = 0,
|
||||
Height = 0,
|
||||
ShowInTaskbar = false,
|
||||
WindowStyle = WindowStyle.None,
|
||||
AllowsTransparency = true,
|
||||
Opacity = 0
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region WriteIconData
|
||||
|
||||
/// <summary>
|
||||
@@ -133,7 +130,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region GetBalloonFlag
|
||||
|
||||
/// <summary>
|
||||
@@ -159,7 +155,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ImageSource to Icon
|
||||
|
||||
/// <summary>
|
||||
@@ -188,7 +183,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region evaluate listings
|
||||
|
||||
/// <summary>
|
||||
@@ -219,7 +213,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region match MouseEvent to PopupActivation
|
||||
|
||||
/// <summary>
|
||||
@@ -252,7 +245,6 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region execute command
|
||||
|
||||
/// <summary>
|
||||
@@ -281,6 +273,22 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#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"/>
|
||||
@@ -296,6 +304,5 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
if (element == null) throw new ArgumentNullException("element");
|
||||
return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user