NotifyIcon WPF

--------------
ADD   Added custom balloon support.
CHG   Refactoring of names - properties and events are prefixed by "Tray" rather than "TaskbarIcon".

git-svn-id: https://svn.evolvesoftware.ch/repos/evolve.net/WPF/NotifyIcon@57 9f600761-6f11-4665-b6dc-0185e9171623
This commit is contained in:
Philipp Sumi
2009-04-01 14:59:44 +00:00
parent 1242596214
commit fc7fa38ef5
14 changed files with 841 additions and 696 deletions

View File

@@ -3,10 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotifyIconWpf", "NotifyIconWpf\NotifyIconWpf.csproj", "{7AC63864-7638-41C4-969C-D3197EF2BED9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication2", "ConsoleApplication2\ConsoleApplication2.csproj", "{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj", "{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample Project", "Sample Project\Sample Project.csproj", "{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}"
EndProject
Global
@@ -19,14 +15,6 @@ Global
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AC63864-7638-41C4-969C-D3197EF2BED9}.Release|Any CPU.Build.0 = Release|Any CPU
{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}.Release|Any CPU.Build.0 = Release|Any CPU
{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}.Release|Any CPU.Build.0 = Release|Any CPU
{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@@ -5,20 +5,10 @@
<_SolutionProjectCacheVersion>3.5</_SolutionProjectCacheVersion>
</PropertyGroup>
<ItemGroup>
<_SolutionProjectProjects Include="ConsoleApplication1\ConsoleApplication1.csproj" />
<_SolutionProjectProjects Include="ConsoleApplication2\ConsoleApplication2.csproj" />
<_SolutionProjectProjects Include="NotifyIconWpf\NotifyIconWpf.csproj" />
<_SolutionProjectProjects Include="Sample Project\Sample Project.csproj" />
</ItemGroup>
<ItemGroup Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<BuildLevel0 Include="ConsoleApplication1\ConsoleApplication1.csproj">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</BuildLevel0>
<BuildLevel0 Include="ConsoleApplication2\ConsoleApplication2.csproj">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</BuildLevel0>
<BuildLevel0 Include="NotifyIconWpf\NotifyIconWpf.csproj">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
@@ -29,14 +19,6 @@
</BuildLevel1>
</ItemGroup>
<ItemGroup Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
<BuildLevel0 Include="ConsoleApplication1\ConsoleApplication1.csproj">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</BuildLevel0>
<BuildLevel0 Include="ConsoleApplication2\ConsoleApplication2.csproj">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</BuildLevel0>
<BuildLevel0 Include="NotifyIconWpf\NotifyIconWpf.csproj">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
@@ -72,8 +54,6 @@
<CurrentSolutionConfigurationContents>
<SolutionConfiguration xmlns="">
<ProjectConfiguration Project="{7AC63864-7638-41C4-969C-D3197EF2BED9}">Debug|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}">Debug|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}">Debug|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}">Debug|AnyCPU</ProjectConfiguration>
</SolutionConfiguration>
</CurrentSolutionConfigurationContents>
@@ -82,8 +62,6 @@
<CurrentSolutionConfigurationContents>
<SolutionConfiguration xmlns="">
<ProjectConfiguration Project="{7AC63864-7638-41C4-969C-D3197EF2BED9}">Release|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{A92D287A-6DD2-4D75-9CE5-64BFB990E2D8}">Release|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{10BB9EF0-20F9-460E-96A3-284FF0D1C2E6}">Release|AnyCPU</ProjectConfiguration>
<ProjectConfiguration Project="{71C74F29-F1C2-49C5-969F-C25AC4CDFCCC}">Release|AnyCPU</ProjectConfiguration>
</SolutionConfiguration>
</CurrentSolutionConfigurationContents>
@@ -120,54 +98,6 @@
<MSBuild Projects="NotifyIconWpf\NotifyIconWpf.csproj" Targets="Publish" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " />
<MSBuild Projects="NotifyIconWpf\NotifyIconWpf.csproj" Targets="Publish" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
</Target>
<Target Name="ConsoleApplication2" Condition="'$(CurrentSolutionConfigurationContents)' != ''" Outputs="@(ConsoleApplication2BuildOutput)">
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication2BuildOutput" />
</MSBuild>
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication2BuildOutput" />
</MSBuild>
</Target>
<Target Name="ConsoleApplication2:Clean" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Clean" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " />
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Clean" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
</Target>
<Target Name="ConsoleApplication2:Rebuild" Condition="'$(CurrentSolutionConfigurationContents)' != ''" Outputs="@(ConsoleApplication2BuildOutput)">
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Rebuild" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication2BuildOutput" />
</MSBuild>
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Rebuild" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication2BuildOutput" />
</MSBuild>
</Target>
<Target Name="ConsoleApplication2:Publish" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Publish" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " />
<MSBuild Projects="ConsoleApplication2\ConsoleApplication2.csproj" Targets="Publish" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
</Target>
<Target Name="ConsoleApplication1" Condition="'$(CurrentSolutionConfigurationContents)' != ''" Outputs="@(ConsoleApplication1BuildOutput)">
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication1BuildOutput" />
</MSBuild>
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication1BuildOutput" />
</MSBuild>
</Target>
<Target Name="ConsoleApplication1:Clean" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Clean" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " />
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Clean" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
</Target>
<Target Name="ConsoleApplication1:Rebuild" Condition="'$(CurrentSolutionConfigurationContents)' != ''" Outputs="@(ConsoleApplication1BuildOutput)">
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Rebuild" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication1BuildOutput" />
</MSBuild>
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Rebuild" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="ConsoleApplication1BuildOutput" />
</MSBuild>
</Target>
<Target Name="ConsoleApplication1:Publish" Condition="'$(CurrentSolutionConfigurationContents)' != ''">
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Publish" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " />
<MSBuild Projects="ConsoleApplication1\ConsoleApplication1.csproj" Targets="Publish" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " />
</Target>
<Target Name="Sample Project" DependsOnTargets="NotifyIconWpf" Condition="'$(CurrentSolutionConfigurationContents)' != ''" Outputs="@(Sample_ProjectBuildOutput)">
<MSBuild Projects="Sample Project\Sample Project.csproj" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" ToolsVersion="$(ProjectToolsVersion)" UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)" UseResultsCache="$(UseResultsCache)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
<Output TaskParameter="TargetOutputs" ItemName="Sample_ProjectBuildOutput" />

View File

@@ -126,7 +126,20 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
{
var data = new NotifyIconData();
data.cbSize = (uint) Marshal.SizeOf(data);
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 = 504;
//set to fixed timeout
data.VersionOrTimeout = 10;
}
data.WindowHandle = handle;
data.TaskbarIconId = 0x0;

View File

@@ -12,11 +12,13 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
public enum NotifyIconVersion
{
/// <summary>
/// Default behavior (legacy Win95).
/// Default behavior (legacy Win95). Expects
/// a <see cref="NotifyIconData"/> size of 488.
/// </summary>
Win95 = 0x0,
/// <summary>
/// Behavior representing Win2000 an higher.
/// Behavior representing Win2000 an higher. Expects
/// a <see cref="NotifyIconData"/> size of 504.
/// </summary>
Win2000 = 0x3,
/// <summary>

View File

@@ -1,95 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Hardcodet.Wpf.TaskbarNotification.Interop
{
public struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
public override string ToString()
{
return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")";
}
}
public struct TaskbarInfo
{
public int cbSize;
public IntPtr WindowHandle;
public int uCallbackMessage;
public TaskbarPosition Position;
public Rect Rectangle;
public IntPtr lParam;
}
public enum TaskbarPosition
{
Left = 0,
Top,
Right,
Bottom
}
/// <summary>
/// Locates the position of the tray area.
/// </summary>
public class TrayLocator
{
public enum ABMsg
{
ABM_NEW = 0,
ABM_REMOVE = 1,
ABM_QUERYPOS = 2,
ABM_SETPOS = 3,
ABM_GETSTATE = 4,
ABM_GETTASKBARPOS = 5,
ABM_ACTIVATE = 6,
ABM_GETAUTOHIDEBAR = 7,
ABM_SETAUTOHIDEBAR = 8,
ABM_WINDOWPOSCHANGED = 9,
ABM_SETSTATE = 10
}
public enum ABNotify
{
ABN_STATECHANGE = 0,
ABN_POSCHANGED,
ABN_FULLSCREENAPP,
ABN_WINDOWARRANGE
}
[DllImport("shell32.dll", EntryPoint = "SHAppBarMessage", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int SHAppBarMessage(int dwMessage, ref TaskbarInfo pData);
/// <summary>
/// Determines the current location of the taskbar.
/// </summary>
/// <returns></returns>
public static TaskbarInfo GetTaskbarInformation()
{
TaskbarInfo tbInfo = new TaskbarInfo();
tbInfo.cbSize = Marshal.SizeOf(tbInfo);
//retrieve the bounding rectangle of the Windows taskbar.
SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref tbInfo);
return tbInfo;
}
}
}

View File

@@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -32,6 +33,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Hardcodet.Wpf.TaskbarNotification.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -39,22 +41,14 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Compile Include="BalloonIcon.cs" />
<Compile Include="Interop\AnyForm.cs" />
<Compile Include="Interop\Point.cs" />
<Compile Include="Interop\TrayLocator.cs" />
<Compile Include="Interop\WindowClass.cs" />
<Compile Include="PopupActivationMode.cs" />
<Compile Include="RoutedEventHelper.cs" />

View File

@@ -9,11 +9,11 @@ using System.Windows.Markup;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NotifyIconWpf")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyDescription("NotifyIcon Implementation for WPF.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyCompany("hardcodet.net")]
[assembly: AssemblyProduct("NotifyIconWpf")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
[assembly: AssemblyCopyright("Copyright © Philipp Sumi 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using Hardcodet.Wpf.TaskbarNotification.Interop;
using Point=Hardcodet.Wpf.TaskbarNotification.Interop.Point;
using Rect=Hardcodet.Wpf.TaskbarNotification.Interop.Rect;
namespace Hardcodet.Wpf.TaskbarNotification
{
@@ -17,6 +18,8 @@ namespace Hardcodet.Wpf.TaskbarNotification
/// </summary>
public partial class TaskbarIcon : FrameworkElement, IDisposable
{
#region Members
/// <summary>
/// Represents the current icon data.
/// </summary>
@@ -39,6 +42,11 @@ namespace Hardcodet.Wpf.TaskbarNotification
/// </summary>
private readonly Timer singleClickTimer;
/// <summary>
/// A timer that is used to close open balloon tooltips.
/// </summary>
private readonly Timer balloonCloseTimer;
/// <summary>
/// Indicates whether the taskbar icon has been created or not.
/// </summary>
@@ -54,6 +62,29 @@ namespace Hardcodet.Wpf.TaskbarNotification
get { return messageSink.Version == NotifyIconVersion.Vista; }
}
/// <summary>
/// Checks whether a non-tooltip popup is currently opened.
/// </summary>
private bool IsPopupOpen
{
get
{
var popup = TrayPopupResolved;
var menu = ContextMenu;
var balloon = CustomBalloon;
return popup != null && popup.IsOpen ||
menu != null && menu.IsOpen ||
balloon != null && balloon.IsOpen;
}
}
#endregion
#region Construction
/// <summary>
@@ -79,8 +110,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
messageSink.ChangeToolTipStateRequest += OnToolTipChange;
messageSink.BallonToolTipChanged += OnBalloonToolTipChanged;
//init single click timer
//init single click / balloon timers
singleClickTimer = new Timer(DoSingleClickAction);
balloonCloseTimer = new Timer(CloseBalloonCallback);
//register listener in order to get notified when the application closes
if (Application.Current != null) Application.Current.Exit += OnExit;
@@ -88,6 +120,112 @@ namespace Hardcodet.Wpf.TaskbarNotification
#endregion
/// <summary>
/// Shows a custom control as a tooltip in the tray location.
/// </summary>
/// <param name="balloon"></param>
/// <param name="animation">An optional animation for the popup.</param>
/// <param name="timeout">The time after which the popup is being closed.
/// </param>
/// <exception cref="ArgumentNullException">If <paramref name="balloon"/>
/// is a null reference.</exception>
public void ShowCustomBalloon(UIElement balloon, PopupAnimation animation, int? timeout)
{
if (balloon == null) throw new ArgumentNullException("balloon");
if (timeout.HasValue && timeout < 500)
{
string msg = "Invalid timeout of {0} milliseconds. Timeout must be at least 500 ms";
msg = String.Format(msg, timeout);
throw new ArgumentOutOfRangeException("timeout", msg);
}
EnsureNotDisposed();
//make sure we don't have an open balloon
lock (this)
{
CloseBalloon();
}
//create an invisible popup that hosts the UIElement
Popup popup = new Popup();
popup.AllowsTransparency = true;
//don't animate by default - devs can use attached
//events or override
popup.PopupAnimation = animation;
Popup.CreateRootPopup(popup, balloon);
popup.PlacementTarget = this;
popup.Placement = PlacementMode.AbsolutePoint;
popup.StaysOpen = true;
Point position = TrayInfo.GetTrayLocation();
popup.HorizontalOffset = position.X -1;
popup.VerticalOffset = position.Y -1;
//store reference
lock (this)
{
SetCustomBalloon(popup);
}
//fire attached event
RaiseBalloonShowingEvent(balloon);
//display item
popup.IsOpen = true;
if (timeout.HasValue)
{
//register timer to close the popup
balloonCloseTimer.Change(timeout.Value, Timeout.Infinite);
}
return;
}
/// <summary>
/// Closes the current <see cref="CustomBalloon"/>, if it's set.
/// </summary>
private void CloseBalloon()
{
if (IsDisposed) return;
lock (this)
{
//reset timer in any case
balloonCloseTimer.Change(Timeout.Infinite, Timeout.Infinite);
//reset old popup, if we still have one
Popup popup = CustomBalloon;
if (popup != null)
{
//if a balloon message is already displayed, close it immediately
popup.IsOpen = false;
SetCustomBalloon(null);
}
}
}
/// <summary>
/// Timer-invoke event which closes the currently open balloon and
/// resets the <see cref="CustomBalloon"/> dependency property.
/// </summary>
private void CloseBalloonCallback(object state)
{
if (IsDisposed) return;
//switch to UI thread
Action action = CloseBalloon;
Application.Current.Dispatcher.Invoke(action);
}
#region Process Incoming Mouse Events
/// <summary>
@@ -104,35 +242,35 @@ namespace Hardcodet.Wpf.TaskbarNotification
switch (me)
{
case MouseEvent.MouseMove:
RaiseTaskbarIconMouseMoveEvent();
RaiseTrayMouseMoveEvent();
//immediately return - there's nothing left to evaluate
return;
case MouseEvent.IconRightMouseDown:
RaiseTaskbarIconRightMouseDownEvent();
RaiseTrayRightMouseDownEvent();
break;
case MouseEvent.IconLeftMouseDown:
RaiseTaskbarIconLeftMouseDownEvent();
RaiseTrayLeftMouseDownEvent();
break;
case MouseEvent.IconRightMouseUp:
RaiseTaskbarIconRightMouseUpEvent();
RaiseTrayRightMouseUpEvent();
break;
case MouseEvent.IconLeftMouseUp:
RaiseTaskbarIconLeftMouseUpEvent();
RaiseTrayLeftMouseUpEvent();
break;
case MouseEvent.IconMiddleMouseDown:
RaiseTaskbarIconMiddleMouseDownEvent();
RaiseTrayMiddleMouseDownEvent();
break;
case MouseEvent.IconMiddleMouseUp:
RaiseTaskbarIconMiddleMouseUpEvent();
RaiseTrayMiddleMouseUpEvent();
break;
case MouseEvent.IconDoubleClick:
//cancel single click timer
singleClickTimer.Change(Timeout.Infinite, Timeout.Infinite);
//bubble event
RaiseTaskbarIconMouseDoubleClickEvent();
RaiseTrayMouseDoubleClickEvent();
break;
case MouseEvent.BalloonToolTipClicked:
RaiseTaskbarIconBalloonTipClickedEvent();
RaiseTrayBalloonTipClickedEvent();
break;
default:
throw new ArgumentOutOfRangeException("me", "Missing handler for mouse event flag: " + me);
@@ -189,47 +327,49 @@ namespace Hardcodet.Wpf.TaskbarNotification
private void OnToolTipChange(bool visible)
{
//if we don't have a tooltip, there's nothing to do here...
if (CustomToolTip == null) return;
if (TrayToolTipResolved == null) return;
if (visible)
{
if (ContextMenu != null && ContextMenu.IsOpen ||
CustomPopup != null && CustomPopup.IsOpen)
TrayPopupResolved != null && TrayPopupResolved.IsOpen)
{
//ignore if we have an open context menu or popup
return;
}
var args = RaisePreviewTaskbarIconToolTipOpenEvent();
var args = RaisePreviewTrayToolTipOpenEvent();
if (args.Handled) return;
CustomToolTip.IsOpen = true;
TrayToolTipResolved.IsOpen = true;
//raise attached event first
if (TaskbarIconToolTip != null) RaiseToolTipOpenedEvent(TaskbarIconToolTip);
if (TrayToolTip != null) RaiseToolTipOpenedEvent(TrayToolTip);
//bubble routed event
RaiseTaskbarIconToolTipOpenEvent();
RaiseTrayToolTipOpenEvent();
}
else
{
var args = RaisePreviewTaskbarIconToolTipCloseEvent();
var args = RaisePreviewTrayToolTipCloseEvent();
if (args.Handled) return;
//raise attached event first
if (TaskbarIconToolTip != null) RaiseToolTipCloseEvent(TaskbarIconToolTip);
if (TrayToolTip != null) RaiseToolTipCloseEvent(TrayToolTip);
//CustomToolTip.IsOpen = false;
RaiseTaskbarIconToolTipCloseEvent();
TrayToolTipResolved.IsOpen = false;
//bubble event
RaiseTrayToolTipCloseEvent();
}
}
/// <summary>
/// Creates a <see cref="ToolTip"/> control that either
/// wraps the currently set <see cref="TaskbarIconToolTip"/>
/// wraps the currently set <see cref="TrayToolTip"/>
/// control or the <see cref="ToolTipText"/> string.<br/>
/// If <see cref="TaskbarIconToolTip"/> itself is already
/// If <see cref="TrayToolTip"/> itself is already
/// a <see cref="ToolTip"/> instance, it will be used directly.
/// </summary>
/// <remarks>We use a <see cref="ToolTip"/> rather than
@@ -241,9 +381,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
private void CreateCustomToolTip()
{
//check if the item itself is a tooltip
ToolTip tt = TaskbarIconToolTip as ToolTip;
ToolTip tt = TrayToolTip as ToolTip;
if (tt == null && TaskbarIconToolTip != null)
if (tt == null && TrayToolTip != null)
{
//create an invisible tooltip that hosts the UIElement
tt = new ToolTip();
@@ -262,8 +402,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
//setting the
tt.StaysOpen = true;
tt.Content = TaskbarIconToolTip;
tt.Content = TrayToolTip;
}
else if (tt == null && !String.IsNullOrEmpty(ToolTipText))
{
@@ -273,7 +412,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
}
//store a reference to the used tooltip
CustomToolTip = tt;
SetTrayToolTipResolved(tt);
}
@@ -290,7 +429,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
{
//we need to set a tooltip text to get tooltip events from the
//taskbar icon
if (String.IsNullOrEmpty(iconData.ToolTipText) && CustomToolTip != null)
if (String.IsNullOrEmpty(iconData.ToolTipText) && TrayToolTipResolved != null)
{
//if we have not tooltip text but a custom tooltip, we
//need to set a dummy value (we're displaying the ToolTip control, not the string)
@@ -308,9 +447,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
/// <summary>
/// Creates a <see cref="ToolTip"/> control that either
/// wraps the currently set <see cref="TaskbarIconToolTip"/>
/// wraps the currently set <see cref="TrayToolTip"/>
/// control or the <see cref="ToolTipText"/> string.<br/>
/// If <see cref="TaskbarIconToolTip"/> itself is already
/// If <see cref="TrayToolTip"/> itself is already
/// a <see cref="ToolTip"/> instance, it will be used directly.
/// </summary>
/// <remarks>We use a <see cref="ToolTip"/> rather than
@@ -322,24 +461,27 @@ namespace Hardcodet.Wpf.TaskbarNotification
private void CreatePopup()
{
//no popup is available
if (TaskbarIconPopup == null) return;
if (TrayPopup == null) return;
//check if the item itself is a popup
Popup popup = TaskbarIconPopup as Popup;
Popup popup = TrayPopup as Popup;
if (popup == null)
{
//create an invisible popup that hosts the UIElement
popup = new Popup();
popup.AllowsTransparency = true;
popup.PopupAnimation = PopupAnimation.Fade;
//don't animate by default - devs can use attached
//events or override
popup.PopupAnimation = PopupAnimation.None;
//the tooltip (and implicitly its context) explicitly gets
//the DataContext of this instance. If there is no DataContext,
//the TaskbarIcon assigns itself
popup.DataContext = DataContext ?? this;
Popup.CreateRootPopup(popup, TaskbarIconPopup);
Popup.CreateRootPopup(popup, TrayPopup);
popup.PlacementTarget = this;
popup.Placement = PlacementMode.AbsolutePoint;
@@ -347,11 +489,12 @@ namespace Hardcodet.Wpf.TaskbarNotification
}
//store a reference to the used tooltip
CustomPopup = popup;
SetTrayPopupResolved(popup);
}
/// <summary>
/// Displays the <see cref="TaskbarIconPopup"/> control if
/// Displays the <see cref="TrayPopup"/> control if
/// it was set.
/// </summary>
private void ShowTrayPopup(Point cursorPosition)
@@ -360,18 +503,18 @@ namespace Hardcodet.Wpf.TaskbarNotification
//raise preview event no matter whether popup is currently set
//or not (enables client to set it on demand)
var args = RaisePreviewTaskbarIconPopupOpenEvent();
var args = RaisePreviewTrayPopupOpenEvent();
if (args.Handled) return;
if (TaskbarIconPopup != null)
if (TrayPopup != null)
{
//use absolute position, but place the popup centered above the icon
CustomPopup.Placement = PlacementMode.AbsolutePoint;
CustomPopup.HorizontalOffset = cursorPosition.X; //+ TaskbarIconPopup.ActualWidth/2;
CustomPopup.VerticalOffset = cursorPosition.Y;
TrayPopupResolved.Placement = PlacementMode.AbsolutePoint;
TrayPopupResolved.HorizontalOffset = cursorPosition.X;
TrayPopupResolved.VerticalOffset = cursorPosition.Y;
//open popup
CustomPopup.IsOpen = true;
TrayPopupResolved.IsOpen = true;
//activate the message window to track deactivation - otherwise, the context menu
//does not close if the user clicks somewhere else
@@ -379,10 +522,10 @@ namespace Hardcodet.Wpf.TaskbarNotification
//raise attached event - item should never be null unless developers
//changed the CustomPopup directly...
if (TaskbarIconPopup != null) RaisePopupOpenedEvent(TaskbarIconPopup);
if (TrayPopup != null) RaisePopupOpenedEvent(TrayPopup);
//bubble routed event
RaiseTaskbarIconPopupOpenEvent();
RaiseTrayPopupOpenEvent();
}
}
@@ -400,7 +543,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
//raise preview event no matter whether context menu is currently set
//or not (enables client to set it on demand)
var args = RaisePreviewTaskbarIconContextMenuOpenEvent();
var args = RaisePreviewTrayContextMenuOpenEvent();
if (args.Handled) return;
if (ContextMenu != null)
@@ -416,7 +559,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
WinApi.SetForegroundWindow(messageSink.MessageWindowHandle);
//bubble event
RaiseTaskbarIconContextMenuOpenEvent();
RaiseTrayContextMenuOpenEvent();
}
}
@@ -434,11 +577,11 @@ namespace Hardcodet.Wpf.TaskbarNotification
{
if (visible)
{
RaiseTaskbarIconBalloonTipShownEvent();
RaiseTrayBalloonTipShownEvent();
}
else
{
RaiseTaskbarIconBalloonTipClosedEvent();
RaiseTrayBalloonTipClosedEvent();
}
}
@@ -491,12 +634,12 @@ namespace Hardcodet.Wpf.TaskbarNotification
{
EnsureNotDisposed();
iconData.BalloonText = message;
iconData.BalloonTitle = title;
iconData.BalloonText = message ?? String.Empty;
iconData.BalloonTitle = title ?? String.Empty;
iconData.BalloonFlags = flags;
iconData.CustomBalloonIconHandle = balloonIconHandle;
Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Info);
Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Info | IconDataMembers.Icon);
}
@@ -720,8 +863,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
//deregister application event listener
Application.Current.Exit -= OnExit;
//stop timer
//stop timers
singleClickTimer.Dispose();
balloonCloseTimer.Dispose();
//dispose message sink
messageSink.Dispose();

View File

@@ -63,11 +63,11 @@
<TextBlock
Margin="107,10,20,0"
TextWrapping="Wrap"
Height="32"
Height="Auto"
VerticalAlignment="Top"
FontSize="16"
FontWeight="Bold"
Foreground="#FF575757"><Run
Foreground="#FF575757" HorizontalAlignment="Right"><Run
Text="This is a fancy Popup..."
Language="de-ch" /></TextBlock>
<Button
@@ -103,11 +103,8 @@
</Button>
<TextBlock
Margin="19,92,10,49"
TextWrapping="Wrap"><Run
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sed sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla dui nisi, venenatis" /><Run
Text="."
Language="de-ch" /></TextBlock>
<TextBlock Margin="0,52,20,0" VerticalAlignment="Top" Height="30" TextWrapping="Wrap" FontWeight="Bold" FontSize="14" HorizontalAlignment="Right" Foreground="#FF575757"><Run Text="Clicks: " Language="de-ch"/><InlineUIContainer>
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>
<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>

View File

@@ -8,12 +8,12 @@
x:Class="Sample_Project.FancyToolTip"
x:Name="me"
Width="285"
Height="108">
Height="136">
<UserControl.Resources>
<Storyboard x:Key="FadeIn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.25"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1" KeySpline="0,0,0.46,0.969"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.6"/>
@@ -41,7 +41,7 @@
</UserControl.Triggers>
<Grid
x:Name="LayoutRoot">
x:Name="LayoutRoot" Height="Auto">
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
@@ -74,7 +74,7 @@
Source="Images\Info.png"
Stretch="Fill"
VerticalAlignment="Top"
RenderTransformOrigin="0.792,0.486" x:Name="image" >
RenderTransformOrigin="0.792,0.486" x:Name="image" Height="72" >
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
@@ -96,12 +96,19 @@
Language="de-ch" /></TextBlock>
<TextBlock
FontSize="12"
FontWeight="Normal"
FontWeight="Bold"
Foreground="#FF141414"
TextWrapping="Wrap"
Margin="82,52,20,0"
VerticalAlignment="Top"
Margin="10,0,20,19"
VerticalAlignment="Bottom"
Text="{Binding ElementName=me, Path=InfoText}"
x:Name="txtToolTipDetail" />
x:Name="txtToolTipDetail" d:LayoutOverrides="Height" />
<TextBlock
FontSize="12"
FontWeight="Normal"
Foreground="#FF141414"
TextWrapping="Wrap"
Margin="82,42,20,44.96"
x:Name="txtToolTipDetail_Copy" ><Run Text="Data binding is simple: this user control automatically derived the DataContext of the TaskbarIcon." Language="de-ch"/></TextBlock>
</Grid>
</UserControl>

View File

@@ -80,6 +80,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="FancyBalloon.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="FancyPopup.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -101,6 +105,9 @@
<Compile Include="Commands\TaskbarIconCommands.cs" />
<Compile Include="Commands\HideMainWindowCommand.cs" />
<Compile Include="Commands\ShowMainWindowCommand.cs" />
<Compile Include="FancyBalloon.xaml.cs">
<DependentUpon>FancyBalloon.xaml</DependentUpon>
</Compile>
<Compile Include="FancyPopup.xaml.cs">
<DependentUpon>FancyPopup.xaml</DependentUpon>
</Compile>

View File

@@ -4,13 +4,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Window1"
Height="808"
Title="WPF NotifyIcon Sample"
Height="833"
Width="769"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:Sample_Project">
xmlns:local="clr-namespace:Sample_Project" MinWidth="750" MinHeight="800">
<Window.Resources>
<BooleanToVisibilityConverter
@@ -25,13 +25,36 @@
TypeName="tb:PopupActivationMode" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Storyboard x:Key="FadeToolTip"/>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="tb:TaskbarIcon.TaskbarIconToolTipOpen" SourceName="tb"/>
</Window.Triggers>
<Window.Background>
<LinearGradientBrush
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop
Color="#FFFFFFFF"
Offset="0" />
<GradientStop
Color="#FFFFE7D1"
Offset="1" />
</LinearGradientBrush>
</Window.Background>
<Window.Triggers>
<EventTrigger
RoutedEvent="tb:TaskbarIcon.TrayToolTipOpen"
SourceName="tb" />
</Window.Triggers>
<Grid>
<!--
THE TASKBARICON ELEMENT WAS DECLARED INLINE IN ORDER TO USE DATABINDING
FOR ITS PROPERTIES. IN A REAL-LIFE APP, YOU'D PROBABLY RATHER CREATE IT THROUGH
CODE OR DECLARE IT IN A RESOURCE DICTIONARY.
-->
<tb:TaskbarIcon
x:Name="tb"
VerticalAlignment="Top"
@@ -42,55 +65,39 @@
MenuActivation="{Binding Path=SelectedItem, ElementName=lstMenuTrigger, Mode=Default}"
PopupActivation="{Binding Path=SelectedItem, ElementName=lstPopupTrigger, Mode=Default}">
<tb:TaskbarIcon.TaskbarIconPopup>
<tb:TaskbarIcon.TrayPopup>
<!-- the control will be put into a popup with an explicit DataContext -->
<local:FancyPopup />
</tb:TaskbarIcon.TaskbarIconPopup>
<tb:TaskbarIcon.TaskbarIconToolTip>
</tb:TaskbarIcon.TrayPopup>
<tb:TaskbarIcon.TrayToolTip>
<!-- the control will be put into a tooltip with an explicit DataContext -->
<local:FancyToolTip
Opacity="0.85"
InfoText="{Binding Path=ToolTipText}" />
</tb:TaskbarIcon.TaskbarIconToolTip>
</tb:TaskbarIcon.TrayToolTip>
</tb:TaskbarIcon>
<!-- EVERYTHING BELOW IS JUST PLUMBING FOR THE SAMPLE -->
<Button
x:Name="btn"
Click="OnClick"
Content="Click me"
Height="24"
Margin="0,70,68,0"
VerticalAlignment="Top"
Width="73"
HorizontalAlignment="Right" />
<Button
Height="23"
HorizontalAlignment="Right"
Margin="0,116,66,0"
x:Name="button1"
VerticalAlignment="Top"
Width="75"
Content="Button" />
<CheckBox
HorizontalAlignment="Left"
Margin="8,116,0,0"
Margin="12,64.04,0,0"
VerticalAlignment="Top"
Width="155.42"
Content="Taskbar Icon Visible"
Content="NotifyIcon Visible"
x:Name="iconVisibility"
IsChecked="True" />
<ListBox
HorizontalAlignment="Left"
Margin="8,171,0,0"
Margin="12,122,0,0"
Width="123"
IsSynchronizedWithCurrentItem="True"
Height="51"
@@ -111,7 +118,7 @@
</ListBox>
<TextBlock
HorizontalAlignment="Left"
Margin="8,149,0,0"
Margin="12,100,0,0"
VerticalAlignment="Top"
Width="Auto"
Height="22"
@@ -119,9 +126,9 @@
Text="Taskbar Icon:"
Language="de-ch" /></TextBlock>
<Grid
Margin="0,0,10,24"
VerticalAlignment="Bottom"
Height="242"
Margin="0,544.58,10,0"
VerticalAlignment="Top"
Height="210"
Width="358"
HorizontalAlignment="Right"
x:Name="Balloons">
@@ -131,13 +138,13 @@
BorderBrush="#FF000000"
BorderThickness="2,2,2,2" />
<TextBox
Margin="127,20,15,0"
Margin="125,0,17,133"
x:Name="txtBalloonTitle"
VerticalAlignment="Top"
VerticalAlignment="Bottom"
Height="23" />
<TextBox
Margin="127,65,15,97"
x:Name="txtBalloonText" />
Margin="125,0,17,76"
x:Name="txtBalloonText" AcceptsReturn="True" Height="47" VerticalAlignment="Bottom" d:LayoutOverrides="VerticalAlignment" />
<RadioButton
HorizontalAlignment="Left"
Margin="14,0,0,54"
@@ -145,23 +152,22 @@
Width="111"
Height="22"
Content="Show as Info"
IsChecked="True" />
IsChecked="True"
x:Name="rbInfo" />
<TextBlock
HorizontalAlignment="Left"
Margin="14,20,0,0"
VerticalAlignment="Top"
Margin="14,0,0,133"
VerticalAlignment="Bottom"
Width="85"
Height="23"
TextWrapping="Wrap"><Run
Text="Balloon Title"
Language="de-ch" /></TextBlock>
<TextBlock
Margin="14,65,0,0"
VerticalAlignment="Top"
Height="23"
Margin="14,0,0,100"
TextWrapping="Wrap"
HorizontalAlignment="Left"
Width="85"><Run
Width="85" Height="23" VerticalAlignment="Bottom" d:LayoutOverrides="VerticalAlignment"><Run
Text="Balloon Text"
Language="de-ch" /></TextBlock>
<RadioButton
@@ -170,27 +176,46 @@
Height="22"
Content="Show as Error"
HorizontalAlignment="Left"
Width="111" />
Width="111"
x:Name="rbError" />
<RadioButton
Margin="14,0,0,10"
VerticalAlignment="Bottom"
Height="22"
Content="Show Custom Icon"
HorizontalAlignment="Left"
Width="130" />
Width="130"
x:Name="rbCustomIcon" />
<Button
HorizontalAlignment="Right"
Margin="0,0,21,12.52"
Margin="0,0,17,43"
x:Name="showBalloonTip"
Width="120"
Content="Show Balloon Tip"
VerticalAlignment="Bottom"
Height="23" />
Height="23"
Click="showBalloonTip_Click" />
<TextBlock
Margin="14,10,17,0"
VerticalAlignment="Top"
Height="33"
TextWrapping="Wrap"><Run
Text="Standard balloon tips. You can use custom icons under all OS versions."
Language="de-ch" /></TextBlock>
<Button
HorizontalAlignment="Right"
Margin="0,0,17,12.52"
x:Name="hideBalloonTip"
Width="120"
Content="Hide Balloon Tip"
VerticalAlignment="Bottom"
Height="23"
Click="hideBalloonTip_Click" />
</Grid>
<Grid
HorizontalAlignment="Left"
Margin="12,0,0,24"
VerticalAlignment="Bottom"
Margin="12,512.58,0,0"
VerticalAlignment="Top"
Width="307"
Height="242"
x:Name="Popups">
@@ -205,70 +230,91 @@
ItemsSource="{Binding Mode=OneWay, Source={StaticResource ActivationModes}}"
Margin="14,115,97,10"
SelectedIndex="0" />
<RadioButton
HorizontalAlignment="Left"
Margin="14,19,0,0"
VerticalAlignment="Top"
Width="Auto"
Height="22"
Content="Use simple Popup"
IsChecked="True" />
<RadioButton
Margin="14,41,97,0"
VerticalAlignment="Top"
Height="22"
Content="Use Popup with Storyboard" />
<TextBlock
Margin="14,83,106,0"
Margin="14,10,10,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
Height="22"><Run
Text="Display Popup on:"
Height="105"><Run
Text="If the user clicks on the Taskbar Icon, a popup can be opened and displayed. Unlike custom ToolTips, this works under Windows xp as well. In case left-clicks are used, popups are displayed with a delay to ensure the user does not double-click. Trigger is determined by the "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="PopupActivation "
Language="de-ch" /><Run
Text="property."
Language="de-ch" /></TextBlock>
</Grid>
<Grid
Margin="0,323,10,276"
Margin="0,166.38,10,0"
Width="358"
HorizontalAlignment="Right"
x:Name="ToolTips">
x:Name="ToolTips" Height="271" VerticalAlignment="Top">
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="#FF000000"
BorderThickness="2,2,2,2" />
<RadioButton
Margin="14,38,10,42"
Content="Use custom ToolTip on MouseOver (Vista and above)" />
<RadioButton
Margin="14,60,97,0"
VerticalAlignment="Top"
Height="22"
Content="Use custom ToolTip with Storyboard" />
<RadioButton
Margin="14,16,10,0"
Content="Only use ToolTipText (no custom tooltip)"
VerticalAlignment="Top"
Height="22"
IsChecked="True" />
<TextBox
Margin="14,0,21,19"
Margin="10,0,25,86"
x:Name="txtToolTipText"
VerticalAlignment="Bottom"
Height="23"
Text="Click to open tooltip" />
Text="THIS IS A SAMPLE TEXT...."
Foreground="#FFFF0000" />
<TextBlock
Margin="14,0,157,52"
Margin="10,132,25,119"
TextWrapping="Wrap"><Run
Text="ToolTipText:"
Language="de-ch" /></TextBlock>
<TextBlock
Margin="10,10,10,0"
VerticalAlignment="Top"
Height="112"
TextWrapping="Wrap"><Run
Text="If the user moves the mouse over the Taskbar Icon, a tooltip can be displayed. Starting from Windows Vista, we have convenient events to display and hide tooltips. If we can, the "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="TrayToolTip "
Language="de-ch" /><Run
Text="control is being displayed."
Language="de-ch" /><LineBreak /><Run
Text="If "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="TrayToolTip "
Language="de-ch" /><Run
Text="is not set or the app runs under an older OS (e.g. xp), the control falls back to the "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="ToolTipText "
Language="de-ch" /><Run
Text="property."
Language="de-ch" /></TextBlock>
<Button
HorizontalAlignment="Left"
Margin="10,0,0,20"
VerticalAlignment="Bottom"
Width="147"
Height="24"
Content="Remove Custom ToolTip"
Name="removeToolTip"
Click="removeToolTip_Click" />
<TextBlock
Margin="10,0,25,53"
VerticalAlignment="Bottom"
Height="16"
TextWrapping="Wrap"><Run
Text="ToolTip Text:"
Text="Click to fall back to ToolTipText (sets TrayToolTip to null):"
Language="de-ch" /></TextBlock>
</Grid>
<Grid
HorizontalAlignment="Left"
Margin="12,323,0,276"
Margin="12,231.58,0,0"
Width="307"
x:Name="ContextMenus">
x:Name="ContextMenus" Height="271" VerticalAlignment="Top">
<Border
BorderBrush="#FF000000"
BorderThickness="2,2,2,2" />
@@ -281,19 +327,58 @@
VerticalAlignment="Bottom"
SelectedIndex="1" />
<TextBlock
Margin="10,10,110,0"
Margin="10,108,48,0"
VerticalAlignment="Top"
Height="22"
TextWrapping="Wrap"><Run
Text="Trigger Context Menu:"
Text="Mouse events that open the context menu:"
Language="de-ch" /></TextBlock>
<TextBlock
Margin="10,10,10,0"
VerticalAlignment="Top"
Height="78"
TextWrapping="Wrap"><Run
Text="Assign a custon context menu through the "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="ContextMenu "
Language="de-ch" /><Run
Text="property of the TaskbarIcon. The "
Language="de-ch" /><Run
FontStyle="Italic"
FontWeight="Bold"
Text="MenuActivation "
Language="de-ch" /><Run
Text="property determines what mouse events open the context menu."
Language="de-ch" /></TextBlock>
</Grid>
<TextBlock
Margin="10,10,45,0"
Margin="10,10,0,0"
VerticalAlignment="Top"
Height="Auto"
TextWrapping="Wrap"
FontWeight="Bold"
FontSize="14"><Run Text="Some Title Goes Here..." Language="de-ch"/></TextBlock>
FontSize="14" Width="309" HorizontalAlignment="Left"><Run
Text="WPF NotifyIcon - RC 1.0"
Language="de-ch" /></TextBlock>
<TextBlock
HorizontalAlignment="Right"
Margin="0,10,10,0"
VerticalAlignment="Top"
Width="358"
Height="146.38"
FontSize="14"
FontStyle="Italic"
Foreground="#FF303030"
TextWrapping="Wrap"><Run Text="This is my first shot at this control and a think a few additions might make sense." Language="de-ch"/><LineBreak/><Run Text="Play around and feel free to commit critical feedback - it's appreciated :)" Language="de-ch"/><LineBreak/><Run Text="" Language="de-ch"/><LineBreak/><Run Foreground="#FF067EBD" Text="Feedback and Updates:" Language="de-ch"/><LineBreak/><Run Foreground="#FF067EBD" Text="http://www.hardcodet.net " Language="de-ch"/><Run FontSize="10" Foreground="#FF067EBD" Text="(watch the spelling" Language="de-ch"/><Run Foreground="#FF067EBD" Text=")" Language="de-ch"/></TextBlock>
<TextBlock Margin="12,0,10,10" VerticalAlignment="Bottom" Height="22.42" TextWrapping="Wrap" FontWeight="Bold" Foreground="#FFFFA051"><Run Text="Copyright (c) 2009 Philipp Sumi. This is prerelease software, realeased under the CodeProject Open License (CPOL)" Language="de-ch"/></TextBlock>
<Grid HorizontalAlignment="Right" Margin="0,0,10,262.42" VerticalAlignment="Bottom" Width="358" Height="87.2" x:Name="CustomBalloons">
<Border HorizontalAlignment="Stretch" Width="Auto" BorderThickness="2,2,2,2" BorderBrush="#FF000000"/>
<Button Content="Display Message" x:Name="showCustomBalloon"
Click="showCustomBalloon_Click" HorizontalAlignment="Right" Margin="0,0,24.377,10.52" Width="107.623" Height="23" VerticalAlignment="Bottom" />
<TextBox VerticalAlignment="Bottom" Height="23" Text="Balloon Title" TextWrapping="Wrap" Margin="10,0,173,10" x:Name="customBalloonTitle"/>
<TextBlock Margin="10,10,24.377,0" VerticalAlignment="Top" TextWrapping="Wrap"><Run Text="Custom Balloon Tips are more flexible then standard tips when it comes to styling..." Language="de-ch"/></TextBlock>
</Grid>
</Grid>
</Window>

View File

@@ -1,17 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Controls.Primitives;
using Hardcodet.Wpf.TaskbarNotification;
namespace Sample_Project
{
@@ -20,23 +9,55 @@ namespace Sample_Project
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void OnClick(object sender, RoutedEventArgs e)
/// <summary>
/// Displays a balloon tip.
/// </summary>
private void showBalloonTip_Click(object sender, RoutedEventArgs e)
{
if (tb.Visibility == System.Windows.Visibility.Visible)
string title = txtBalloonTitle.Text;
string message = txtBalloonText.Text;
if (rbCustomIcon.IsChecked == true)
{
tb.Visibility = System.Windows.Visibility.Collapsed;
//just display the icon on the tray
var icon = tb.Icon;
tb.ShowBalloonTip(title, message, icon);
}
else
{
tb.Visibility = Visibility.Visible;
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);
}
}
}
}