Added Ambilight-Example-Project

This commit is contained in:
DarthAffe committed 2016-11-06 00:32:40 +01:00
1 parent 662085a346
commit 74824e3363
33 files changed
+1609

No files matched your search

@@ -0,0 +1,45 @@
using System;
using Example_Ambilight_full.TakeAsIs.Model;
namespace Example_Ambilight_full.TakeAsIs
{
public class AmbilightSettings
{
private AmbienceCreatorType _ambienceCreatorType = AmbienceCreatorType.Mirror;
#region Properties & Fields
public AmbienceCreatorType AmbienceCreatorType
{
get { return _ambienceCreatorType; }
set
{
if (_ambienceCreatorType != value)
{
_ambienceCreatorType = value;
AmbienceCreatorTypeChanged?.Invoke(this, new EventArgs());
}
}
}
public int OffsetLeft { get; set; } = 0;
public int OffsetRight { get; set; } = 0;
public int OffsetTop { get; set; } = 0;
public int OffsetBottom { get; set; } = 0;
public int Downsampling { get; set; } = 2;
public double MirroredAmount { get; set; } = 10;
public SmoothMode SmoothMode { get; set; } = SmoothMode.Low;
public BlackBarDetectionMode BlackBarDetectionMode { get; set; } = BlackBarDetectionMode.Bottom;
public FlipMode FlipMode { get; set; } = FlipMode.Vertical;
#endregion
#region Events
public event EventHandler AmbienceCreatorTypeChanged;
#endregion
}
}
@@ -0,0 +1,93 @@
using System;
using System.Windows;
using System.Windows.Controls;
using Example_Ambilight_full.TakeAsIs.Model.Extensions;
namespace Example_Ambilight_full.TakeAsIs.Helper
{
public class CheckboxEnumFlagHelper
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty FlagsProperty = DependencyProperty.RegisterAttached(
"Flags", typeof(Enum), typeof(CheckboxEnumFlagHelper), new FrameworkPropertyMetadata(default(Enum), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FlagsChanged));
public static void SetFlags(DependencyObject element, Enum value)
{
element.SetValue(FlagsProperty, value);
}
public static Enum GetFlags(DependencyObject element)
{
return (Enum)element.GetValue(FlagsProperty);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached(
"Value", typeof(Enum), typeof(CheckboxEnumFlagHelper), new PropertyMetadata(default(Enum), ValueChanged));
public static void SetValue(DependencyObject element, Enum value)
{
element.SetValue(ValueProperty, value);
}
public static Enum GetValue(DependencyObject element)
{
return (Enum)element.GetValue(ValueProperty);
}
// ReSharper restore InconsistentNaming
#endregion
#region Methods
private static void FlagsChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
UpdateTarget(dependencyObject as CheckBox, dependencyPropertyChangedEventArgs.NewValue as Enum);
}
private static void ValueChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
CheckBox checkbox = dependencyObject as CheckBox;
if (checkbox == null) return;
checkbox.Checked -= UpdateSource;
checkbox.Unchecked -= UpdateSource;
if (dependencyPropertyChangedEventArgs.NewValue != null)
{
checkbox.Checked += UpdateSource;
checkbox.Unchecked += UpdateSource;
}
UpdateTarget(checkbox, GetFlags(checkbox));
}
private static void UpdateTarget(CheckBox checkbox, Enum flags)
{
if (checkbox == null) return;
Enum value = GetValue(checkbox);
checkbox.IsChecked = value != null && (flags?.HasFlag(value) ?? false);
}
private static void UpdateSource(object sender, RoutedEventArgs routedEventArgs)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox == null) return;
Enum flags = GetFlags(checkbox);
Enum value = GetValue(checkbox);
if (value == null) return;
if (checkbox.IsChecked ?? false)
SetFlags(checkbox, flags == null ? value : flags.SetFlag(value, true, flags.GetType()));
else
SetFlags(checkbox, flags?.SetFlag(value, false, flags.GetType()));
}
#endregion
}
}
@@ -0,0 +1,50 @@
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace Example_Ambilight_full.TakeAsIs.Helper
{
public static class SerializationHelper
{
public static void SaveObjectToFile<T>(T serializableObject, string path)
{
if (serializableObject == null) return;
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Seek(0, SeekOrigin.Begin);
xmlDocument.Load(stream);
xmlDocument.Save(path);
}
}
catch {/* Catch'em all */}
}
public static T LoadObjectFromFile<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) return default(T);
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader sr = new StringReader(xmlString))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (XmlReader reader = new XmlTextReader(sr))
return (T)serializer.Deserialize(reader);
}
}
catch {/* Catch'em all */}
return default(T);
}
}
}
@@ -0,0 +1,13 @@
using System.ComponentModel;
namespace Example_Ambilight_full.TakeAsIs.Model
{
public enum AmbienceCreatorType
{
[Description("Mirror")]
Mirror,
[Description("Extend")]
Extend
}
}
@@ -0,0 +1,14 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model
{
[Flags]
public enum BlackBarDetectionMode
{
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3,
}
}
@@ -0,0 +1,26 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model.Extensions
{
public static class EnumExtension
{
#region Methods
public static Enum SetFlag(this Enum e, Enum value, bool set, Type t)
{
if (e == null || value == null || t == null) return e;
int eValue = Convert.ToInt32(e);
int valueValue = Convert.ToInt32(value);
if (set)
eValue |= valueValue;
else
eValue &= ~valueValue;
return (Enum)Enum.ToObject(t, eValue);
}
#endregion
}
}
@@ -0,0 +1,89 @@
namespace Example_Ambilight_full.TakeAsIs.Model.Extensions
{
public static class PixelDataExtension
{
#region Methods
public static int DetectBlackBarLeft(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarWidth = 0;
for (int x = rightBorder - 1; x >= offsetLeft; x--)
{
for (int y = offsetTop; y < bottomBorder; y++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarWidth;
}
blackBarWidth++;
}
return width;
}
public static int DetectBlackBarRight(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarWidth = 0;
for (int x = offsetLeft; x < rightBorder; x++)
{
for (int y = offsetTop; y < bottomBorder; y++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarWidth;
}
blackBarWidth++;
}
return width;
}
public static int DetectBlackBarTop(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarHeight = 0;
for (int y = offsetTop; y < bottomBorder; y++)
{
for (int x = offsetLeft; x < rightBorder; x++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarHeight;
}
blackBarHeight++;
}
return height;
}
public static int DetectBlackBarBottom(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarHeight = 0;
for (int y = bottomBorder - 1; y >= offsetTop; y--)
{
for (int x = offsetLeft; x < rightBorder; x++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarHeight;
}
blackBarHeight++;
}
return height;
}
#endregion
}
}
@@ -0,0 +1,12 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model
{
[Flags]
public enum FlipMode
{
None = 0,
Vertical = 1 << 0,
Horizontal = 1 << 1
}
}
@@ -0,0 +1,19 @@
using System.ComponentModel;
namespace Example_Ambilight_full.TakeAsIs.Model
{
public enum SmoothMode
{
[Description("None")]
None,
[Description("Low")]
Low,
[Description("Medium")]
Medium,
[Description("High")]
High
}
}
@@ -0,0 +1,64 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Media;
using SharpDX;
using SharpDX.Direct3D9;
namespace Example_Ambilight_full.TakeAsIs.ScreenCapturing
{
public class DX9ScreenCapture : IScreenCapture
{
#region Properties & Fields
private Device _device;
private Surface _surface;
private byte[] _buffer;
public int Width { get; }
public int Height { get; }
public PixelFormat PixelFormat => PixelFormats.Bgr24;
#endregion
#region Constructors
public DX9ScreenCapture()
{
Width = (int)System.Windows.SystemParameters.PrimaryScreenWidth;
Height = (int)System.Windows.SystemParameters.PrimaryScreenHeight;
PresentParameters presentParams = new PresentParameters(Width, Height)
{
Windowed = true,
SwapEffect = SwapEffect.Discard
};
_device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.SoftwareVertexProcessing, presentParams);
_surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch);
_buffer = new byte[Width * Height * 4];
}
#endregion
#region Methods
public byte[] CaptureScreen()
{
_device.GetFrontBufferData(0, _surface);
DataRectangle dr = _surface.LockRectangle(LockFlags.None);
Marshal.Copy(dr.DataPointer, _buffer, 0, _buffer.Length);
_surface.UnlockRectangle();
return _buffer;
}
public void Dispose()
{
_device?.Dispose();
_surface?.Dispose();
}
#endregion
}
}
@@ -0,0 +1,18 @@
using System;
using System.Windows.Media;
namespace Example_Ambilight_full.TakeAsIs.ScreenCapturing
{
public interface IScreenCapture : IDisposable
{
int Width { get; }
int Height { get; }
PixelFormat PixelFormat { get; }
/// <summary>
/// As Pixel-Data BGRA
/// </summary>
/// <returns>The Pixel-Data</returns>
byte[] CaptureScreen();
}
}
@@ -0,0 +1,50 @@
using System;
using System.Windows.Input;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class ActionCommand : ICommand
{
#region Properties & Fields
private readonly Func<bool> _canExecute;
private readonly Action _command;
#endregion
#region Constructors
public ActionCommand(Action command, Func<bool> canExecute = null)
{
this._command = command;
this._canExecute = canExecute;
}
#endregion
#region Methods
public bool CanExecute(object parameter)
{
return _canExecute?.Invoke() ?? true;
}
public void Execute(object parameter)
{
_command?.Invoke();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, new EventArgs());
}
#endregion
#region Events
public event EventHandler CanExecuteChanged;
#endregion
}
}
@@ -0,0 +1,167 @@
<UserControl x:Class="Example_Ambilight_full.TakeAsIs.UI.ConfigView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:helper="clr-namespace:Example_Ambilight_full.TakeAsIs.Helper"
xmlns:model="clr-namespace:Example_Ambilight_full.TakeAsIs.Model"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:ui="clr-namespace:Example_Ambilight_full.TakeAsIs.UI">
<!-- Quick'n'Dirty - you really shouldn't implement a View like this ... -->
<UserControl.Resources>
<ui:EnumDescriptionConverter x:Key="HEnumDescriptionConverter" />
<ObjectDataProvider x:Key="SmoothModeEnumValues" ObjectType="{x:Type system:Enum}" MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="model:SmoothMode" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="AmbienceCreatorTypeValues" ObjectType="{x:Type system:Enum}" MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="model:AmbienceCreatorType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource HEnumDescriptionConverter}}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,4,0" />
</Style>
<Style TargetType="controls:NumericUpDown" BasedOn="{StaticResource {x:Type controls:NumericUpDown}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Border Padding="16" Background="#CECECE" BorderBrush="#2E2E2E" BorderThickness="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="160" />
<ColumnDefinition Width="32" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="160" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<!-- Update-Rate-->
<TextBlock Grid.Row="0" Grid.Column="0" Text="Update-Rate (FPS):" />
<controls:NumericUpDown Grid.Row="0" Grid.Column="1"
Minimum="1" Maximum="60"
Value="{Binding Path=UpdateRate, Mode=TwoWay}" />
<!-- AmbienceCreatorType -->
<TextBlock Grid.Row="1" Grid.Column="0" Text="Ambilight-Mode:"/>
<ComboBox Grid.Row="1" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource AmbienceCreatorTypeValues}}"
SelectedItem="{Binding Path=Settings.AmbienceCreatorType}" />
<!-- MirrorAmount & Downsampling-->
<TextBlock Grid.Row="2" Grid.Column="0" Text="Mirrored Amount (%):" />
<controls:NumericUpDown Grid.Row="2" Grid.Column="1"
Minimum="0" Maximum="100"
Value="{Binding Path=Settings.MirroredAmount, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Grid.Column="3" Text="Downsampling:" />
<controls:NumericUpDown Grid.Row="2" Grid.Column="4"
Minimum="1" Maximum="20"
Value="{Binding Path=Settings.Downsampling, Mode=TwoWay}" />
<!-- SmoothMode -->
<TextBlock Grid.Row="3" Grid.Column="0" Text="Smoothing:" />
<ComboBox Grid.Row="3" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource SmoothModeEnumValues}}"
SelectedItem="{Binding Path=Settings.SmoothMode}" />
<!-- FlipMode -->
<TextBlock Grid.Row="4" Grid.Column="0" Text="Flip Horizontal:" />
<CheckBox Grid.Row="4" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:FlipMode.Horizontal}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.FlipMode}" />
<TextBlock Grid.Row="4" Grid.Column="3" Text="Flip Vertical:" />
<CheckBox Grid.Row="4" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:FlipMode.Vertical}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.FlipMode}" />
<!-- Horizontal offsets -->
<TextBlock Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="4" FontWeight="Black" Text="Offset" />
<TextBlock Grid.Row="6" Grid.Column="0" Text="Left:" />
<controls:NumericUpDown Grid.Row="6" Grid.Column="1"
Minimum="0"
Value="{Binding Path=Settings.OffsetLeft, Mode=TwoWay}" />
<TextBlock Grid.Row="6" Grid.Column="3" Text="Right:" />
<controls:NumericUpDown Grid.Row="6" Grid.Column="4"
Minimum="0"
Value="{Binding Path=Settings.OffsetRight, Mode=TwoWay}" />
<!-- Vertical offsets -->
<TextBlock Grid.Row="7" Grid.Column="0" Text="Top:" />
<controls:NumericUpDown Grid.Row="7" Grid.Column="1" Minimum="0"
Value="{Binding Path=Settings.OffsetTop, Mode=TwoWay}" />
<TextBlock Grid.Row="7" Grid.Column="3" Text="Bottom:"/>
<controls:NumericUpDown Grid.Row="7" Grid.Column="4" Minimum="0"
Value="{Binding Path=Settings.OffsetBottom, Mode=TwoWay}" />
<!-- Horizontal BlackBar-detection -->
<TextBlock Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="4" FontWeight="Black" Text="Black-Bar detection" />
<TextBlock Grid.Row="9" Grid.Column="0" Text="Left:" />
<CheckBox Grid.Row="9" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Left}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<TextBlock Grid.Row="9" Grid.Column="3" Text="Right:" />
<CheckBox Grid.Row="9" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Right}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<!-- Vertical BlackBar-detection -->
<TextBlock Grid.Row="10" Grid.Column="0" Text="Top:" />
<CheckBox Grid.Row="10" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Top}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<TextBlock Grid.Row="10" Grid.Column="3" Text="Bottom:" />
<CheckBox Grid.Row="10" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Bottom}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<Button Grid.Row="12" Grid.Column="4" Command="{Binding ExitCommand}" Content="Exit" />
</Grid>
</Border>
</UserControl>
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Example_Ambilight_full.TakeAsIs.UI
{
/// <summary>
/// Interaction logic for ConfigView.xaml
/// </summary>
public partial class ConfigView : UserControl
{
public ConfigView()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,46 @@
using System;
using System.Windows;
using CUE.NET;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class ConfigViewModel
{
#region Properties & Fields
public AmbilightSettings Settings { get; }
public int UpdateRate
{
get { return (int)Math.Round(1f / CueSDK.UpdateFrequency); }
set { CueSDK.UpdateFrequency = 1f / value; }
}
#endregion
#region Commands
private ActionCommand _exitCommand;
public ActionCommand ExitCommand => _exitCommand ?? (_exitCommand = new ActionCommand(Exit));
#endregion
#region Constructors
public ConfigViewModel(AmbilightSettings settings)
{
this.Settings = settings;
}
#endregion
#region Methods
private void Exit()
{
Application.Current.Shutdown();
}
#endregion
}
}
@@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Windows.Data;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class EnumDescriptionConverter : IValueConverter
{
#region Methods
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return enumObj.ToString();
DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
return attrib?.Description;
}
#endregion
}
}
@@ -0,0 +1,16 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:ui="clr-namespace:Example_Ambilight_full.TakeAsIs.UI">
<tb:TaskbarIcon x:Key="Taskbar"
ToolTipText="Keyboard-Ambilight"
IconSource="../../Resources/ambilight.ico"
PopupActivation="All">
<tb:TaskbarIcon.TrayPopup>
<ui:ConfigView />
</tb:TaskbarIcon.TrayPopup>
</tb:TaskbarIcon>
</ResourceDictionary>