From 9bae55d17fb966bc8c5b68c4e45eafb0cc179b73 Mon Sep 17 00:00:00 2001 From: Panagiotis Kanavos Date: Tue, 16 Aug 2011 17:01:53 +0300 Subject: [PATCH] Added WPF client based on Caliburn.Micro --- trunk/NotifyIconWpf/BalloonIcon.cs | 49 + trunk/NotifyIconWpf/DefaultTrayIcon.ico | Bin 0 -> 1150 bytes .../NotifyIconWpf/Diagrams/TaskbarIcon Overview.cd | 30 + trunk/NotifyIconWpf/Interop/BalloonFlags.cs | 55 + trunk/NotifyIconWpf/Interop/IconDataMembers.cs | 67 + trunk/NotifyIconWpf/Interop/IconState.cs | 23 + trunk/NotifyIconWpf/Interop/MouseEvent.cs | 48 + trunk/NotifyIconWpf/Interop/NotifyCommand.cs | 39 + trunk/NotifyIconWpf/Interop/NotifyIconData.cs | 166 + trunk/NotifyIconWpf/Interop/NotifyIconVersion.cs | 25 + trunk/NotifyIconWpf/Interop/Point.cs | 14 + trunk/NotifyIconWpf/Interop/TrayInfo.cs | 171 + trunk/NotifyIconWpf/Interop/WinApi.cs | 87 + trunk/NotifyIconWpf/Interop/WindowClass.cs | 31 + trunk/NotifyIconWpf/Interop/WindowMessageSink.cs | 369 ++ trunk/NotifyIconWpf/NotifyIconWpf.csproj | 142 + trunk/NotifyIconWpf/PopupActivationMode.cs | 69 + trunk/NotifyIconWpf/Properties/AssemblyInfo.cs | 57 + .../NotifyIconWpf/Properties/Resources.Designer.cs | 70 + trunk/NotifyIconWpf/Properties/Resources.resx | 124 + trunk/NotifyIconWpf/RoutedEventHelper.cs | 81 + trunk/NotifyIconWpf/TaskbarIcon.Declarations.cs | 1869 +++++++++ trunk/NotifyIconWpf/TaskbarIcon.cs | 1016 +++++ trunk/NotifyIconWpf/Util.cs | 308 ++ trunk/NotifyIconWpf/pithos.snk | Bin 0 -> 596 bytes trunk/Pithos.Client.WPF/App.xaml | 17 + trunk/Pithos.Client.WPF/App.xaml.cs | 21 + trunk/Pithos.Client.WPF/AppBootstrapper.cs | 81 + .../Caliburn/Micro/Logging/DebugLogger.cs | 85 + .../Configuration/PithosSettings.cs | 123 + trunk/Pithos.Client.WPF/FileEntry.cs | 8 + trunk/Pithos.Client.WPF/IShell.cs | 3 + trunk/Pithos.Client.WPF/Images/Accounts.png | Bin 0 -> 1854 bytes trunk/Pithos.Client.WPF/Images/Advanced.png | Bin 0 -> 2618 bytes trunk/Pithos.Client.WPF/Images/Bandwidth.png | Bin 0 -> 1950 bytes trunk/Pithos.Client.WPF/Images/General.png | Bin 0 -> 2688 bytes trunk/Pithos.Client.WPF/Images/Network.png | Bin 0 -> 1496 bytes trunk/Pithos.Client.WPF/Images/Tray.ico | Bin 0 -> 1078 bytes trunk/Pithos.Client.WPF/Images/TrayInSynch.ico | Bin 0 -> 1078 bytes trunk/Pithos.Client.WPF/Images/TraySynching.ico | Bin 0 -> 1078 bytes trunk/Pithos.Client.WPF/MainWindow.xaml | 8 + trunk/Pithos.Client.WPF/MainWindow.xaml.cs | 27 + trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj | 183 + trunk/Pithos.Client.WPF/PithosCommand.cs | 45 + trunk/Pithos.Client.WPF/PithosStyles.xaml | 10 + trunk/Pithos.Client.WPF/PreferencesView.xaml | 189 + trunk/Pithos.Client.WPF/PreferencesView.xaml.cs | 36 + trunk/Pithos.Client.WPF/PreferencesViewModel.cs | 285 ++ trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs | 55 + .../Properties/Resources.Designer.cs | 63 + trunk/Pithos.Client.WPF/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 202 + .../Pithos.Client.WPF/Properties/Settings.settings | 56 + .../Pithos.Client.WPF/ShellExtensionController.cs | 74 + trunk/Pithos.Client.WPF/ShellView.xaml | 53 + trunk/Pithos.Client.WPF/ShellViewModel.cs | 100 + trunk/Pithos.Client.WPF/WhistlerBlue.xaml | 4032 ++++++++++++++++++++ trunk/Pithos.Client.WPF/app.config | 79 + trunk/Pithos.Client.WPF/packages.config | 6 + trunk/Pithos.sln | 51 + .../Caliburn.Micro.1.2.0.nupkg | Bin 0 -> 1811782 bytes .../lib/Net40/Caliburn.Micro.dll | Bin 0 -> 96768 bytes .../lib/Net40/Caliburn.Micro.xml | 2422 ++++++++++++ .../lib/Net40/System.Windows.Interactivity.dll | Bin 0 -> 39936 bytes .../lib/Net40/System.Windows.Interactivity.xml | 1072 ++++++ .../lib/SL40-wp/Caliburn.Micro.Extensions.dll | Bin 0 -> 37888 bytes .../lib/SL40-wp/Caliburn.Micro.Extensions.xml | 900 +++++ .../lib/SL40-wp/Caliburn.Micro.dll | Bin 0 -> 114176 bytes .../lib/SL40-wp/Caliburn.Micro.xml | 2830 ++++++++++++++ .../lib/SL40-wp/System.Windows.Interactivity.dll | Bin 0 -> 33280 bytes .../lib/SL40-wp/System.Windows.Interactivity.xml | 964 +++++ .../lib/SL40/Caliburn.Micro.dll | Bin 0 -> 96256 bytes .../lib/SL40/Caliburn.Micro.xml | 2439 ++++++++++++ .../lib/SL40/System.Windows.Controls.dll | Bin 0 -> 370544 bytes .../lib/SL40/System.Windows.Controls.xml | 1726 +++++++++ .../lib/SL40/System.Windows.Interactivity.dll | Bin 0 -> 37376 bytes .../lib/SL40/System.Windows.Interactivity.xml | 1025 +++++ .../SL40/ar/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/bg/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ca/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/cs/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/da/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/de/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/el/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/es/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/et/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/eu/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/fi/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/fr/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/he/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/hr/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/hu/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/id/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/it/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ja/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ko/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/lt/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/lv/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ms/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/nl/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/no/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/pl/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../pt-BR/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/pt/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ro/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/ru/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/sk/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/sl/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/sv/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/th/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/tr/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/uk/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../SL40/vi/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../zh-Hans/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../zh-Hant/System.Windows.Controls.resources.dll | Bin 0 -> 178048 bytes .../tools/NET40/AppBootstrapper.cs | 57 + .../Caliburn.Micro.1.2.0/tools/NET40/IShell.cs | 4 + .../tools/NET40/ShellView.xaml | 13 + .../tools/NET40/ShellViewModel.cs | 7 + .../tools/SL40-WP/AppBootstrapper.cs | 72 + .../tools/SL40-WP/MainPageViewModel.cs | 3 + .../tools/SL40/AppBootstrapper.cs | 56 + .../Caliburn.Micro.1.2.0/tools/SL40/IShell.cs | 3 + .../Caliburn.Micro.1.2.0/tools/SL40/ShellView.xaml | 12 + .../tools/SL40/ShellViewModel.cs | 6 + .../Caliburn.Micro.1.2.0/tools/install.ps1 | 26 + .../Caliburn.Micro.Logging.1.2.nupkg | Bin 0 -> 9932 bytes .../content/Caliburn/Micro/Logging/DebugLogger.cs | 85 + .../lib/net40-client/Caliburn.Micro.Logging.dll | Bin 0 -> 6144 bytes .../lib/net40/Caliburn.Micro.Logging.dll | Bin 0 -> 6144 bytes 132 files changed, 24641 insertions(+) create mode 100644 trunk/NotifyIconWpf/BalloonIcon.cs create mode 100644 trunk/NotifyIconWpf/DefaultTrayIcon.ico create mode 100644 trunk/NotifyIconWpf/Diagrams/TaskbarIcon Overview.cd create mode 100644 trunk/NotifyIconWpf/Interop/BalloonFlags.cs create mode 100644 trunk/NotifyIconWpf/Interop/IconDataMembers.cs create mode 100644 trunk/NotifyIconWpf/Interop/IconState.cs create mode 100644 trunk/NotifyIconWpf/Interop/MouseEvent.cs create mode 100644 trunk/NotifyIconWpf/Interop/NotifyCommand.cs create mode 100644 trunk/NotifyIconWpf/Interop/NotifyIconData.cs create mode 100644 trunk/NotifyIconWpf/Interop/NotifyIconVersion.cs create mode 100644 trunk/NotifyIconWpf/Interop/Point.cs create mode 100644 trunk/NotifyIconWpf/Interop/TrayInfo.cs create mode 100644 trunk/NotifyIconWpf/Interop/WinApi.cs create mode 100644 trunk/NotifyIconWpf/Interop/WindowClass.cs create mode 100644 trunk/NotifyIconWpf/Interop/WindowMessageSink.cs create mode 100644 trunk/NotifyIconWpf/NotifyIconWpf.csproj create mode 100644 trunk/NotifyIconWpf/PopupActivationMode.cs create mode 100644 trunk/NotifyIconWpf/Properties/AssemblyInfo.cs create mode 100644 trunk/NotifyIconWpf/Properties/Resources.Designer.cs create mode 100644 trunk/NotifyIconWpf/Properties/Resources.resx create mode 100644 trunk/NotifyIconWpf/RoutedEventHelper.cs create mode 100644 trunk/NotifyIconWpf/TaskbarIcon.Declarations.cs create mode 100644 trunk/NotifyIconWpf/TaskbarIcon.cs create mode 100644 trunk/NotifyIconWpf/Util.cs create mode 100644 trunk/NotifyIconWpf/pithos.snk create mode 100644 trunk/Pithos.Client.WPF/App.xaml create mode 100644 trunk/Pithos.Client.WPF/App.xaml.cs create mode 100644 trunk/Pithos.Client.WPF/AppBootstrapper.cs create mode 100644 trunk/Pithos.Client.WPF/Caliburn/Micro/Logging/DebugLogger.cs create mode 100644 trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs create mode 100644 trunk/Pithos.Client.WPF/FileEntry.cs create mode 100644 trunk/Pithos.Client.WPF/IShell.cs create mode 100644 trunk/Pithos.Client.WPF/Images/Accounts.png create mode 100644 trunk/Pithos.Client.WPF/Images/Advanced.png create mode 100644 trunk/Pithos.Client.WPF/Images/Bandwidth.png create mode 100644 trunk/Pithos.Client.WPF/Images/General.png create mode 100644 trunk/Pithos.Client.WPF/Images/Network.png create mode 100644 trunk/Pithos.Client.WPF/Images/Tray.ico create mode 100644 trunk/Pithos.Client.WPF/Images/TrayInSynch.ico create mode 100644 trunk/Pithos.Client.WPF/Images/TraySynching.ico create mode 100644 trunk/Pithos.Client.WPF/MainWindow.xaml create mode 100644 trunk/Pithos.Client.WPF/MainWindow.xaml.cs create mode 100644 trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj create mode 100644 trunk/Pithos.Client.WPF/PithosCommand.cs create mode 100644 trunk/Pithos.Client.WPF/PithosStyles.xaml create mode 100644 trunk/Pithos.Client.WPF/PreferencesView.xaml create mode 100644 trunk/Pithos.Client.WPF/PreferencesView.xaml.cs create mode 100644 trunk/Pithos.Client.WPF/PreferencesViewModel.cs create mode 100644 trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs create mode 100644 trunk/Pithos.Client.WPF/Properties/Resources.Designer.cs create mode 100644 trunk/Pithos.Client.WPF/Properties/Resources.resx create mode 100644 trunk/Pithos.Client.WPF/Properties/Settings.Designer.cs create mode 100644 trunk/Pithos.Client.WPF/Properties/Settings.settings create mode 100644 trunk/Pithos.Client.WPF/ShellExtensionController.cs create mode 100644 trunk/Pithos.Client.WPF/ShellView.xaml create mode 100644 trunk/Pithos.Client.WPF/ShellViewModel.cs create mode 100644 trunk/Pithos.Client.WPF/WhistlerBlue.xaml create mode 100644 trunk/Pithos.Client.WPF/app.config create mode 100644 trunk/Pithos.Client.WPF/packages.config create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/Caliburn.Micro.1.2.0.nupkg create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/Net40/Caliburn.Micro.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/Net40/Caliburn.Micro.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/Net40/System.Windows.Interactivity.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/Net40/System.Windows.Interactivity.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/Caliburn.Micro.Extensions.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/Caliburn.Micro.Extensions.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/Caliburn.Micro.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/Caliburn.Micro.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/System.Windows.Interactivity.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40-wp/System.Windows.Interactivity.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/Caliburn.Micro.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/Caliburn.Micro.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/System.Windows.Controls.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/System.Windows.Controls.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/System.Windows.Interactivity.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/System.Windows.Interactivity.xml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ar/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/bg/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ca/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/cs/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/da/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/de/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/el/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/es/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/et/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/eu/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/fi/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/fr/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/he/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/hr/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/hu/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/id/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/it/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ja/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ko/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/lt/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/lv/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ms/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/nl/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/no/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/pl/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/pt-BR/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/pt/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ro/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/ru/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/sk/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/sl/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/sr-Cyrl-CS/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/sr-Latn-CS/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/sv/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/th/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/tr/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/uk/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/vi/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/zh-Hans/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/lib/SL40/zh-Hant/System.Windows.Controls.resources.dll create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/NET40/AppBootstrapper.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/NET40/IShell.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/NET40/ShellView.xaml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/NET40/ShellViewModel.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40-WP/AppBootstrapper.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40-WP/MainPageViewModel.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40/AppBootstrapper.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40/IShell.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40/ShellView.xaml create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/SL40/ShellViewModel.cs create mode 100644 trunk/packages/Caliburn.Micro.1.2.0/tools/install.ps1 create mode 100644 trunk/packages/Caliburn.Micro.Logging.1.2/Caliburn.Micro.Logging.1.2.nupkg create mode 100644 trunk/packages/Caliburn.Micro.Logging.1.2/content/Caliburn/Micro/Logging/DebugLogger.cs create mode 100644 trunk/packages/Caliburn.Micro.Logging.1.2/lib/net40-client/Caliburn.Micro.Logging.dll create mode 100644 trunk/packages/Caliburn.Micro.Logging.1.2/lib/net40/Caliburn.Micro.Logging.dll diff --git a/trunk/NotifyIconWpf/BalloonIcon.cs b/trunk/NotifyIconWpf/BalloonIcon.cs new file mode 100644 index 0000000..69d97eb --- /dev/null +++ b/trunk/NotifyIconWpf/BalloonIcon.cs @@ -0,0 +1,49 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + +namespace Hardcodet.Wpf.TaskbarNotification +{ + /// + /// Supported icons for the tray's balloon messages. + /// + public enum BalloonIcon + { + /// + /// The balloon message is displayed without an icon. + /// + None, + /// + /// An information is displayed. + /// + Info, + /// + /// A warning is displayed. + /// + Warning, + /// + /// An error is displayed. + /// + Error + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/DefaultTrayIcon.ico b/trunk/NotifyIconWpf/DefaultTrayIcon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e3ff3c4bf60174f7cc6140efc302f7098ae911fc GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x$w1a$TERC983*Voq8Zn3qs)g?tU zCpWjSlZ)G?#N^cfwRLs>laiAU35$rx5o-pYfPk)xhv)0k%Ig0cHg5Xg)7$q!R7}j2 zSpDJ>68b^GA#ZbX^8PnBH~*hJY0@V(H8o3O^;;S1>%>QePs>V8Sec)dvZ^pUW4fc2 znK7~Y&jq(p@p5TifL-HtaeCEjKBj2Twl4W)iS958p* z46CxdEXNo>cYZ=<#0UErw>LGotX#I#a^duT&$WwZ2XEiJ(QVq~NluyZk%rz@hK#t( z2z9p?%TG)6S+aPs?T&3*y|!&!nYefRy4>SO4khi_zRk0$q|iAw$XgVb{wP0p^M=}L zk2R}TyB<5VzvTGgy$weX?y5U^^l<5cy}OgQZ{3p6*WO}}O}_#s17l8docFGsJ2K|Z zo$I<~!@7(;+cq_9-?YAH|BkJ#ySHrUx^?~9!i}p}W&`zO^+Rn*e!#i2XS%0Mnc_Wt z>eRrEtCqFyShsTV)-}slZd2l!QxvW<-EUOKI-h>D{fXmd>5oym{@a#*ORO zWp7wAf9;~lJ$IXmGPflMdCKC_4-(Ib4$`g5PoH;i*Y-1y9y~bt^vRP0XO11d(o~$Y zI@;5os63G1=PEI0Qcv=sJv*lzJGgJg%7t^%!rbj8vDy2_evRV~c})C)e~se@_BD + + + + + + + + + N6qdVIeUdLmQtSUbiJhEGdYRjvJYXlhbEVBDKuPRO5s= + TaskbarIcon.cs + + + + + + + ABAEAAAAAAAAAAABAAAAAAAAAAAAAAAAAIAKAIAAAAA= + PopupActivationMode.cs + + + + + + AAAAAAAAAAAAAQAAAAAAABAAAAAAAAAAAAAAAEEAAAA= + BalloonIcon.cs + + + + \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/BalloonFlags.cs b/trunk/NotifyIconWpf/Interop/BalloonFlags.cs new file mode 100644 index 0000000..aa325ca --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/BalloonFlags.cs @@ -0,0 +1,55 @@ +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Flags that define the icon that is shown on a balloon + /// tooltip. + /// + public enum BalloonFlags + { + /// + /// No icon is displayed. + /// + None = 0x00, + /// + /// An information icon is displayed. + /// + Info = 0x01, + /// + /// A warning icon is displayed. + /// + Warning = 0x02, + /// + /// An error icon is displayed. + /// + Error = 0x03, + /// + /// Windows XP Service Pack 2 (SP2) and later. + /// Use a custom icon as the title icon. + /// + User = 0x04, + /// + /// Windows XP (Shell32.dll version 6.0) and later. + /// Do not play the associated sound. Applies only to balloon ToolTips. + /// + NoSound = 0x10, + /// + /// Windows Vista (Shell32.dll version 6.0.6) and later. The large version + /// of the icon should be used as the balloon icon. This corresponds to the + /// icon with dimensions SM_CXICON x SM_CYICON. If this flag is not set, + /// the icon with dimensions XM_CXSMICON x SM_CYSMICON is used.
+ /// - This flag can be used with all stock icons.
+ /// - 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).
+ /// - New customized icons (NIIF_USER with hBalloonIcon) must supply an + /// SM_CXICON x SM_CYICON version in the supplied icon (hBalloonIcon). + ///
+ LargeIcon = 0x20, + /// + /// Windows 7 and later. + /// + RespectQuietTime = 0x80 + + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/IconDataMembers.cs b/trunk/NotifyIconWpf/Interop/IconDataMembers.cs new file mode 100644 index 0000000..6156897 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/IconDataMembers.cs @@ -0,0 +1,67 @@ +using System; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Indicates which members of a structure + /// were set, and thus contain valid data or provide additional information + /// to the ToolTip as to how it should display. + /// + [Flags] + public enum IconDataMembers + { + /// + /// The message ID is set. + /// + Message = 0x01, + /// + /// The notification icon is set. + /// + Icon = 0x02, + /// + /// The tooltip is set. + /// + Tip = 0x04, + /// + /// State information () is set. This + /// applies to both and + /// . + /// + State = 0x08, + /// + /// The balloon ToolTip is set. Accordingly, the following + /// members are set: , + /// , , + /// and . + /// + Info = 0x10, + + /// + /// Internal identifier is set. Reserved, thus commented out. + /// + //Guid = 0x20, + + /// + /// Windows Vista (Shell32.dll version 6.0.6) and later. If the ToolTip + /// cannot be displayed immediately, discard it.
+ /// 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."
+ /// This modifies and must be combined with the flag. + ///
+ Realtime = 0x40, + /// + /// 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.
+ /// Note that the NIF_SHOWTIP flag is effective until the next call + /// to Shell_NotifyIcon. + ///
+ UseLegacyToolTips = 0x80 + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/IconState.cs b/trunk/NotifyIconWpf/Interop/IconState.cs new file mode 100644 index 0000000..338bb1b --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/IconState.cs @@ -0,0 +1,23 @@ +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// The state of the icon - can be set to + /// hide the icon. + /// + public enum IconState + { + /// + /// The icon is visible. + /// + Visible = 0x00, + /// + /// Hide the icon. + /// + Hidden = 0x01, + + /// + /// The icon is shared - currently not supported, thus commented out. + /// + //Shared = 0x02 + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/MouseEvent.cs b/trunk/NotifyIconWpf/Interop/MouseEvent.cs new file mode 100644 index 0000000..9fa39ca --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/MouseEvent.cs @@ -0,0 +1,48 @@ + + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Event flags for clicked events. + /// + public enum MouseEvent + { + /// + /// The mouse was moved withing the + /// taskbar icon's area. + /// + MouseMove, + /// + /// The right mouse button was clicked. + /// + IconRightMouseDown, + /// + /// The left mouse button was clicked. + /// + IconLeftMouseDown, + /// + /// The right mouse button was released. + /// + IconRightMouseUp, + /// + /// The left mouse button was released. + /// + IconLeftMouseUp, + /// + /// The middle mouse button was clicked. + /// + IconMiddleMouseDown, + /// + /// The middle mouse button was released. + /// + IconMiddleMouseUp, + /// + /// The taskbar icon was double clicked. + /// + IconDoubleClick, + /// + /// The balloon tip was clicked. + /// + BalloonToolTipClicked + } +} diff --git a/trunk/NotifyIconWpf/Interop/NotifyCommand.cs b/trunk/NotifyIconWpf/Interop/NotifyCommand.cs new file mode 100644 index 0000000..5a8c7ee --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/NotifyCommand.cs @@ -0,0 +1,39 @@ + + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Main operations performed on the + /// function. + /// + public enum NotifyCommand + { + /// + /// The taskbar icon is being created. + /// + Add = 0x00, + /// + /// The settings of the taskbar icon are being updated. + /// + Modify = 0x01, + /// + /// The taskbar icon is deleted. + /// + Delete = 0x02, + /// + /// Focus is returned to the taskbar icon. Currently not in use. + /// + SetFocus = 0x03, + /// + /// 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. + /// + SetVersion = 0x04 + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/NotifyIconData.cs b/trunk/NotifyIconWpf/Interop/NotifyIconData.cs new file mode 100644 index 0000000..9512f1e --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/NotifyIconData.cs @@ -0,0 +1,166 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// 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 + /// that were defined. + /// + [StructLayout(LayoutKind.Sequential)] + public struct NotifyIconData + { + /// + /// Size of this structure, in bytes. + /// + public uint cbSize; + + /// + /// 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. + /// + public IntPtr WindowHandle; + + /// + /// 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. + /// + public uint TaskbarIconId; + + /// + /// Flags that indicate which of the other members contain valid data. This member can be + /// a combination of the NIF_XXX constants. + /// + public IconDataMembers ValidMembers; + + /// + /// Application-defined message identifier. The system uses this identifier to send + /// notifications to the window identified in hWnd. + /// + public uint CallbackMessageId; + + /// + /// A handle to the icon that should be displayed. Just + /// . + /// + public IntPtr IconHandle; + + /// + /// 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. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string ToolTipText; + + + /// + /// State of the icon. Remember to also set the . + /// + public IconState IconState; + + /// + /// A value that specifies which bits of the state member are retrieved or modified. + /// For example, setting this member to + /// causes only the item's hidden + /// state to be retrieved. + /// + public IconState StateMask; + + /// + /// String with the text for a balloon ToolTip. It can have a maximum of 255 characters. + /// To remove the ToolTip, set the NIF_INFO flag in uFlags and set szInfo to an empty string. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string BalloonText; + + /// + /// Mainly used to set the version when is invoked + /// with . However, for legacy operations, + /// the same member is also used to set timouts for balloon ToolTips. + /// + public uint VersionOrTimeout; + + /// + /// String containing a title for a balloon ToolTip. This title appears in boldface + /// above the text. It can have a maximum of 63 characters. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string BalloonTitle; + + /// + /// Adds an icon to a balloon ToolTip, which is placed to the left of the title. If the + /// member is zero-length, the icon is not shown. + /// + public BalloonFlags BalloonFlags; + + /// + /// Windows XP (Shell32.dll version 6.0) and later.
+ /// - Windows 7 and later: A registered GUID that identifies the icon. + /// This value overrides uID and is the recommended method of identifying the icon.
+ /// - Windows XP through Windows Vista: Reserved. + ///
+ public Guid TaskbarIconGuid; + + /// + /// 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 + /// flag is set, this icon is used as the balloon icon.
+ /// If this member is NULL, the legacy behavior is carried out. + ///
+ public IntPtr CustomBalloonIconHandle; + + + /// + /// Creates a default data structure that provides + /// a hidden taskbar icon without the icon being set. + /// + /// + /// + 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 = 504; + + //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; + } + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/NotifyIconVersion.cs b/trunk/NotifyIconWpf/Interop/NotifyIconVersion.cs new file mode 100644 index 0000000..85852b7 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/NotifyIconVersion.cs @@ -0,0 +1,25 @@ +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// The notify icon version that is used. The higher + /// the version, the more capabilities are available. + /// + public enum NotifyIconVersion + { + /// + /// Default behavior (legacy Win95). Expects + /// a size of 488. + /// + Win95 = 0x0, + /// + /// Behavior representing Win2000 an higher. Expects + /// a size of 504. + /// + Win2000 = 0x3, + /// + /// Extended tooltip support, which is available + /// for Vista and later. + /// + Vista = 0x4 + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/Point.cs b/trunk/NotifyIconWpf/Interop/Point.cs new file mode 100644 index 0000000..f05d53f --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/Point.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Win API struct providing coordinates for a single point. + /// + [StructLayout(LayoutKind.Sequential)] + public struct Point + { + public int X; + public int Y; + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/TrayInfo.cs b/trunk/NotifyIconWpf/Interop/TrayInfo.cs new file mode 100644 index 0000000..db0d1b3 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/TrayInfo.cs @@ -0,0 +1,171 @@ +// Some interop code taken from Mike Marshall's AnyForm + +using System; +using System.Drawing; +using System.Runtime.InteropServices; + + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Resolves the current tray position. + /// + public static class TrayInfo + { + /// + /// Gets the position of the system tray. + /// + /// Tray coordinates. + public static Point GetTrayLocation() + { + var info = new AppBarInfo(); + 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; } + } + + + 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); + 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; + } + + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/WinApi.cs b/trunk/NotifyIconWpf/Interop/WinApi.cs new file mode 100644 index 0000000..6461ee4 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/WinApi.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.InteropServices; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Win32 API imports. + /// + internal static class WinApi + { + /// + /// Creates, updates or deletes the taskbar icon. + /// + [DllImport("shell32.Dll")] + public static extern bool Shell_NotifyIcon(NotifyCommand cmd, [In]ref NotifyIconData data); + + + /// + /// Creates the helper window that receives messages from the taskar icon. + /// + [DllImport("USER32.DLL", EntryPoint = "CreateWindowExW", SetLastError = true)] + public static extern IntPtr CreateWindowEx(int dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, + [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, int dwStyle, int x, int y, + int nWidth, int nHeight, uint hWndParent, int hMenu, int hInstance, + int lpParam); + + + /// + /// Processes a default windows procedure. + /// + [DllImport("USER32.DLL")] + public static extern long DefWindowProc(IntPtr hWnd, uint msg, uint wparam, uint lparam); + + /// + /// Registers the helper window class. + /// + [DllImport("USER32.DLL", EntryPoint = "RegisterClassW", SetLastError = true)] + public static extern short RegisterClass(ref WindowClass lpWndClass); + + /// + /// Registers a listener for a window message. + /// + /// + /// + [DllImport("User32.Dll", EntryPoint = "RegisterWindowMessageW")] + public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString); + + /// + /// Used to destroy the hidden helper window that receives messages from the + /// taskbar icon. + /// + /// + /// + [DllImport("USER32.DLL", SetLastError = true)] + public static extern bool DestroyWindow(IntPtr hWnd); + + + /// + /// Gives focus to a given window. + /// + /// + /// + [DllImport("USER32.DLL")] + public static extern bool SetForegroundWindow(IntPtr hWnd); + + + /// + /// Gets the maximum number of milliseconds that can elapse between a + /// first click and a second click for the OS to consider the + /// mouse action a double-click. + /// + /// The maximum amount of time, in milliseconds, that can + /// elapse between a first click and a second click for the OS to + /// consider the mouse action a double-click. + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern int GetDoubleClickTime(); + + + /// + /// Gets the screen coordinates of the current mouse position. + /// + /// + /// + [DllImport("USER32.DLL", SetLastError = true)] + public static extern bool GetCursorPos(ref Point lpPoint); + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/WindowClass.cs b/trunk/NotifyIconWpf/Interop/WindowClass.cs new file mode 100644 index 0000000..7d7b422 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/WindowClass.cs @@ -0,0 +1,31 @@ +using System; +using System.Runtime.InteropServices; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Callback delegate which is used by the Windows API to + /// submit window messages. + /// + public delegate long WindowProcedureHandler(IntPtr hwnd, uint uMsg, uint wparam, uint lparam); + + + /// + /// Win API WNDCLASS struct - represents a single window. + /// Used to receive window messages. + /// + [StructLayout(LayoutKind.Sequential)] + public struct WindowClass + { + public uint style; + public WindowProcedureHandler lpfnWndProc; + public int cbClsExtra; + public int cbWndExtra; + public IntPtr hInstance; + public IntPtr hIcon; + public IntPtr hCursor; + public IntPtr hbrBackground; + [MarshalAs(UnmanagedType.LPWStr)] public string lpszMenuName; + [MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName; + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Interop/WindowMessageSink.cs b/trunk/NotifyIconWpf/Interop/WindowMessageSink.cs new file mode 100644 index 0000000..fafea31 --- /dev/null +++ b/trunk/NotifyIconWpf/Interop/WindowMessageSink.cs @@ -0,0 +1,369 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + + +using System; +using System.ComponentModel; +using System.Diagnostics; + +namespace Hardcodet.Wpf.TaskbarNotification.Interop +{ + /// + /// Receives messages from the taskbar icon through + /// window messages of an underlying helper window. + /// + public class WindowMessageSink : IDisposable + { + + #region members + + /// + /// The ID of messages that are received from the the + /// taskbar icon. + /// + public const int CallbackMessageId = 0x400; + + /// + /// The ID of the message that is being received if the + /// taskbar is (re)started. + /// + private uint taskbarRestartMessageId; + + /// + /// Used to track whether a mouse-up event is just + /// the aftermath of a double-click and therefore needs + /// to be suppressed. + /// + private bool isDoubleClick; + + /// + /// 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. + /// + private WindowProcedureHandler messageHandler; + + /// + /// Window class ID. + /// + internal string WindowId { get; private set; } + + /// + /// Handle for the message window. + /// + /// The version of the underlying icon. Defines how + /// incoming messages are interpreted. + /// + public NotifyIconVersion Version { get; set; } + + #endregion + + + #region events + + /// + /// The custom tooltip should be closed or hidden. + /// + public event Action ChangeToolTipStateRequest; + + /// + /// Fired in case the user clicked or moved within + /// the taskbar icon area. + /// + public event Action MouseEventReceived; + + /// + /// Fired if a balloon ToolTip was either displayed + /// or closed (indicated by the boolean flag). + /// + public event Action BalloonToolTipChanged; + + /// + /// Fired if the taskbar was created or restarted. Requires the taskbar + /// icon to be reset. + /// + public event Action TaskbarCreated; + + #endregion + + + #region construction + + /// + /// Creates a new message sink that receives message from + /// a given taskbar icon. + /// + /// + public WindowMessageSink(NotifyIconVersion version) + { + Version = version; + CreateMessageWindow(); + } + + + private WindowMessageSink() + { + } + + + /// + /// Creates a dummy instance that provides an empty + /// pointer rather than a real window handler.
+ /// Used at design time. + ///
+ /// + internal static WindowMessageSink CreateEmpty() + { + return new WindowMessageSink + { + MessageWindowHandle = IntPtr.Zero, + Version = NotifyIconVersion.Vista + }; + } + + #endregion + + + #region CreateMessageWindow + + /// + /// Creates the helper message window that is used + /// to receive messages from the taskbar icon. + /// + private void CreateMessageWindow() + { + //generate a unique ID for the window + WindowId = "WPFTaskbarIcon_" + DateTime.Now.Ticks; + + //register window message handler + messageHandler = OnWindowMessageReceived; + + // Create a simple window class which is reference through + //the messageHandler delegate + WindowClass wc; + + wc.style = 0; + wc.lpfnWndProc = messageHandler; + 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 + WinApi.RegisterClass(ref wc); + + // Get the message used to indicate the taskbar has been restarted + // This is used to re-add icons when the taskbar restarts + taskbarRestartMessageId = WinApi.RegisterWindowMessage("TaskbarCreated"); + + // Create the message window + MessageWindowHandle = WinApi.CreateWindowEx(0, WindowId, "", 0, 0, 0, 1, 1, 0, 0, 0, 0); + + if (MessageWindowHandle == IntPtr.Zero) + { + throw new Win32Exception(); + } + } + + #endregion + + + #region Handle Window Messages + + /// + /// Callback method that receives messages from the taskbar area. + /// + private long OnWindowMessageReceived(IntPtr hwnd, uint messageId, uint wparam, uint 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); + } + + + /// + /// Processes incoming system messages. + /// + /// Callback ID. + /// If the version is + /// or higher, this parameter can be used to resolve mouse coordinates. + /// Currently not in use. + /// Provides information about the event. + private void ProcessWindowMessage(uint msg, uint wParam, uint lParam) + { + if (msg != CallbackMessageId) return; + + switch (lParam) + { + 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 + + /// + /// Set to true as soon as + /// has been invoked. + /// + public bool IsDisposed { get; private set; } + + + /// + /// Disposes the object. + /// + /// This method is not virtual by design. Derived classes + /// should override . + /// + 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); + } + + /// + /// This destructor will run only if the + /// method does not get called. This gives this base class the + /// opportunity to finalize. + /// + /// Important: Do not provide destructors in types derived from + /// this class. + /// + /// + ~WindowMessageSink() + { + Dispose(false); + } + + + /// + /// Removes the windows hook that receives window + /// messages and closes the underlying helper window. + /// + private void Dispose(bool disposing) + { + //don't do anything if the component is already disposed + if (IsDisposed || !disposing) return; + IsDisposed = true; + + WinApi.DestroyWindow(MessageWindowHandle); + messageHandler = null; + } + + #endregion + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/NotifyIconWpf.csproj b/trunk/NotifyIconWpf/NotifyIconWpf.csproj new file mode 100644 index 0000000..8ec2521 --- /dev/null +++ b/trunk/NotifyIconWpf/NotifyIconWpf.csproj @@ -0,0 +1,142 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {7AC63864-7638-41C4-969C-D3197EF2BED9} + library + Properties + Hardcodet.Wpf.TaskbarNotification + Hardcodet.Wpf.TaskbarNotification + v4.0 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + Client + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AnyCPU + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Hardcodet.Wpf.TaskbarNotification.xml + AllRules.ruleset + + + true + + + pithos.snk + + + + + 3.5 + + + + + + + + + + + Code + + + + + + + + + + + + + + + + Code + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/trunk/NotifyIconWpf/PopupActivationMode.cs b/trunk/NotifyIconWpf/PopupActivationMode.cs new file mode 100644 index 0000000..1611c59 --- /dev/null +++ b/trunk/NotifyIconWpf/PopupActivationMode.cs @@ -0,0 +1,69 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + +namespace Hardcodet.Wpf.TaskbarNotification +{ + /// + /// Defines flags that define when a popup + /// is being displyed. + /// + public enum PopupActivationMode + { + /// + /// The item is displayed if the user clicks the + /// tray icon with the left mouse button. + /// + LeftClick, + /// + /// The item is displayed if the user clicks the + /// tray icon with the right mouse button. + /// + RightClick, + /// + /// The item is displayed if the user double-clicks the + /// tray icon. + /// + DoubleClick, + /// + /// The item is displayed if the user clicks the + /// tray icon with the left or the right mouse button. + /// + LeftOrRightClick, + /// + /// The item is displayed if the user clicks the + /// tray icon with the left mouse button or if a + /// double-click is being performed. + /// + LeftOrDoubleClick, + /// + /// The item is displayed if the user clicks the + /// tray icon with the middle mouse button. + /// + MiddleClick, + /// + /// The item is displayed whenever a click occurs. + /// + All + } +} diff --git a/trunk/NotifyIconWpf/Properties/AssemblyInfo.cs b/trunk/NotifyIconWpf/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b1eb257 --- /dev/null +++ b/trunk/NotifyIconWpf/Properties/AssemblyInfo.cs @@ -0,0 +1,57 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Markup; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NotifyIcon for WPF")] +[assembly: AssemblyDescription("NotifyIcon Implementation for the WPF platform.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("hardcodet.net")] +[assembly: AssemblyProduct("NotifyIcon WPF")] +[assembly: AssemblyCopyright("Copyright © Philipp Sumi 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//provides simplified declaration +[assembly: XmlnsDefinition("http://www.hardcodet.net/taskbar", "Hardcodet.Wpf.TaskbarNotification")] + +// 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 +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// 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.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] diff --git a/trunk/NotifyIconWpf/Properties/Resources.Designer.cs b/trunk/NotifyIconWpf/Properties/Resources.Designer.cs new file mode 100644 index 0000000..3ccd02d --- /dev/null +++ b/trunk/NotifyIconWpf/Properties/Resources.Designer.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.235 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Hardcodet.Wpf.TaskbarNotification.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Hardcodet.Wpf.TaskbarNotification.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static System.Drawing.Icon DefaultTrayIcon { + get { + object obj = ResourceManager.GetObject("DefaultTrayIcon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/trunk/NotifyIconWpf/Properties/Resources.resx b/trunk/NotifyIconWpf/Properties/Resources.resx new file mode 100644 index 0000000..4050202 --- /dev/null +++ b/trunk/NotifyIconWpf/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\defaulttrayicon.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/trunk/NotifyIconWpf/RoutedEventHelper.cs b/trunk/NotifyIconWpf/RoutedEventHelper.cs new file mode 100644 index 0000000..3b9eaec --- /dev/null +++ b/trunk/NotifyIconWpf/RoutedEventHelper.cs @@ -0,0 +1,81 @@ +using System; +using System.Windows; + +namespace Hardcodet.Wpf.TaskbarNotification +{ + /// + /// Helper class used by routed events of the + /// class. + /// + internal static class RoutedEventHelper + { + #region RoutedEvent Helper Methods + + /// + /// A static helper method to raise a routed event on a target UIElement or ContentElement. + /// + /// UIElement or ContentElement on which to raise the event + /// RoutedEventArgs to use when raising the event + internal static void RaiseEvent(DependencyObject target, RoutedEventArgs args) + { + if (target is UIElement) + { + (target as UIElement).RaiseEvent(args); + } + else if (target is ContentElement) + { + (target as ContentElement).RaiseEvent(args); + } + } + + /// + /// A static helper method that adds a handler for a routed event + /// to a target UIElement or ContentElement. + /// + /// UIElement or ContentElement that listens to the event + /// Event that will be handled + /// Event handler to be added + 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); + } + } + } + + /// + /// A static helper method that removes a handler for a routed event + /// from a target UIElement or ContentElement. + /// + /// UIElement or ContentElement that listens to the event + /// Event that will no longer be handled + /// Event handler to be removed + 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 + } +} diff --git a/trunk/NotifyIconWpf/TaskbarIcon.Declarations.cs b/trunk/NotifyIconWpf/TaskbarIcon.Declarations.cs new file mode 100644 index 0000000..0ad227e --- /dev/null +++ b/trunk/NotifyIconWpf/TaskbarIcon.Declarations.cs @@ -0,0 +1,1869 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using System.Windows.Media; +using Hardcodet.Wpf.TaskbarNotification.Interop; + +namespace Hardcodet.Wpf.TaskbarNotification +{ + /// + /// Contains declarations of WPF dependency properties + /// and events. + /// + partial class TaskbarIcon + { + /// + /// Category name that is set on designer properties. + /// + public const string CategoryName = "NotifyIcon"; + + + //POPUP CONTROLS + + #region TrayPopupResolved + + /// + /// TrayPopupResolved Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey TrayPopupResolvedPropertyKey + = DependencyProperty.RegisterReadOnly("TrayPopupResolved", typeof(Popup), typeof(TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + + /// + /// A read-only dependency property that returns the + /// that is being displayed in the taskbar area based on a user action. + /// + public static readonly DependencyProperty TrayPopupResolvedProperty + = TrayPopupResolvedPropertyKey.DependencyProperty; + + /// + /// Gets the TrayPopupResolved property. Returns + /// a which is either the + /// control itself or a + /// control that contains the + /// . + /// + [Category(CategoryName)] + public Popup TrayPopupResolved + { + get { return (Popup)GetValue(TrayPopupResolvedProperty); } + } + + /// + /// Provides a secure method for setting the TrayPopupResolved property. + /// This dependency property indicates .... + /// + /// The new value for the property. + protected void SetTrayPopupResolved(Popup value) + { + SetValue(TrayPopupResolvedPropertyKey, value); + } + + #endregion + + #region TrayToolTipResolved + + /// + /// TrayToolTipResolved Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey TrayToolTipResolvedPropertyKey + = DependencyProperty.RegisterReadOnly("TrayToolTipResolved", typeof(ToolTip), typeof(TaskbarIcon), + new FrameworkPropertyMetadata(null )); + + + /// + /// A read-only dependency property that returns the + /// that is being displayed. + /// + public static readonly DependencyProperty TrayToolTipResolvedProperty + = TrayToolTipResolvedPropertyKey.DependencyProperty; + + /// + /// Gets the TrayToolTipResolved property. Returns + /// a control that was created + /// in order to display either + /// or . + /// + [Category(CategoryName)] + [Browsable(true)] + [Bindable(true)] + public ToolTip TrayToolTipResolved + { + get { return (ToolTip)GetValue(TrayToolTipResolvedProperty); } + } + + /// + /// Provides a secure method for setting the + /// property. + /// + /// The new value for the property. + protected void SetTrayToolTipResolved(ToolTip value) + { + SetValue(TrayToolTipResolvedPropertyKey, value); + } + + #endregion + + #region CustomBalloon + + /// + /// CustomBalloon Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey CustomBalloonPropertyKey + = DependencyProperty.RegisterReadOnly("CustomBalloon", typeof(Popup), typeof(TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty CustomBalloonProperty + = CustomBalloonPropertyKey.DependencyProperty; + + /// + /// A custom popup that is being displayed in the tray area in order + /// to display messages to the user. + /// + public Popup CustomBalloon + { + get { return (Popup)GetValue(CustomBalloonProperty); } + } + + /// + /// Provides a secure method for setting the property. + /// + /// The new value for the property. + protected void SetCustomBalloon(Popup value) + { + SetValue(CustomBalloonPropertyKey, value); + } + + #endregion + + + + //DEPENDENCY PROPERTIES + + #region Icon property / IconSource dependency property + + private Icon icon; + + /// + /// Gets or sets the icon to be displayed. This is not a + /// dependency property - if you want to assign the property + /// through XAML, please use the + /// dependency property. + /// + [Browsable(false)] + public Icon Icon + { + get { return icon; } + set + { + icon = value; + iconData.IconHandle = value == null ? IntPtr.Zero : icon.Handle; + + Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Icon); + } + } + + + /// + /// Resolves an image source and updates the property accordingly. + /// + public static readonly DependencyProperty IconSourceProperty = + DependencyProperty.Register("IconSource", + typeof(ImageSource), + typeof(TaskbarIcon), + new FrameworkPropertyMetadata(null, IconSourcePropertyChanged)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Resolves an image source and updates the property accordingly. + ///
+ [Category(CategoryName)] + [Description("Sets the displayed taskbar icon.")] + public ImageSource IconSource + { + get { return (ImageSource)GetValue(IconSourceProperty); } + set { SetValue(IconSourceProperty, value); } + } + + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void IconSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon)d; + owner.OnIconSourcePropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnIconSourcePropertyChanged(DependencyPropertyChangedEventArgs e) + { + ImageSource newValue = (ImageSource)e.NewValue; + + //resolving the ImageSource at design time is unlikely to work + if (!Util.IsDesignMode) Icon = newValue.ToIcon(); + } + + #endregion + + #region ToolTipText dependency property + + /// + /// A tooltip text that is being displayed if no custom + /// was set or if custom tooltips are not supported. + /// + public static readonly DependencyProperty ToolTipTextProperty = + DependencyProperty.Register("ToolTipText", + typeof (string), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(String.Empty, ToolTipTextPropertyChanged)); + + + /// + /// A property wrapper for the + /// dependency property:
+ /// A tooltip text that is being displayed if no custom + /// was set or if custom tooltips are not supported. + ///
+ [Category(CategoryName)] + [Description("Alternative to a fully blown ToolTip, which is only displayed on Vista and above.")] + public string ToolTipText + { + get { return (string) GetValue(ToolTipTextProperty); } + set { SetValue(ToolTipTextProperty, value); } + } + + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void ToolTipTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon) d; + owner.OnToolTipTextPropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnToolTipTextPropertyChanged(DependencyPropertyChangedEventArgs e) + { + //only recreate tooltip if we're not using a custom control + if (TrayToolTipResolved == null || TrayToolTipResolved.Content is string) + { + CreateCustomToolTip(); + } + + WriteToolTipSettings(); + } + + #endregion + + #region TrayToolTip dependency property + + /// + /// A custom UI element that is displayed as a tooltip if the user hovers over the taskbar icon. + /// Works only with Vista and above. Accordingly, you should make sure that + /// the property is set as well. + /// + public static readonly DependencyProperty TrayToolTipProperty = + DependencyProperty.Register("TrayToolTip", + typeof (UIElement), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null, TrayToolTipPropertyChanged)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// A custom UI element that is displayed as a tooltip if the user hovers over the taskbar icon. + /// Works only with Vista and above. Accordingly, you should make sure that + /// the property is set as well. + ///
+ [Category(CategoryName)] + [Description("Custom UI element that is displayed as a tooltip. Only on Vista and above")] + public UIElement TrayToolTip + { + get { return (UIElement) GetValue(TrayToolTipProperty); } + set { SetValue(TrayToolTipProperty, value); } + } + + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void TrayToolTipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon) d; + owner.OnTrayToolTipPropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnTrayToolTipPropertyChanged(DependencyPropertyChangedEventArgs e) + { + //recreate tooltip control + CreateCustomToolTip(); + + if (e.OldValue != null) + { + //remove the taskbar icon reference from the previously used element + SetParentTaskbarIcon((DependencyObject) e.OldValue, null); + } + + + if (e.NewValue != null) + { + //set this taskbar icon as a reference to the new tooltip element + SetParentTaskbarIcon((DependencyObject) e.NewValue, this); + } + + + //update tooltip settings - needed to make sure a string is set, even + //if the ToolTipText property is not set. Otherwise, the event that + //triggers tooltip display is never fired. + WriteToolTipSettings(); + } + + #endregion + + #region TrayPopup dependency property + + /// + /// A control that is displayed as a popup when the taskbar icon is clicked. + /// + public static readonly DependencyProperty TrayPopupProperty = + DependencyProperty.Register("TrayPopup", + typeof(UIElement), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null, TrayPopupPropertyChanged)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// A control that is displayed as a popup when the taskbar icon is clicked. + ///
+ [Category(CategoryName)] + [Description("Displayed as a Popup if the user clicks on the taskbar icon.")] + public UIElement TrayPopup + { + get { return (UIElement)GetValue(TrayPopupProperty); } + set { SetValue(TrayPopupProperty, value); } + } + + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void TrayPopupPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon) d; + owner.OnTrayPopupPropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnTrayPopupPropertyChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + { + //remove the taskbar icon reference from the previously used element + SetParentTaskbarIcon((DependencyObject)e.OldValue, null); + } + + + if (e.NewValue != null) + { + //set this taskbar icon as a reference to the new tooltip element + SetParentTaskbarIcon((DependencyObject)e.NewValue, this); + } + + //create a pop + CreatePopup(); + } + + #endregion + + + #region MenuActivation dependency property + + /// + /// Defines what mouse events display the context menu. + /// Defaults to . + /// + public static readonly DependencyProperty MenuActivationProperty = + DependencyProperty.Register("MenuActivation", + typeof (PopupActivationMode), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(PopupActivationMode.RightClick)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Defines what mouse events display the context menu. + /// Defaults to . + ///
+ [Category(CategoryName)] + [Description("Defines what mouse events display the context menu.")] + public PopupActivationMode MenuActivation + { + get { return (PopupActivationMode) GetValue(MenuActivationProperty); } + set { SetValue(MenuActivationProperty, value); } + } + + #endregion + + #region PopupActivation dependency property + + /// + /// Defines what mouse events trigger the . + /// Default is . + /// + public static readonly DependencyProperty PopupActivationProperty = + DependencyProperty.Register("PopupActivation", + typeof (PopupActivationMode), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(PopupActivationMode.LeftClick)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Defines what mouse events trigger the . + /// Default is . + ///
+ [Category(CategoryName)] + [Description("Defines what mouse events display the TaskbarIconPopup.")] + public PopupActivationMode PopupActivation + { + get { return (PopupActivationMode) GetValue(PopupActivationProperty); } + set { SetValue(PopupActivationProperty, value); } + } + + #endregion + + + #region Visibility dependency property override + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void VisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon) d; + owner.OnVisibilityPropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnVisibilityPropertyChanged(DependencyPropertyChangedEventArgs e) + { + Visibility newValue = (Visibility) e.NewValue; + + //update + if (newValue == Visibility.Visible) + { + CreateTaskbarIcon(); + } + else + { + RemoveTaskbarIcon(); + } + } + + #endregion + + #region DataContext dependency property override / target update + + /// + /// Updates the of a given + /// . This method only updates target elements + /// that do not already have a data context of their own, and either assigns + /// the of the NotifyIcon, or the + /// NotifyIcon itself, if no data context was assigned at all. + /// + private void UpdateDataContext(FrameworkElement target, object oldDataContextValue, object newDataContextValue) + { + //if there is no target or it's data context is determined through a binding + //of its own, keep it + if (target == null || target.IsDataContextDataBound()) return; + + //if the target's data context is the NotifyIcon's old DataContext or the NotifyIcon itself, + //update it + if (ReferenceEquals(this, target.DataContext) || Equals(oldDataContextValue, target.DataContext)) + { + //assign own data context, if available. If there is no data + //context at all, assign NotifyIcon itself. + target.DataContext = newDataContextValue ?? this; + } + } + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void DataContextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon) d; + owner.OnDataContextPropertyChanged(e); + } + + + /// + /// Handles changes of the dependency property. As + /// WPF internally uses the dependency property system and bypasses the + /// property wrapper, updates of the property's value + /// should be handled here. + /// Provides information about the updated property. + private void OnDataContextPropertyChanged(DependencyPropertyChangedEventArgs e) + { + object newValue = e.NewValue; + object oldValue = e.OldValue; + + //replace custom data context for ToolTips, Popup, and + //ContextMenu + UpdateDataContext(TrayPopupResolved, oldValue, newValue); + UpdateDataContext(TrayToolTipResolved, oldValue, newValue); + UpdateDataContext(ContextMenu, oldValue, newValue); + } + + #endregion + + #region ContextMenu dependency property override + + /// + /// A static callback listener which is being invoked if the + /// dependency property has + /// been changed. Invokes the + /// instance method of the changed instance. + /// + /// The currently processed owner of the property. + /// Provides information about the updated property. + private static void ContextMenuPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TaskbarIcon owner = (TaskbarIcon)d; + owner.OnContextMenuPropertyChanged(e); + } + + + /// + /// Releases the old and updates the new property + /// in order to reflect both the NotifyIcon's + /// property and have the assigned. + /// + /// Provides information about the updated property. + private void OnContextMenuPropertyChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + { + //remove the taskbar icon reference from the previously used element + SetParentTaskbarIcon((DependencyObject)e.OldValue, null); + } + + if (e.NewValue != null) + { + //set this taskbar icon as a reference to the new tooltip element + SetParentTaskbarIcon((DependencyObject)e.NewValue, this); + } + + UpdateDataContext((ContextMenu) e.NewValue, null, DataContext); + } + + #endregion + + + + #region DoubleClickCommand dependency property + + /// + /// Associates a command that is being executed if the tray icon is being + /// double clicked. + /// + public static readonly DependencyProperty DoubleClickCommandProperty = + DependencyProperty.Register("DoubleClickCommand", + typeof (ICommand), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Associates a command that is being executed if the tray icon is being + /// double clicked. + ///
+ public ICommand DoubleClickCommand + { + get { return (ICommand) GetValue(DoubleClickCommandProperty); } + set { SetValue(DoubleClickCommandProperty, value); } + } + + #endregion + + #region DoubleClickCommandParameter dependency property + + /// + /// Command parameter for the . + /// + public static readonly DependencyProperty DoubleClickCommandParameterProperty = + DependencyProperty.Register("DoubleClickCommandParameter", + typeof (object), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Command parameter for the . + ///
+ public object DoubleClickCommandParameter + { + get { return GetValue(DoubleClickCommandParameterProperty); } + set { SetValue(DoubleClickCommandParameterProperty, value); } + } + + #endregion + + #region DoubleClickCommandTarget dependency property + + /// + /// The target of the command that is fired if the notify icon is double clicked. + /// + public static readonly DependencyProperty DoubleClickCommandTargetProperty = + DependencyProperty.Register("DoubleClickCommandTarget", + typeof (IInputElement), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// The target of the command that is fired if the notify icon is double clicked. + ///
+ public IInputElement DoubleClickCommandTarget + { + get { return (IInputElement) GetValue(DoubleClickCommandTargetProperty); } + set { SetValue(DoubleClickCommandTargetProperty, value); } + } + + #endregion + + + + #region LeftClickCommand dependency property + + /// + /// Associates a command that is being executed if the tray icon is being + /// double clicked. + /// + public static readonly DependencyProperty LeftClickCommandProperty = + DependencyProperty.Register("LeftClickCommand", + typeof (ICommand), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Associates a command that is being executed if the tray icon is being + /// double clicked. + ///
+ public ICommand LeftClickCommand + { + get { return (ICommand) GetValue(LeftClickCommandProperty); } + set { SetValue(LeftClickCommandProperty, value); } + } + + #endregion + + #region LeftClickCommandParameter dependency property + + /// + /// Command parameter for the . + /// + public static readonly DependencyProperty LeftClickCommandParameterProperty = + DependencyProperty.Register("LeftClickCommandParameter", + typeof (object), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// Command parameter for the . + ///
+ public object LeftClickCommandParameter + { + get { return GetValue(LeftClickCommandParameterProperty); } + set { SetValue(LeftClickCommandParameterProperty, value); } + } + + #endregion + + #region LeftClickCommandTarget dependency property + + /// + /// The target of the command that is fired if the notify icon is clicked. + /// + public static readonly DependencyProperty LeftClickCommandTargetProperty = + DependencyProperty.Register("LeftClickCommandTarget", + typeof (IInputElement), + typeof (TaskbarIcon), + new FrameworkPropertyMetadata(null)); + + /// + /// A property wrapper for the + /// dependency property:
+ /// The target of the command that is fired if the notify icon is clicked. + ///
+ public IInputElement LeftClickCommandTarget + { + get { return (IInputElement) GetValue(LeftClickCommandTargetProperty); } + set { SetValue(LeftClickCommandTargetProperty, value); } + } + + #endregion + + + + //EVENTS + + #region TrayLeftMouseDown + + /// + /// TrayLeftMouseDown Routed Event + /// + public static readonly RoutedEvent TrayLeftMouseDownEvent = EventManager.RegisterRoutedEvent("TrayLeftMouseDown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user presses the left mouse button. + /// + [Category(CategoryName)] + public event RoutedEventHandler TrayLeftMouseDown + { + add { AddHandler(TrayLeftMouseDownEvent, value); } + remove { RemoveHandler(TrayLeftMouseDownEvent, value); } + } + + /// + /// A helper method to raise the TrayLeftMouseDown event. + /// + protected RoutedEventArgs RaiseTrayLeftMouseDownEvent() + { + RoutedEventArgs args = RaiseTrayLeftMouseDownEvent(this); + return args; + } + + /// + /// A static helper method to raise the TrayLeftMouseDown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayLeftMouseDownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayLeftMouseDownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayRightMouseDown + + /// + /// TrayRightMouseDown Routed Event + /// + public static readonly RoutedEvent TrayRightMouseDownEvent = EventManager.RegisterRoutedEvent("TrayRightMouseDown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the presses the right mouse button. + /// + public event RoutedEventHandler TrayRightMouseDown + { + add { AddHandler(TrayRightMouseDownEvent, value); } + remove { RemoveHandler(TrayRightMouseDownEvent, value); } + } + + /// + /// A helper method to raise the TrayRightMouseDown event. + /// + protected RoutedEventArgs RaiseTrayRightMouseDownEvent() + { + return RaiseTrayRightMouseDownEvent(this); + } + + /// + /// A static helper method to raise the TrayRightMouseDown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayRightMouseDownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayRightMouseDownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayMiddleMouseDown + + /// + /// TrayMiddleMouseDown Routed Event + /// + public static readonly RoutedEvent TrayMiddleMouseDownEvent = EventManager.RegisterRoutedEvent("TrayMiddleMouseDown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user presses the middle mouse button. + /// + public event RoutedEventHandler TrayMiddleMouseDown + { + add { AddHandler(TrayMiddleMouseDownEvent, value); } + remove { RemoveHandler(TrayMiddleMouseDownEvent, value); } + } + + /// + /// A helper method to raise the TrayMiddleMouseDown event. + /// + protected RoutedEventArgs RaiseTrayMiddleMouseDownEvent() + { + return RaiseTrayMiddleMouseDownEvent(this); + } + + /// + /// A static helper method to raise the TrayMiddleMouseDown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayMiddleMouseDownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayMiddleMouseDownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TrayLeftMouseUp + + /// + /// TrayLeftMouseUp Routed Event + /// + public static readonly RoutedEvent TrayLeftMouseUpEvent = EventManager.RegisterRoutedEvent("TrayLeftMouseUp", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user releases the left mouse button. + /// + public event RoutedEventHandler TrayLeftMouseUp + { + add { AddHandler(TrayLeftMouseUpEvent, value); } + remove { RemoveHandler(TrayLeftMouseUpEvent, value); } + } + + /// + /// A helper method to raise the TrayLeftMouseUp event. + /// + protected RoutedEventArgs RaiseTrayLeftMouseUpEvent() + { + return RaiseTrayLeftMouseUpEvent(this); + } + + /// + /// A static helper method to raise the TrayLeftMouseUp event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayLeftMouseUpEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayLeftMouseUpEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayRightMouseUp + + /// + /// TrayRightMouseUp Routed Event + /// + public static readonly RoutedEvent TrayRightMouseUpEvent = EventManager.RegisterRoutedEvent("TrayRightMouseUp", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user releases the right mouse button. + /// + public event RoutedEventHandler TrayRightMouseUp + { + add { AddHandler(TrayRightMouseUpEvent, value); } + remove { RemoveHandler(TrayRightMouseUpEvent, value); } + } + + /// + /// A helper method to raise the TrayRightMouseUp event. + /// + protected RoutedEventArgs RaiseTrayRightMouseUpEvent() + { + return RaiseTrayRightMouseUpEvent(this); + } + + /// + /// A static helper method to raise the TrayRightMouseUp event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayRightMouseUpEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayRightMouseUpEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayMiddleMouseUp + + /// + /// TrayMiddleMouseUp Routed Event + /// + public static readonly RoutedEvent TrayMiddleMouseUpEvent = EventManager.RegisterRoutedEvent("TrayMiddleMouseUp", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user releases the middle mouse button. + /// + public event RoutedEventHandler TrayMiddleMouseUp + { + add { AddHandler(TrayMiddleMouseUpEvent, value); } + remove { RemoveHandler(TrayMiddleMouseUpEvent, value); } + } + + /// + /// A helper method to raise the TrayMiddleMouseUp event. + /// + protected RoutedEventArgs RaiseTrayMiddleMouseUpEvent() + { + return RaiseTrayMiddleMouseUpEvent(this); + } + + /// + /// A static helper method to raise the TrayMiddleMouseUp event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayMiddleMouseUpEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayMiddleMouseUpEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TrayMouseDoubleClick + + /// + /// TrayMouseDoubleClick Routed Event + /// + public static readonly RoutedEvent TrayMouseDoubleClickEvent = EventManager.RegisterRoutedEvent("TrayMouseDoubleClick", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user double-clicks the taskbar icon. + /// + public event RoutedEventHandler TrayMouseDoubleClick + { + add { AddHandler(TrayMouseDoubleClickEvent, value); } + remove { RemoveHandler(TrayMouseDoubleClickEvent, value); } + } + + /// + /// A helper method to raise the TrayMouseDoubleClick event. + /// + protected RoutedEventArgs RaiseTrayMouseDoubleClickEvent() + { + RoutedEventArgs args = RaiseTrayMouseDoubleClickEvent(this); + DoubleClickCommand.ExecuteIfEnabled(DoubleClickCommandParameter, DoubleClickCommandTarget ?? this); + return args; + } + + /// + /// A static helper method to raise the TrayMouseDoubleClick event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayMouseDoubleClickEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayMouseDoubleClickEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayMouseMove + + /// + /// TrayMouseMove Routed Event + /// + public static readonly RoutedEvent TrayMouseMoveEvent = EventManager.RegisterRoutedEvent("TrayMouseMove", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user moves the mouse over the taskbar icon. + /// + public event RoutedEventHandler TrayMouseMove + { + add { AddHandler(TrayMouseMoveEvent, value); } + remove { RemoveHandler(TrayMouseMoveEvent, value); } + } + + /// + /// A helper method to raise the TrayMouseMove event. + /// + protected RoutedEventArgs RaiseTrayMouseMoveEvent() + { + return RaiseTrayMouseMoveEvent(this); + } + + /// + /// A static helper method to raise the TrayMouseMove event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayMouseMoveEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayMouseMoveEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TrayBalloonTipShown + + /// + /// TrayBalloonTipShown Routed Event + /// + public static readonly RoutedEvent TrayBalloonTipShownEvent = EventManager.RegisterRoutedEvent("TrayBalloonTipShown", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when a balloon ToolTip is displayed. + /// + public event RoutedEventHandler TrayBalloonTipShown + { + add { AddHandler(TrayBalloonTipShownEvent, value); } + remove { RemoveHandler(TrayBalloonTipShownEvent, value); } + } + + /// + /// A helper method to raise the TrayBalloonTipShown event. + /// + protected RoutedEventArgs RaiseTrayBalloonTipShownEvent() + { + return RaiseTrayBalloonTipShownEvent(this); + } + + /// + /// A static helper method to raise the TrayBalloonTipShown event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayBalloonTipShownEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayBalloonTipShownEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayBalloonTipClosed + + /// + /// TrayBalloonTipClosed Routed Event + /// + public static readonly RoutedEvent TrayBalloonTipClosedEvent = EventManager.RegisterRoutedEvent("TrayBalloonTipClosed", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when a balloon ToolTip was closed. + /// + public event RoutedEventHandler TrayBalloonTipClosed + { + add { AddHandler(TrayBalloonTipClosedEvent, value); } + remove { RemoveHandler(TrayBalloonTipClosedEvent, value); } + } + + /// + /// A helper method to raise the TrayBalloonTipClosed event. + /// + protected RoutedEventArgs RaiseTrayBalloonTipClosedEvent() + { + return RaiseTrayBalloonTipClosedEvent(this); + } + + /// + /// A static helper method to raise the TrayBalloonTipClosed event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayBalloonTipClosedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayBalloonTipClosedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayBalloonTipClicked + + /// + /// TrayBalloonTipClicked Routed Event + /// + public static readonly RoutedEvent TrayBalloonTipClickedEvent = EventManager.RegisterRoutedEvent("TrayBalloonTipClicked", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Occurs when the user clicks on a balloon ToolTip. + /// + public event RoutedEventHandler TrayBalloonTipClicked + { + add { AddHandler(TrayBalloonTipClickedEvent, value); } + remove { RemoveHandler(TrayBalloonTipClickedEvent, value); } + } + + /// + /// A helper method to raise the TrayBalloonTipClicked event. + /// + protected RoutedEventArgs RaiseTrayBalloonTipClickedEvent() + { + return RaiseTrayBalloonTipClickedEvent(this); + } + + /// + /// A static helper method to raise the TrayBalloonTipClicked event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayBalloonTipClickedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayBalloonTipClickedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TrayContextMenuOpen (and PreviewTrayContextMenuOpen) + + /// + /// TrayContextMenuOpen Routed Event + /// + public static readonly RoutedEvent TrayContextMenuOpenEvent = EventManager.RegisterRoutedEvent("TrayContextMenuOpen", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Bubbled event that occurs when the context menu of the taskbar icon is being displayed. + /// + public event RoutedEventHandler TrayContextMenuOpen + { + add { AddHandler(TrayContextMenuOpenEvent, value); } + remove { RemoveHandler(TrayContextMenuOpenEvent, value); } + } + + /// + /// A helper method to raise the TrayContextMenuOpen event. + /// + protected RoutedEventArgs RaiseTrayContextMenuOpenEvent() + { + return RaiseTrayContextMenuOpenEvent(this); + } + + /// + /// A static helper method to raise the TrayContextMenuOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayContextMenuOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayContextMenuOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + /// + /// PreviewTrayContextMenuOpen Routed Event + /// + public static readonly RoutedEvent PreviewTrayContextMenuOpenEvent = EventManager.RegisterRoutedEvent("PreviewTrayContextMenuOpen", + RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Tunneled event that occurs when the context menu of the taskbar icon is being displayed. + /// + public event RoutedEventHandler PreviewTrayContextMenuOpen + { + add { AddHandler(PreviewTrayContextMenuOpenEvent, value); } + remove { RemoveHandler(PreviewTrayContextMenuOpenEvent, value); } + } + + /// + /// A helper method to raise the PreviewTrayContextMenuOpen event. + /// + protected RoutedEventArgs RaisePreviewTrayContextMenuOpenEvent() + { + return RaisePreviewTrayContextMenuOpenEvent(this); + } + + /// + /// A static helper method to raise the PreviewTrayContextMenuOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePreviewTrayContextMenuOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PreviewTrayContextMenuOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayPopupOpen (and PreviewTrayPopupOpen) + + /// + /// TrayPopupOpen Routed Event + /// + public static readonly RoutedEvent TrayPopupOpenEvent = EventManager.RegisterRoutedEvent("TrayPopupOpen", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Bubbled event that occurs when the custom popup is being opened. + /// + public event RoutedEventHandler TrayPopupOpen + { + add { AddHandler(TrayPopupOpenEvent, value); } + remove { RemoveHandler(TrayPopupOpenEvent, value); } + } + + /// + /// A helper method to raise the TrayPopupOpen event. + /// + protected RoutedEventArgs RaiseTrayPopupOpenEvent() + { + return RaiseTrayPopupOpenEvent(this); + } + + /// + /// A static helper method to raise the TrayPopupOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayPopupOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayPopupOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + /// + /// PreviewTrayPopupOpen Routed Event + /// + public static readonly RoutedEvent PreviewTrayPopupOpenEvent = EventManager.RegisterRoutedEvent("PreviewTrayPopupOpen", + RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Tunneled event that occurs when the custom popup is being opened. + /// + public event RoutedEventHandler PreviewTrayPopupOpen + { + add { AddHandler(PreviewTrayPopupOpenEvent, value); } + remove { RemoveHandler(PreviewTrayPopupOpenEvent, value); } + } + + /// + /// A helper method to raise the PreviewTrayPopupOpen event. + /// + protected RoutedEventArgs RaisePreviewTrayPopupOpenEvent() + { + return RaisePreviewTrayPopupOpenEvent(this); + } + + /// + /// A static helper method to raise the PreviewTrayPopupOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePreviewTrayPopupOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PreviewTrayPopupOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + #region TrayToolTipOpen (and PreviewTrayToolTipOpen) + + /// + /// TrayToolTipOpen Routed Event + /// + public static readonly RoutedEvent TrayToolTipOpenEvent = EventManager.RegisterRoutedEvent("TrayToolTipOpen", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Bubbled event that occurs when the custom ToolTip is being displayed. + /// + public event RoutedEventHandler TrayToolTipOpen + { + add { AddHandler(TrayToolTipOpenEvent, value); } + remove { RemoveHandler(TrayToolTipOpenEvent, value); } + } + + /// + /// A helper method to raise the TrayToolTipOpen event. + /// + protected RoutedEventArgs RaiseTrayToolTipOpenEvent() + { + return RaiseTrayToolTipOpenEvent(this); + } + + /// + /// A static helper method to raise the TrayToolTipOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayToolTipOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayToolTipOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + /// + /// PreviewTrayToolTipOpen Routed Event + /// + public static readonly RoutedEvent PreviewTrayToolTipOpenEvent = EventManager.RegisterRoutedEvent("PreviewTrayToolTipOpen", + RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Tunneled event that occurs when the custom ToolTip is being displayed. + /// + public event RoutedEventHandler PreviewTrayToolTipOpen + { + add { AddHandler(PreviewTrayToolTipOpenEvent, value); } + remove { RemoveHandler(PreviewTrayToolTipOpenEvent, value); } + } + + /// + /// A helper method to raise the PreviewTrayToolTipOpen event. + /// + protected RoutedEventArgs RaisePreviewTrayToolTipOpenEvent() + { + return RaisePreviewTrayToolTipOpenEvent(this); + } + + /// + /// A static helper method to raise the PreviewTrayToolTipOpen event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePreviewTrayToolTipOpenEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PreviewTrayToolTipOpenEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region TrayToolTipClose (and PreviewTrayToolTipClose) + + /// + /// TrayToolTipClose Routed Event + /// + public static readonly RoutedEvent TrayToolTipCloseEvent = EventManager.RegisterRoutedEvent("TrayToolTipClose", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Bubbled event that occurs when a custom tooltip is being closed. + /// + public event RoutedEventHandler TrayToolTipClose + { + add { AddHandler(TrayToolTipCloseEvent, value); } + remove { RemoveHandler(TrayToolTipCloseEvent, value); } + } + + /// + /// A helper method to raise the TrayToolTipClose event. + /// + protected RoutedEventArgs RaiseTrayToolTipCloseEvent() + { + return RaiseTrayToolTipCloseEvent(this); + } + + /// + /// A static helper method to raise the TrayToolTipClose event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseTrayToolTipCloseEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = TrayToolTipCloseEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + /// + /// PreviewTrayToolTipClose Routed Event + /// + public static readonly RoutedEvent PreviewTrayToolTipCloseEvent = EventManager.RegisterRoutedEvent("PreviewTrayToolTipClose", + RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Tunneled event that occurs when a custom tooltip is being closed. + /// + public event RoutedEventHandler PreviewTrayToolTipClose + { + add { AddHandler(PreviewTrayToolTipCloseEvent, value); } + remove { RemoveHandler(PreviewTrayToolTipCloseEvent, value); } + } + + /// + /// A helper method to raise the PreviewTrayToolTipClose event. + /// + protected RoutedEventArgs RaisePreviewTrayToolTipCloseEvent() + { + return RaisePreviewTrayToolTipCloseEvent(this); + } + + /// + /// A static helper method to raise the PreviewTrayToolTipClose event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePreviewTrayToolTipCloseEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PreviewTrayToolTipCloseEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + //ATTACHED EVENTS + + #region PopupOpened + + /// + /// PopupOpened Attached Routed Event + /// + public static readonly RoutedEvent PopupOpenedEvent = EventManager.RegisterRoutedEvent("PopupOpened", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Adds a handler for the PopupOpened attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be added + public static void AddPopupOpenedHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.AddHandler(element, PopupOpenedEvent, handler); + } + + /// + /// Removes a handler for the PopupOpened attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be removed + public static void RemovePopupOpenedHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.RemoveHandler(element, PopupOpenedEvent, handler); + } + + /// + /// A static helper method to raise the PopupOpened event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaisePopupOpenedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = PopupOpenedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region ToolTipOpened + + /// + /// ToolTipOpened Attached Routed Event + /// + public static readonly RoutedEvent ToolTipOpenedEvent = EventManager.RegisterRoutedEvent("ToolTipOpened", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Adds a handler for the ToolTipOpened attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be added + public static void AddToolTipOpenedHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.AddHandler(element, ToolTipOpenedEvent, handler); + } + + /// + /// Removes a handler for the ToolTipOpened attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be removed + public static void RemoveToolTipOpenedHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.RemoveHandler(element, ToolTipOpenedEvent, handler); + } + + /// + /// A static helper method to raise the ToolTipOpened event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseToolTipOpenedEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = ToolTipOpenedEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region ToolTipClose + + /// + /// ToolTipClose Attached Routed Event + /// + public static readonly RoutedEvent ToolTipCloseEvent = EventManager.RegisterRoutedEvent("ToolTipClose", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Adds a handler for the ToolTipClose attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be added + public static void AddToolTipCloseHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.AddHandler(element, ToolTipCloseEvent, handler); + } + + /// + /// Removes a handler for the ToolTipClose attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be removed + public static void RemoveToolTipCloseHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.RemoveHandler(element, ToolTipCloseEvent, handler); + } + + /// + /// A static helper method to raise the ToolTipClose event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + internal static RoutedEventArgs RaiseToolTipCloseEvent(DependencyObject target) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(); + args.RoutedEvent = ToolTipCloseEvent; + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region BalloonShowing + + /// + /// BalloonShowing Attached Routed Event + /// + public static readonly RoutedEvent BalloonShowingEvent = EventManager.RegisterRoutedEvent("BalloonShowing", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Adds a handler for the BalloonShowing attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be added + public static void AddBalloonShowingHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.AddHandler(element, BalloonShowingEvent, handler); + } + + /// + /// Removes a handler for the BalloonShowing attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be removed + public static void RemoveBalloonShowingHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.RemoveHandler(element, BalloonShowingEvent, handler); + } + + /// + /// A static helper method to raise the BalloonShowing event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + /// The instance that manages the balloon. + internal static RoutedEventArgs RaiseBalloonShowingEvent(DependencyObject target, TaskbarIcon source) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(BalloonShowingEvent, source); + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + #region BalloonClosing + + /// + /// BalloonClosing Attached Routed Event + /// + public static readonly RoutedEvent BalloonClosingEvent = EventManager.RegisterRoutedEvent("BalloonClosing", + RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TaskbarIcon)); + + /// + /// Adds a handler for the BalloonClosing attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be added + public static void AddBalloonClosingHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.AddHandler(element, BalloonClosingEvent, handler); + } + + /// + /// Removes a handler for the BalloonClosing attached event + /// + /// UIElement or ContentElement that listens to the event + /// Event handler to be removed + public static void RemoveBalloonClosingHandler(DependencyObject element, RoutedEventHandler handler) + { + RoutedEventHelper.RemoveHandler(element, BalloonClosingEvent, handler); + } + + /// + /// A static helper method to raise the BalloonClosing event on a target element. + /// + /// UIElement or ContentElement on which to raise the event + /// The instance that manages the balloon. + internal static RoutedEventArgs RaiseBalloonClosingEvent(DependencyObject target, TaskbarIcon source) + { + if (target == null) return null; + + RoutedEventArgs args = new RoutedEventArgs(BalloonClosingEvent, source); + RoutedEventHelper.RaiseEvent(target, args); + return args; + } + + #endregion + + + + //ATTACHED PROPERTIES + + #region ParentTaskbarIcon + + /// + /// An attached property that is assigned to + /// + public static readonly DependencyProperty ParentTaskbarIconProperty = + DependencyProperty.RegisterAttached("ParentTaskbarIcon", typeof (TaskbarIcon), typeof (TaskbarIcon)); + + /// + /// Gets the ParentTaskbarIcon property. This dependency property + /// indicates .... + /// + public static TaskbarIcon GetParentTaskbarIcon(DependencyObject d) + { + return (TaskbarIcon)d.GetValue(ParentTaskbarIconProperty); + } + + /// + /// Sets the ParentTaskbarIcon property. This dependency property + /// indicates .... + /// + public static void SetParentTaskbarIcon(DependencyObject d, TaskbarIcon value) + { + d.SetValue(ParentTaskbarIconProperty, value); + } + + #endregion + + + //BASE CLASS PROPERTY OVERRIDES + + /// + /// Registers properties. + /// + static TaskbarIcon() + { + //register change listener for the Visibility property + PropertyMetadata md = new PropertyMetadata(Visibility.Visible, VisibilityPropertyChanged); + VisibilityProperty.OverrideMetadata(typeof(TaskbarIcon), md); + + //register change listener for the DataContext property + md = new FrameworkPropertyMetadata(new PropertyChangedCallback(DataContextPropertyChanged)); + DataContextProperty.OverrideMetadata(typeof(TaskbarIcon), md); + + //register change listener for the ContextMenu property + md = new FrameworkPropertyMetadata(new PropertyChangedCallback(ContextMenuPropertyChanged)); + ContextMenuProperty.OverrideMetadata(typeof(TaskbarIcon), md); + } + + + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/TaskbarIcon.cs b/trunk/NotifyIconWpf/TaskbarIcon.cs new file mode 100644 index 0000000..e56c138 --- /dev/null +++ b/trunk/NotifyIconWpf/TaskbarIcon.cs @@ -0,0 +1,1016 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Interop; +using System.Windows.Threading; +using Hardcodet.Wpf.TaskbarNotification.Interop; +using Point=Hardcodet.Wpf.TaskbarNotification.Interop.Point; + + + +namespace Hardcodet.Wpf.TaskbarNotification +{ + /// + /// A WPF proxy to for a taskbar icon (NotifyIcon) that sits in the system's + /// taskbar notification area ("system tray"). + /// + public partial class TaskbarIcon : FrameworkElement, IDisposable + { + #region Members + + /// + /// Represents the current icon data. + /// + private NotifyIconData iconData; + + /// + /// Receives messages from the taskbar icon. + /// + private readonly WindowMessageSink messageSink; + + /// + /// An action that is being invoked if the + /// fires. + /// + private Action delayedTimerAction; + + /// + /// A timer that is used to differentiate between single + /// and double clicks. + /// + private readonly Timer singleClickTimer; + + /// + /// A timer that is used to close open balloon tooltips. + /// + private readonly Timer balloonCloseTimer; + + /// + /// Indicates whether the taskbar icon has been created or not. + /// + public bool IsTaskbarIconCreated { get; private set; } + + /// + /// Indicates whether custom tooltips are supported, which depends + /// on the OS. Windows Vista or higher is required in order to + /// support this feature. + /// + public bool SupportsCustomToolTips + { + get { return messageSink.Version == NotifyIconVersion.Vista; } + } + + + + /// + /// Checks whether a non-tooltip popup is currently opened. + /// + 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 + + /// + /// Inits the taskbar icon and registers a message listener + /// in order to receive events from the taskbar area. + /// + public TaskbarIcon() + { + //using dummy sink in design mode + messageSink = Util.IsDesignMode + ? WindowMessageSink.CreateEmpty() + : new WindowMessageSink(NotifyIconVersion.Win95); + + //init icon data structure + iconData = NotifyIconData.CreateDefault(messageSink.MessageWindowHandle); + + //create the taskbar icon + CreateTaskbarIcon(); + + //register event listeners + messageSink.MouseEventReceived += OnMouseEvent; + messageSink.TaskbarCreated += OnTaskbarCreated; + messageSink.ChangeToolTipStateRequest += OnToolTipChange; + messageSink.BalloonToolTipChanged += OnBalloonToolTipChanged; + + //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; + } + + #endregion + + + #region Custom Balloons + + /// + /// Shows a custom control as a tooltip in the tray location. + /// + /// + /// An optional animation for the popup. + /// The time after which the popup is being closed. + /// Submit null in order to keep the balloon open inde + /// + /// If + /// is a null reference. + public void ShowCustomBalloon(UIElement balloon, PopupAnimation animation, int? timeout) + { + Dispatcher dispatcher = this.GetDispatcher(); + if (!dispatcher.CheckAccess()) + { + var action = new Action(() => ShowCustomBalloon(balloon, animation, timeout)); + dispatcher.Invoke(DispatcherPriority.Normal, action); + return; + } + + 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; + + //provide the popup with the taskbar icon's data context + UpdateDataContext(popup, null, DataContext); + + //don't animate by default - devs can use attached + //events or override + popup.PopupAnimation = animation; + + popup.Child = balloon; + + //don't set the PlacementTarget as it causes the popup to become hidden if the + //TaskbarIcon's parent is hidden, too... + //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); + } + + //assign this instance as an attached property + SetParentTaskbarIcon(balloon, this); + + //fire attached event + RaiseBalloonShowingEvent(balloon, this); + + //display item + popup.IsOpen = true; + + if (timeout.HasValue) + { + //register timer to close the popup + balloonCloseTimer.Change(timeout.Value, Timeout.Infinite); + } + } + + + /// + /// Resets the closing timeout, which effectively + /// keeps a displayed balloon message open until + /// it is either closed programmatically through + /// or due to a new + /// message being displayed. + /// + public void ResetBalloonCloseTimer() + { + if (IsDisposed) return; + + lock (this) + { + //reset timer in any case + balloonCloseTimer.Change(Timeout.Infinite, Timeout.Infinite); + } + } + + + /// + /// Closes the current , if the + /// property is set. + /// + public void CloseBalloon() + { + if (IsDisposed) return; + + Dispatcher dispatcher = this.GetDispatcher(); + if (!dispatcher.CheckAccess()) + { + Action action = CloseBalloon; + dispatcher.Invoke(DispatcherPriority.Normal, action); + 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) + { + UIElement element = popup.Child; + + //announce closing + RoutedEventArgs eventArgs = RaiseBalloonClosingEvent(element, this); + if (!eventArgs.Handled) + { + //if the event was handled, clear the reference to the popup, + //but don't close it - the handling code has to manage this stuff now + + //close the popup + popup.IsOpen = false; + + //reset attached property + if (element != null) SetParentTaskbarIcon(element, null); + } + + //remove custom balloon anyway + SetCustomBalloon(null); + } + } + } + + + /// + /// Timer-invoke event which closes the currently open balloon and + /// resets the dependency property. + /// + private void CloseBalloonCallback(object state) + { + if (IsDisposed) return; + + //switch to UI thread + Action action = CloseBalloon; + this.GetDispatcher().Invoke(action); + } + + #endregion + + #region Process Incoming Mouse Events + + /// + /// Processes mouse events, which are bubbled + /// through the class' routed events, trigger + /// certain actions (e.g. show a popup), or + /// both. + /// + /// Event flag. + private void OnMouseEvent(MouseEvent me) + { + if (IsDisposed) return; + + switch (me) + { + case MouseEvent.MouseMove: + RaiseTrayMouseMoveEvent(); + //immediately return - there's nothing left to evaluate + return; + case MouseEvent.IconRightMouseDown: + RaiseTrayRightMouseDownEvent(); + break; + case MouseEvent.IconLeftMouseDown: + RaiseTrayLeftMouseDownEvent(); + break; + case MouseEvent.IconRightMouseUp: + RaiseTrayRightMouseUpEvent(); + break; + case MouseEvent.IconLeftMouseUp: + RaiseTrayLeftMouseUpEvent(); + break; + case MouseEvent.IconMiddleMouseDown: + RaiseTrayMiddleMouseDownEvent(); + break; + case MouseEvent.IconMiddleMouseUp: + RaiseTrayMiddleMouseUpEvent(); + break; + case MouseEvent.IconDoubleClick: + //cancel single click timer + singleClickTimer.Change(Timeout.Infinite, Timeout.Infinite); + //bubble event + RaiseTrayMouseDoubleClickEvent(); + break; + case MouseEvent.BalloonToolTipClicked: + RaiseTrayBalloonTipClickedEvent(); + break; + default: + throw new ArgumentOutOfRangeException("me", "Missing handler for mouse event flag: " + me); + } + + + //get mouse coordinates + Point cursorPosition = new Point(); + WinApi.GetCursorPos(ref cursorPosition); + + bool isLeftClickCommandInvoked = false; + + //show popup, if requested + if (me.IsMatch(PopupActivation)) + { + if (me == MouseEvent.IconLeftMouseUp) + { + //show popup once we are sure it's not a double click + delayedTimerAction = () => + { + LeftClickCommand.ExecuteIfEnabled(LeftClickCommandParameter, LeftClickCommandTarget ?? this); + ShowTrayPopup(cursorPosition); + }; + singleClickTimer.Change(WinApi.GetDoubleClickTime(), Timeout.Infinite); + isLeftClickCommandInvoked = true; + } + else + { + //show popup immediately + ShowTrayPopup(cursorPosition); + } + } + + + //show context menu, if requested + if (me.IsMatch(MenuActivation)) + { + if (me == MouseEvent.IconLeftMouseUp) + { + //show context menu once we are sure it's not a double click + delayedTimerAction = () => + { + LeftClickCommand.ExecuteIfEnabled(LeftClickCommandParameter, LeftClickCommandTarget ?? this); + ShowContextMenu(cursorPosition); + }; + singleClickTimer.Change(WinApi.GetDoubleClickTime(), Timeout.Infinite); + isLeftClickCommandInvoked = true; + } + else + { + //show context menu immediately + ShowContextMenu(cursorPosition); + } + } + + //make sure the left click command is invoked on mouse clicks + if (me == MouseEvent.IconLeftMouseUp && !isLeftClickCommandInvoked) + { + //show context menu once we are sure it's not a double click + delayedTimerAction = () => LeftClickCommand.ExecuteIfEnabled(LeftClickCommandParameter, LeftClickCommandTarget ?? this); + singleClickTimer.Change(WinApi.GetDoubleClickTime(), Timeout.Infinite); + } + + } + + #endregion + + #region ToolTips + + /// + /// Displays a custom tooltip, if available. This method is only + /// invoked for Windows Vista and above. + /// + /// Whether to show or hide the tooltip. + private void OnToolTipChange(bool visible) + { + //if we don't have a tooltip, there's nothing to do here... + if (TrayToolTipResolved == null) return; + + if (visible) + { + if (IsPopupOpen) + { + //ignore if we are already displaying something down there + return; + } + + var args = RaisePreviewTrayToolTipOpenEvent(); + if (args.Handled) return; + + TrayToolTipResolved.IsOpen = true; + + //raise attached event first + if (TrayToolTip != null) RaiseToolTipOpenedEvent(TrayToolTip); + + //bubble routed event + RaiseTrayToolTipOpenEvent(); + } + else + { + var args = RaisePreviewTrayToolTipCloseEvent(); + if (args.Handled) return; + + //raise attached event first + if (TrayToolTip != null) RaiseToolTipCloseEvent(TrayToolTip); + + TrayToolTipResolved.IsOpen = false; + + //bubble event + RaiseTrayToolTipCloseEvent(); + } + } + + + /// + /// Creates a control that either + /// wraps the currently set + /// control or the string.
+ /// If itself is already + /// a instance, it will be used directly. + ///
+ /// We use a rather than + /// because there was no way to prevent a + /// popup from causing cyclic open/close commands if it was + /// placed under the mouse. ToolTip internally uses a Popup of + /// its own, but takes advance of Popup's internal + /// property which prevents this issue. + private void CreateCustomToolTip() + { + //check if the item itself is a tooltip + ToolTip tt = TrayToolTip as ToolTip; + + if (tt == null && TrayToolTip != null) + { + //create an invisible tooltip that hosts the UIElement + tt = new ToolTip(); + tt.Placement = PlacementMode.Mouse; + + //do *not* set the placement target, as it causes the popup to become hidden if the + //TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through + //the ParentTaskbarIcon attached dependency property: + //tt.PlacementTarget = this; + + //make sure the tooltip is invisible + tt.HasDropShadow = false; + tt.BorderThickness = new Thickness(0); + tt.Background = System.Windows.Media.Brushes.Transparent; + + //setting the + tt.StaysOpen = true; + tt.Content = TrayToolTip; + } + else if (tt == null && !String.IsNullOrEmpty(ToolTipText)) + { + //create a simple tooltip for the string + tt = new ToolTip(); + tt.Content = ToolTipText; + } + + //the tooltip explicitly gets the DataContext of this instance. + //If there is no DataContext, the TaskbarIcon assigns itself + if (tt != null) + { + UpdateDataContext(tt, null, DataContext); + } + + //store a reference to the used tooltip + SetTrayToolTipResolved(tt); + } + + + /// + /// Sets tooltip settings for the class depending on defined + /// dependency properties and OS support. + /// + private void WriteToolTipSettings() + { + const IconDataMembers flags = IconDataMembers.Tip; + iconData.ToolTipText = ToolTipText; + + if (messageSink.Version == NotifyIconVersion.Vista) + { + //we need to set a tooltip text to get tooltip events from the + //taskbar icon + if (String.IsNullOrEmpty(iconData.ToolTipText) && TrayToolTipResolved != null) + { + //if we have not tooltip text but a custom tooltip, we + //need to set a dummy value (we're displaying the ToolTip control, not the string) + iconData.ToolTipText = "ToolTip"; + } + } + + //update the tooltip text + Util.WriteIconData(ref iconData, NotifyCommand.Modify, flags); + } + + #endregion + + #region Custom Popup + + /// + /// Creates a control that either + /// wraps the currently set + /// control or the string.
+ /// If itself is already + /// a instance, it will be used directly. + ///
+ /// We use a rather than + /// because there was no way to prevent a + /// popup from causing cyclic open/close commands if it was + /// placed under the mouse. ToolTip internally uses a Popup of + /// its own, but takes advance of Popup's internal + /// property which prevents this issue. + private void CreatePopup() + { + //check if the item itself is a popup + Popup popup = TrayPopup as Popup; + + if (popup == null && TrayPopup != null) + { + //create an invisible popup that hosts the UIElement + popup = new Popup(); + popup.AllowsTransparency = true; + + //don't animate by default - devs can use attached + //events or override + popup.PopupAnimation = PopupAnimation.None; + + //the CreateRootPopup method outputs binding errors in the debug window because + //it tries to bind to "Popup-specific" properties in case they are provided by the child. + //We don't need that so just assign the control as the child. + popup.Child = TrayPopup; + + //do *not* set the placement target, as it causes the popup to become hidden if the + //TaskbarIcon's parent is hidden, too. At runtime, the parent can be resolved through + //the ParentTaskbarIcon attached dependency property: + //popup.PlacementTarget = this; + + popup.Placement = PlacementMode.AbsolutePoint; + popup.StaysOpen = false; + } + + //the popup explicitly gets the DataContext of this instance. + //If there is no DataContext, the TaskbarIcon assigns itself + if (popup != null) + { + UpdateDataContext(popup, null, DataContext); + } + + //store a reference to the used tooltip + SetTrayPopupResolved(popup); + } + + + /// + /// Displays the control if + /// it was set. + /// + private void ShowTrayPopup(Point cursorPosition) + { + if (IsDisposed) return; + + //raise preview event no matter whether popup is currently set + //or not (enables client to set it on demand) + var args = RaisePreviewTrayPopupOpenEvent(); + if (args.Handled) return; + + if (TrayPopup != null) + { + //use absolute position, but place the popup centered above the icon + TrayPopupResolved.Placement = PlacementMode.AbsolutePoint; + TrayPopupResolved.HorizontalOffset = cursorPosition.X; + TrayPopupResolved.VerticalOffset = cursorPosition.Y; + + //open popup + TrayPopupResolved.IsOpen = true; + + + IntPtr handle = IntPtr.Zero; + if (TrayPopupResolved.Child != null) + { + //try to get a handle on the popup itself (via its child) + HwndSource source = (HwndSource)PresentationSource.FromVisual(TrayPopupResolved.Child); + if (source != null) handle = source.Handle; + } + + //if we don't have a handle for the popup, fall back to the message sink + if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle; + + //activate either popup or message sink to track deactivation. + //otherwise, the popup does not close if the user clicks somewhere else + WinApi.SetForegroundWindow(handle); + + //raise attached event - item should never be null unless developers + //changed the CustomPopup directly... + if (TrayPopup != null) RaisePopupOpenedEvent(TrayPopup); + + //bubble routed event + RaiseTrayPopupOpenEvent(); + } + } + + #endregion + + #region Context Menu + + /// + /// Displays the if + /// it was set. + /// + private void ShowContextMenu(Point cursorPosition) + { + if (IsDisposed) return; + + //raise preview event no matter whether context menu is currently set + //or not (enables client to set it on demand) + var args = RaisePreviewTrayContextMenuOpenEvent(); + if (args.Handled) return; + + if (ContextMenu != null) + { + //use absolute position + ContextMenu.Placement = PlacementMode.AbsolutePoint; + ContextMenu.HorizontalOffset = cursorPosition.X; + ContextMenu.VerticalOffset = cursorPosition.Y; + ContextMenu.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); + + //bubble event + RaiseTrayContextMenuOpenEvent(); + } + } + + #endregion + + #region Balloon Tips + + /// + /// Bubbles events if a balloon ToolTip was displayed + /// or removed. + /// + /// Whether the ToolTip was just displayed + /// or removed. + private void OnBalloonToolTipChanged(bool visible) + { + if (visible) + { + RaiseTrayBalloonTipShownEvent(); + } + else + { + RaiseTrayBalloonTipClosedEvent(); + } + } + + /// + /// Displays a balloon tip with the specified title, + /// text, and icon in the taskbar for the specified time period. + /// + /// The title to display on the balloon tip. + /// The text to display on the balloon tip. + /// A symbol that indicates the severity. + public void ShowBalloonTip(string title, string message, BalloonIcon symbol) + { + lock (this) + { + ShowBalloonTip(title, message, symbol.GetBalloonFlag(), IntPtr.Zero); + } + } + + + /// + /// Displays a balloon tip with the specified title, + /// text, and a custom icon in the taskbar for the specified time period. + /// + /// The title to display on the balloon tip. + /// The text to display on the balloon tip. + /// A custom icon. + /// If + /// is a null reference. + public void ShowBalloonTip(string title, string message, Icon customIcon) + { + if (customIcon == null) throw new ArgumentNullException("customIcon"); + + lock (this) + { + ShowBalloonTip(title, message, BalloonFlags.User, customIcon.Handle); + } + } + + + /// + /// Invokes in order to display + /// a given balloon ToolTip. + /// + /// The title to display on the balloon tip. + /// The text to display on the balloon tip. + /// Indicates what icon to use. + /// A handle to a custom icon, if any, or + /// . + private void ShowBalloonTip(string title, string message, BalloonFlags flags, IntPtr balloonIconHandle) + { + EnsureNotDisposed(); + + iconData.BalloonText = message ?? String.Empty; + iconData.BalloonTitle = title ?? String.Empty; + + iconData.BalloonFlags = flags; + iconData.CustomBalloonIconHandle = balloonIconHandle; + Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Info | IconDataMembers.Icon); + } + + + /// + /// Hides a balloon ToolTip, if any is displayed. + /// + public void HideBalloonTip() + { + EnsureNotDisposed(); + + //reset balloon by just setting the info to an empty string + iconData.BalloonText = iconData.BalloonTitle = String.Empty; + Util.WriteIconData(ref iconData, NotifyCommand.Modify, IconDataMembers.Info); + } + + #endregion + + #region Single Click Timer event + + /// + /// Performs a delayed action if the user requested an action + /// based on a single click of the left mouse.
+ /// This method is invoked by the . + ///
+ private void DoSingleClickAction(object state) + { + if (IsDisposed) return; + + //run action + Action action = delayedTimerAction; + if (action != null) + { + //cleanup action + delayedTimerAction = null; + + //switch to UI thread + this.GetDispatcher().Invoke(action); + } + } + + #endregion + + #region Set Version (API) + + /// + /// Sets the version flag for the . + /// + private void SetVersion() + { + iconData.VersionOrTimeout = (uint) NotifyIconVersion.Vista; + bool status = WinApi.Shell_NotifyIcon(NotifyCommand.SetVersion, ref iconData); + + if (!status) + { + iconData.VersionOrTimeout = (uint) NotifyIconVersion.Win2000; + status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); + } + + if (!status) + { + iconData.VersionOrTimeout = (uint) NotifyIconVersion.Win95; + status = Util.WriteIconData(ref iconData, NotifyCommand.SetVersion); + } + + if (!status) + { + Debug.Fail("Could not set version"); + } + } + + #endregion + + #region Create / Remove Taskbar Icon + + /// + /// Recreates the taskbar icon if the whole taskbar was + /// recreated (e.g. because Explorer was shut down). + /// + private void OnTaskbarCreated() + { + IsTaskbarIconCreated = false; + CreateTaskbarIcon(); + } + + + /// + /// Creates the taskbar icon. This message is invoked during initialization, + /// if the taskbar is restarted, and whenever the icon is displayed. + /// + private void CreateTaskbarIcon() + { + lock (this) + { + if (!IsTaskbarIconCreated) + { + const IconDataMembers members = IconDataMembers.Message + | IconDataMembers.Icon + | IconDataMembers.Tip; + + //write initial configuration + var status = Util.WriteIconData(ref iconData, NotifyCommand.Add, members); + if (!status) + { + throw new Win32Exception("Could not create icon data"); + } + + //set to most recent version + SetVersion(); + messageSink.Version = (NotifyIconVersion) iconData.VersionOrTimeout; + + IsTaskbarIconCreated = true; + } + } + } + + + /// + /// Closes the taskbar icon if required. + /// + private void RemoveTaskbarIcon() + { + lock (this) + { + if (IsTaskbarIconCreated) + { + Util.WriteIconData(ref iconData, NotifyCommand.Delete, IconDataMembers.Message); + IsTaskbarIconCreated = false; + } + } + } + + #endregion + + #region Dispose / Exit + + /// + /// Set to true as soon as + /// has been invoked. + /// + public bool IsDisposed { get; private set; } + + + /// + /// Checks if the object has been disposed and + /// raises a in case + /// the flag is true. + /// + private void EnsureNotDisposed() + { + if (IsDisposed) throw new ObjectDisposedException(Name ?? GetType().FullName); + } + + + /// + /// Disposes the class if the application exits. + /// + private void OnExit(object sender, EventArgs e) + { + Dispose(); + } + + + /// + /// This destructor will run only if the + /// method does not get called. This gives this base class the + /// opportunity to finalize. + /// + /// Important: Do not provide destructors in types derived from + /// this class. + /// + /// + ~TaskbarIcon() + { + Dispose(false); + } + + + /// + /// Disposes the object. + /// + /// This method is not virtual by design. Derived classes + /// should override . + /// + 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); + } + + + /// + /// Closes the tray and releases all resources. + /// + /// + /// Dispose(bool disposing) executes in two distinct scenarios. + /// If disposing equals true, the method has been called directly + /// or indirectly by a user's code. Managed and unmanaged resources + /// can be disposed. + /// + /// If disposing equals false, the method + /// has been called by the runtime from inside the finalizer and you + /// should not reference other objects. Only unmanaged resources can + /// be disposed. + /// Check the property to determine whether + /// the method has already been called. + private void Dispose(bool disposing) + { + //don't do anything if the component is already disposed + if (IsDisposed || !disposing) return; + + lock (this) + { + IsDisposed = true; + + //deregister application event listener + if (Application.Current != null) + { + Application.Current.Exit -= OnExit; + } + + //stop timers + singleClickTimer.Dispose(); + balloonCloseTimer.Dispose(); + + //dispose message sink + messageSink.Dispose(); + + //remove icon + RemoveTaskbarIcon(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/Util.cs b/trunk/NotifyIconWpf/Util.cs new file mode 100644 index 0000000..3fa31be --- /dev/null +++ b/trunk/NotifyIconWpf/Util.cs @@ -0,0 +1,308 @@ +// hardcodet.net NotifyIcon for WPF +// Copyright (c) 2009 Philipp Sumi +// Contact and Information: http://www.hardcodet.net +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the Code Project Open License (CPOL); +// either version 1.0 of the License, or (at your option) any later +// version. +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE + + +using System; +using System.ComponentModel; +using System.Drawing; +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 +{ + /// + /// Util and extension methods. + /// + internal static class Util + { + public static readonly object SyncRoot = new object(); + + #region IsDesignMode + + private static readonly bool isDesignMode; + + /// + /// Checks whether the application is currently in design mode. + /// + 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 + + /// + /// Creates an transparent window without dimension that + /// can be used to temporarily obtain focus and/or + /// be used as a window message sink. + /// + /// Empty window. + public static Window CreateHelperWindow() + { + return new Window + { + Width = 0, + Height = 0, + ShowInTaskbar = false, + WindowStyle = WindowStyle.None, + AllowsTransparency = true, + Opacity = 0 + }; + } + + #endregion + + #region WriteIconData + + /// + /// Updates the taskbar icons with data provided by a given + /// instance. + /// + /// Configuration settings for the NotifyIcon. + /// Operation on the icon (e.g. delete the icon). + /// True if the data was successfully written. + /// See Shell_NotifyIcon documentation on MSDN for details. + public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command) + { + return WriteIconData(ref data, command, data.ValidMembers); + } + + + /// + /// Updates the taskbar icons with data provided by a given + /// instance. + /// + /// Configuration settings for the NotifyIcon. + /// Operation on the icon (e.g. delete the icon). + /// Defines which members of the + /// structure are set. + /// True if the data was successfully written. + /// See Shell_NotifyIcon documentation on MSDN for details. + 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 + + /// + /// Gets a enum value that + /// matches a given . + /// + 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 + + /// + /// Reads a given image resource into a WinForms icon. + /// + /// Image source pointing to + /// an icon file (*.ico). + /// An icon object that can be used with the + /// taskbar area. + 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 + + /// + /// Checks a list of candidates for equality to a given + /// reference value. + /// + /// + /// The evaluated value. + /// A liste of possible values that are + /// regarded valid. + /// True if one of the submitted + /// matches the evaluated value. If the + /// parameter itself is null, too, the method returns false as well, + /// which allows to check with null values, too. + /// If + /// is a null reference. + public static bool Is(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 + + /// + /// Checks if a given is a match for + /// an effectively pressed mouse button. + /// + 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 + + /// + /// Executes a given command if its method + /// indicates it can run. + /// + /// The command to be executed, or a null reference. + /// An optional parameter that is associated with + /// the command. + /// The target element on which to raise the command. + 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 + + /// + /// Returns a dispatcher for multi-threaded scenarios + /// + /// + 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; + } + + + /// + /// Checks whether the + /// is bound or not. + /// + /// The element to be checked. + /// True if the data context property is being managed by a + /// binding expression. + /// If + /// is a null reference. + public static bool IsDataContextDataBound(this FrameworkElement element) + { + if (element == null) throw new ArgumentNullException("element"); + return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null; + } + } +} \ No newline at end of file diff --git a/trunk/NotifyIconWpf/pithos.snk b/trunk/NotifyIconWpf/pithos.snk new file mode 100644 index 0000000000000000000000000000000000000000..2069d32e563de400beb1a972c946ce177b074ef4 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096;V}LV6+_zUyQ2acG1{SHi_%xL-;Y`sk zO_q{_R=X%l_bl+sW8AJxseNcB)DcDUSL1_!N5x9({xv)v7b&8nUH5Erdu^&StxlxB zhlttl{pG$`c^AgWq$xE}O)Pex0cGXoD$lX!5yR*`Y{y_NNG5KxePK9jrpe#=bNQ7u z1Aw9*`onL7bRd}Q@$8)fc$+oPFsPNf+UD?S`Yyv3Wyd(qDvI&Obdt}DQu>KSdLK(# z{}SQTr9%DVJJQVyK*#lDgI6@$PKEsC@U?Epv?hJ95DE0RWe3+7h44WjfZDg;44)4o z<^`PD-lv&wj0a0mJJ1O6C2T&%gcZwaaisFyjlIz)k4!mmHD?lacL2xz z59*5?_6ICbx+(wesu3+yJRVio42H8PK8s!UTH+AgQ*?)6SWKmZKRHIBRw~&27n*^} zG$*jG4S?!n1X~Icebr3~36pEM?2-s)EWX|@hui&MMU;;7Fb7hYO2T2o%oiCX_v)0V z!rHq?-=hR>*Gh=)2Sp9z=(GpN&o>lFchQULGF%V3vL z2J$G$gGL-P|&?lbxE#GaLxGQDnH;y-2@G$n69^p zYT{~oCJ(2wj7-QXM)q_E2~6|99gbH1OAj2FW-FI*ejgQ|hb9E!$l1}`SPG3+YiRM= iwK + + + + + + + + + + + + diff --git a/trunk/Pithos.Client.WPF/App.xaml.cs b/trunk/Pithos.Client.WPF/App.xaml.cs new file mode 100644 index 0000000..54109ad --- /dev/null +++ b/trunk/Pithos.Client.WPF/App.xaml.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Windows; + +namespace Pithos.Client.WPF +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public App() + { + InitializeComponent(); + } + } + +} diff --git a/trunk/Pithos.Client.WPF/AppBootstrapper.cs b/trunk/Pithos.Client.WPF/AppBootstrapper.cs new file mode 100644 index 0000000..a9167f8 --- /dev/null +++ b/trunk/Pithos.Client.WPF/AppBootstrapper.cs @@ -0,0 +1,81 @@ +using System.Windows; +using System.Windows.Navigation; +using Caliburn.Micro.Logging; +using Pithos.Core; +using Pithos.Network; + +namespace Pithos.Client.WPF +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.Composition; + using System.ComponentModel.Composition.Hosting; + using System.ComponentModel.Composition.Primitives; + using System.Linq; + using Caliburn.Micro; + + public class AppBootstrapper : Bootstrapper + { + CompositionContainer container; + + public AppBootstrapper() + { + LogManager.GetLog = type => new DebugLogger(type); + } + + /// + /// By default, we are configured to use MEF + /// + protected override void Configure() { + var catalog = new AggregateCatalog( + AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType() + ); + + Type[] types = { typeof(PithosMonitor), typeof(CloudFilesClient) }; + foreach (var type in types) + { + catalog.Catalogs.Add(new AssemblyCatalog(type.Assembly)); + } + + + + + container = new CompositionContainer(catalog); + + var batch = new CompositionBatch(); + + batch.AddExportedValue(new WindowManager()); + batch.AddExportedValue(new EventAggregator()); + batch.AddExportedValue(container); + batch.AddExportedValue(catalog); + + + + + + + container.Compose(batch); + } + + protected override object GetInstance(Type serviceType, string key) + { + string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key; + var exports = container.GetExportedValues(contract); + + if (exports.Count() > 0) + return exports.First(); + + throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract)); + } + + protected override IEnumerable GetAllInstances(Type serviceType) + { + return container.GetExportedValues(AttributedModelServices.GetContractName(serviceType)); + } + + protected override void BuildUp(object instance) + { + container.SatisfyImportsOnce(instance); + } + } +} diff --git a/trunk/Pithos.Client.WPF/Caliburn/Micro/Logging/DebugLogger.cs b/trunk/Pithos.Client.WPF/Caliburn/Micro/Logging/DebugLogger.cs new file mode 100644 index 0000000..d274791 --- /dev/null +++ b/trunk/Pithos.Client.WPF/Caliburn/Micro/Logging/DebugLogger.cs @@ -0,0 +1,85 @@ +using System; +using System.Diagnostics; + +namespace Caliburn.Micro.Logging +{ + /// + /// Implementation of the ILog and ILogExtended interfaces using + /// . + /// + public class DebugLogger : ILog//, ILogExtended + { + #region Constants + private const string ErrorText = "ERROR"; + private const string WarnText = "WARN"; + private const string InfoText = "INFO"; + #endregion + + #region Fields + private readonly Type _type; + #endregion + + #region Constructors + public DebugLogger(Type type) + { + _type = type; + } + #endregion + + #region Helper Methods + private string CreateLogMessage(string format, params object[] args) + { + return string.Format("[{0}] {1}", DateTime.Now.ToString("o"), string.Format(format, args)); + } + #endregion + + #region ILog Members + /// + /// Logs the exception. + /// + /// The exception. + public void Error(Exception exception) + { + Debug.WriteLine(CreateLogMessage(exception.ToString()), ErrorText); + } + /// + /// Logs the message as info. + /// + /// A formatted message.Parameters to be injected into the formatted message. + public void Info(string format, params object[] args) + { + Debug.WriteLine(CreateLogMessage(format, args), InfoText); + } + /// + /// Logs the message as a warning. + /// + /// A formatted message.Parameters to be injected into the formatted message. + public void Warn(string format, params object[] args) + { + Debug.WriteLine(CreateLogMessage(format, args), WarnText); + } + #endregion + + #region Implementation of ILogExtended + /// + /// Logs the message as error. + /// + /// A formatted message. + /// Parameters to be injected into the formatted message. + public void Error(string format, params object[] args) + { + Debug.WriteLine(CreateLogMessage(format, args), ErrorText); + } + /// + /// Logs the exception. + /// + /// The exception. + /// A formatted message. + /// Parameters to be injected into the formatted message. + public void Error(Exception exception, string format, params object[] args) + { + Debug.WriteLine(CreateLogMessage(format + " - Exception = " + exception.ToString(), args), ErrorText); + } + #endregion + } +} diff --git a/trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs b/trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs new file mode 100644 index 0000000..5e8583e --- /dev/null +++ b/trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs @@ -0,0 +1,123 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +using System.ComponentModel.Composition; +using System.Configuration; +using System.Dynamic; +using Pithos.Client.WPF.Properties; +using Pithos.Interfaces; + +namespace Pithos.Client.WPF.Configuration +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + [Export(typeof(IPithosSettings))] + public class PithosSettings : DynamicObject, IPithosSettings + { + public string PithosPath + { + get { return Settings.Default.PithosPath; } + set { Settings.Default.PithosPath = value; } + } + + public string IconsPath + { + get { return Settings.Default.IconPath; } + set { Settings.Default.IconPath = value; } + } + + public string UserName + { + get { return Settings.Default.UserName; } + set { Settings.Default.UserName = value; } + } + + public string ApiKey + { + get { return Settings.Default.ApiKey; } + set { Settings.Default.ApiKey = value; } + } + + public AccountsCollection Accounts + { + get { return Settings.Default.Accounts; } + set { Settings.Default.Accounts = value; } + } + + public string ProxyServer + { + get { return Settings.Default.ProxyServer; } + set { Settings.Default.ProxyServer = value; } + } + + public string ProxyPort + { + get { return Settings.Default.ProxyPort; } + set { Settings.Default.ProxyPort = value; } + } + + public string ProxyUsername + { + get { return Settings.Default.ProxyUsername; } + set { Settings.Default.ProxyUsername = value; } + } + + + public string ProxyPassword + { + get { return Settings.Default.ProxyPassword; } + set { Settings.Default.ProxyPassword = value; } + } + + public bool ProxyAuthentication + { + + get { return Settings.Default.ProxyAuthentication; } + set { Settings.Default.ProxyAuthentication = value; } + } + + public bool ExtensionsActivated + { + + get { return Settings.Default.ExtensionsActivated; } + set { Settings.Default.ExtensionsActivated = value; } + } + + public override IEnumerable GetDynamicMemberNames() + { + return (from SettingsProperty property in Settings.Default.Properties + select property.Name); + } + + + private Lazy> _propertyNames = new Lazy>( + () => (from SettingsProperty property in + Settings.Default.Properties + select property).ToLookup(property => property.Name)); + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + result = null; + if (!_propertyNames.Value.Contains(binder.Name)) + return false; + result=Settings.Default.Properties[binder.Name]; + return true; + } + + public void Save() + { + Settings.Default.Save(); + } + + public void Reload() + { + Settings.Default.Reload(); + } + } +} diff --git a/trunk/Pithos.Client.WPF/FileEntry.cs b/trunk/Pithos.Client.WPF/FileEntry.cs new file mode 100644 index 0000000..0958358 --- /dev/null +++ b/trunk/Pithos.Client.WPF/FileEntry.cs @@ -0,0 +1,8 @@ +namespace Pithos.Client.WPF +{ + public class FileEntry + { + public string FileName { get; set; } + public string FullPath { get; set; } + } +} \ No newline at end of file diff --git a/trunk/Pithos.Client.WPF/IShell.cs b/trunk/Pithos.Client.WPF/IShell.cs new file mode 100644 index 0000000..8290828 --- /dev/null +++ b/trunk/Pithos.Client.WPF/IShell.cs @@ -0,0 +1,3 @@ +namespace Pithos.Client.WPF { + public interface IShell {} +} diff --git a/trunk/Pithos.Client.WPF/Images/Accounts.png b/trunk/Pithos.Client.WPF/Images/Accounts.png new file mode 100644 index 0000000000000000000000000000000000000000..356ebfa07b65c22e2af74eba7c5facaebf7b8953 GIT binary patch literal 1854 zcmV-E2f_G>P))|&t4V_nVS@Bj9_Sgql0ZF<3-Zqr`{ zqyeR2sx2CNKWv-3V$txczj^#d?@IR+SE_->e)W%)`BHsPUvGBdilsR^GHrxIE&hh< zb9S=Kz|k|D9xop5Ogr~H_rnb*t{cFk+um&}l$lxox) z9)Xky1g2#YkA;cH94tFDUzk>8=@&NFk00EnuNgoUM&b@3?-P#m+8r6K!}!LKx>T%XDTfujvzZ!id?ys%Og=xDAhbr7+&C z73!81nR_{wfgIFIzNVGDzf`J`jf4@jQr|@i(4du~RH`vKdh|mOb+=xeJHSiZzNx?U z#Lj2Rh0=YK6M2!zrVyry)?!AgIA?m4R7_6h+9oA3K>^H8-? z`+T`rp)Hj_&!jnV!5CDE6^4(0baZU!@IQqxYS*PB`rgxf%xK8Gy-@QLO2Nd~6i!=| zKxx!W1QXc{dM)4yP;NXZ0yXn=T@v) zhBh5eesYSw8|GsUH-f+qU}JvneCnnIYHRK~Havws@3kJ>cX>g_Fll(2;e>|IuZHT?%IXR>e)EW}46orX1Si+-w(L&syRShGSWaQXU%K1~=y6Fyb z^U~OsiByVGp~C3M1RwMdQZANXvBTyAJDz(;3avE{JofuXBeAyUzjDW|q!S^^)qrZf z^)|hkN*MSAUK8JQ@ftNy9+_-APO=?$Mgx(Mre2)l#F2kvM-n8`^GK%CBvWmqQx5T% zO}^OVtv!EZ^7O}#DCz&s0tme3=J{*ZFkSQ*9dl>m-p8$#ajO*q&&4tgoQOqRG(<9+ zAdyPq6Q)pBXe|MOR3=?LT`ZWNp-+f>LPpwVzCqUs105n1((e;p|mM!!0G s>R;V~->?DWe{d_;f!`dj*QVe24{Yh2ThI*-=l}o!07*qoM6N<$g7E~Am;e9( literal 0 HcmV?d00001 diff --git a/trunk/Pithos.Client.WPF/Images/Advanced.png b/trunk/Pithos.Client.WPF/Images/Advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..b506c9e18169ee94b39cac51790c06a997f8f1c7 GIT binary patch literal 2618 zcmV-A3dQw_P)`6pHR9M5Um-};6^%=&Wb3bQq*{CQc5`F1o83KU z&-L3MsLXUE3{!djfOkIgeV_Mv=1UPma5*h}_TYQEZqDU-_OQq^U$K<6Wy_kI6S&5r z2q9Rxv5HTs`XrI(j&EKwO6b8J5h7Awpo&FMvW~;*u3tR^VbAm-fuqL=JC3hOrBH(UgV&u zI;yLi(ARsRM-YV6(n(|ZQ6sXTDl#Gw8EqZ?Xl?D*FHP!wdie05)xT zr_{16J4I6ohGyzlEW7`z*TgDu*|6KB-^U_@tCG3_C8UWJKbTKLU8{ssVPsxqvKuboXPTBth4J zj4U4ti+^^nCp~w#&6!!8H!2r2Xmozpj&N@Xw9<-9XUs6e763q1)rGTX&&HV11?cJR z$EHo2=C6DDnKc`pdq#WZ)z^QbD9IUKuV>TBw$`gcFbZq{_|-+pN^P9K@w?X zr}K~pqp&&bh{!a$+S<@^vc|YBEzI6}%XFMM+l)}C=kG3;>kU~>>|3$&VU}SS0KoPS zwxQ`{*jw7WaxeRt~?<9}Abv3M`i*Ei?e6DMceopuE31F^`3j;2vX z6Q&kVn~G@Mgw0_?q?dx>7HEb>Sy>qvhK8makQE)4Wx+5AMvNSVqA{aE2!X8V zh{hDe1|#V2?`u3>Tf=^D+)Du4|FqDWyW|gxPE@yV)6^JgJig-vIo=<#NgIzAO(@E7 zuoQZFf{4V#{u3t}y@g}OBB>fsH3JkVD9I$^@i=tD0LOB0Ivo%N0RUhT0*;{&2n5i0 zqTv%k6fYme7kWBlq4SLu!Si*jX=;==GslYb2R77I@|y)FMg!KM+cp?HQ!64%Ci~U4V6uvJur_+gSzYiS8!2kt|P#8Wu_cm9G%d=+f)4a#y+55!mM-N^q zBLHx@vnfMYz%VR|#!bZd8*Z?ry4da+Ww$w4_M*YY6_1Ce6U5>&THD${Q51Yx8A$iI z!E-D$-9TUe0D|4UpePD?dAV@dL@+c#Lwy}+ng%Ee`}Q3Or?_0%>z;ffNexxUYu7z{ zx8I+&`G*r*&%<@Y{0MdTAdyJGvP39J6?PjB8WvcV z#+fsx$FeN@`H%pjD8AX=)?Tn_%iGH;%6|#FD-B9ghh>^@IUTUuY&dzc2?xJAShwSE zA1tset3SoJJ*6h;M9kbWDEKH{zPux2;%ek z-u>=e>&(J2#c((r002TP5X-_RpY6q-&pv&jwx;U!QTYXthWc+T_DVS|3SwSPZtkz# z?lkDS3Cpq|NdhQPNU8={PC!aZiho@3c=hO!Llyx1?#cDJ94|oA4cKiWEQ>%VU z-wmK@NB~7vN{Wic+6%`NAr_ZmnkFa!vZ5k0BNeHp1x4VoV)-)Rz<~pQ?(XhEdb$_$ z=9R;p>VYH)5G4Uh?*IV6G)*KF6{VA>AQFvc?A`NO*)Q&#Q#~XAFYy0tX*q|q6x*ec zk&_w*A_;^CV#x5iK?Y)=s1z(&vKSo8KsQXp6AA>LgWF|CcW)Sk5O~}U*d+eaoc6Xh z)O~aOkk6k@519i1@ZiIb>~lEmw`-aPilXrA`HD%uF9N%>YBwkVGCd zO`)eR4BapR0#Fpd^BhEh15FA4O->D7Zw4e$lsKLXSf-_?rlpat&Q9x!SMa@RYpMtU z^MU0L-CZ)_dN}MN>^2dRfiM(JgWvB*?}aFmst$)uLTZW~EiEm`$Vi97<3c=<#DtOw zICiXNP9z$6srl>~^9OBsHKJ+iOjXs9y!jR7sH?BT$2)f`vB6kRS=nv5x0lU;uA8vi z1ibRh!P=Jt#$LY(~@zuzamR4R8+7SWVNPg zE{^BSBZm&I7Dcfk80^vjVAyrTY11$e3I(kpf5$&oQ>RVmP6qwG9lzTmS$707*qoM6N<$g47-1Jpcdz literal 0 HcmV?d00001 diff --git a/trunk/Pithos.Client.WPF/Images/Bandwidth.png b/trunk/Pithos.Client.WPF/Images/Bandwidth.png new file mode 100644 index 0000000000000000000000000000000000000000..185a21342a607dac760a57e5f1ae4f8816a99b62 GIT binary patch literal 1950 zcmV;P2VwY$P)lu6ZvKv@F#_N+RdESTaRU$_wqV+EfYq+$_g<#kW5jS0tbDQcS+A}=U0v?S z`AdOQ1v$#R`nrj+Z1cAq@*Z$&zOM*~A>aDVaEp1XaO%dzo&0|>u=>}n-(<#y+9}2G zdo{Fo8?!pv+c&LwA@;TP!Ek&{IM~?;;DA#cGZ2z}P>lDXio~ypCBkfg2{^Xj z(C_b3BZpp+oE5;j9j)b|h`DdZloD@#t{aw3AY$kq4R=p2QkqT#e)q%8O|yRU)ZA;g z#}XxWZBrB}u?YYa6+{BT9@31ElHG*scU!sZ*}N9T{KD)YmZ459>BTM|YT>X;Q-W20)wzz{;&3tkzvh-Q814l7=D&lM&o571O7b zqA48zX{fL5T>$?~?@|sA005XA06ezszw<3i*3X_%0gp>Vf80j48 zP*$3Qi4#VRZfooM?b40UKeXqWCrCJiP zA~baX1T#1(iR>Q?oRzX0A5J|03^$F7BB;>D4?V~#Nsvy$UfV0p}n@{ zLVMZ|iXw2|y%Q5Z;dDI#5#!yXmj-Jq?VGJ<8gJBX-YdN20t|*Ef=C831{eT~p$xqI z%sne+e&Nx_|9xba4}hLqRONke)ti@z1(-O!z5s(5AZho%^7A><0Ym^u0P#t)rW!k+ z`hZvN(m~9yNe*zGk|3D{jwbBwylhpBn;mkw{ozp)W_v&cW`b#D0svHIfS3XF7FSHZ zWrVxfmsh}^+#siNol^i(wpSD=%#bo+LMRRZu3R|GDYC!4=1s{=ki;-eJDsQVcG84JRqF7^ab961Ow$GvVA}(QLlppvfrK7W zt>J5HO5NjU`aPPW!tK&v%LG9r?EwIa0yXJ@f->P7KWRkn@?TZ6zff@f(zb}^STTq| z1lSgkIyP7VSRDY6H!?h}XhQ5nFly`R-6%Swv>}N=a)1FFi~ zUdaFbPykE-6PObWq^q$Cu$$8^Qr%XmPtVbpJ+Ks|-fAQo5TGM?30?iIkVys<7RV7L z*tmEzMADEUs~bnozk|0M{#B+8U7rEsL_W)b@+wkAB&kWbJ-@N5sAKnmlLx>5rF%XP zX%I}aA2BO}xE;@|o#+lmP@3`Y(}ZJ3f>R z`Q=K~*#k68tDY<{mZ7Hlg!k-z?dg4uP4!E@x&S_3E(~K(*9D(17k+;p{(SH-&NTME zeyQ2sl~XK&eK(}7IWE9-$8(isqNeYDyn~lMSGBdX`_}xX)8`h`f`z7Qle+ z7VvvrgPW1K4KPDdU2IwXL&#B8)lFu_1Vaj{A#6 zG}JXXO&l*K-&?Ww?_hPo&?I1av-88hH8<2RiAH)NP6{pg#b|GPSK#Qv`)g}kKE8_P zeb;whJQUyPFBUzK9r z|LC*d^}a1sRC)`9o^5W{t6AmfnZk-2!ie??PU$WLTrQn&1+LMZE}i4%=&qj2mL>!w k*|0*L(s3d2X1R9M5sS7~rmRT@3_ZQZYzbh?wy+MNXwAOrz%7!-$L6PQs6 z=zvl>BM2yp3yVMrg$#(+prQy^OsT~-!my|#f-(akk=?L}pb%nMvWFzy=_I|qe(Rkd zorx4Bg8rFTb^qLY-*-=)`<-*Yk5EeS|NOXL6SVIA^%>30&BqPh$nM+KL3)cnoc!cr-zSxO&7hgbp5NZzroxp-;L|041BnL zGuz(YK0g=?{dM{4ZC^NK&*YJEuEBVFe(7C%YR!F}C7jxfwuo_1blO zG%CFki9{wQCMK?$H}}O4Zgvj&sTz3a-S;ws!QfVp$20U#4;A6W$TJ^e9F z*Twd>_I*#yc$OiAfKq^A2zG4SietwP&$##A-<9}$tsA@L<_sA&bO`>vZ$BEZHI>+` z)+ZOtn_YKX0G2IZu{bw3cX?4!5jc(o!w_7#d>OlT??JN5g#mXBKz@$`D5?$$K;RfO zHq_$i(W7W=yrzvDF`OH8_aIOTD5{3tyZ7MqsT0e5zLsU%wthr!S%e(V9cgX#!!UG& zA}UyhL2hn0ESNV348uT{HAG`748s5bXc|R!b`E;>$cLsX90-d@RDq@$5I7*%(T z#ov0pUIO6O00f>t?DzXCeJ#yB94Rj)z!XBl@(>lNy)b-!}%}GqRW>5t@!&3tFqVNgD;wRq=iSFJ z%(T4xd}jIUDY~joE4siew3pZAVL&N`tZIl#GIYbhwWel7B2kE>=rXj z0t>^?0RVQ31$L_m&cp;%Ro9{;7=+*x;7(406q8ZVyAb{Q^#uUv1_dD;_U`>+(u`-H zKf*0u@+zw+$^*T6<|7oAAgemAm!_g92nIti2?DabnMkmi(dzeM-@am0*VHNikmdCV zW5$d^N=hoSvplG(sYP2`8xkE37zTx+hT~U42n3!*L9d=DEiD;;u=K!e?zLB!=<^mV zI#W_|U}({U_e0=$grf>{BMu@G3Bzm>;B-16ns~JOTJYieO;YKB{Y$_5?(8Q3k^A=R ze}7$l!^&w>Cnq?ZZX_oqAs7rI5(&d@PXMI=%MjQ^9-tb&{Hhc!%}o~rZLJIk00{~9 z`^(Bsyj@pU|I8y39)`o|MnqELs6k;7&9I0fIF`Zw;u4gW>|c8J?3oRY#Ke#&S~QMh zH#XGQMgOy}c+2CDKMt$a0!>wbPQM2Lvx$e_--4YxKc&ZyAKg@1QoJN9J4fRHV9DZz z(aBS$KL5?>(AL-J9!8HE z1<_)I6qAva=>|Y>rKSzYu7}tUb&nUXJF3!ZDYqiFzK!Vcfv3z zDB{m(FeE|O4Wy+w;c_NGipgla=7%VnkYKmMB=DVHp`s%cMNC$ZnVt-jz@ypMhSoq3 zEX%-dGeh7x5JJE(1n16uhc#=~?mc(*%mfYq%%XYcvEyG)3U+kBpcJa2AU{73nci#! z+QVq_wLuVg*sLP5y=m|VI?&Y82HN?uG7N#;YC*O;6)el3y(0{NpaTp;;B;6~Usr>g zn%XWV&X-@r4;2@8MIw=S4a}K4kJQ)KPphh`$^*c197pfIXYj1qvtASw4Nz4bgaE1T zI1_}#g{A8{00Nd}x?Vq@za9QSN2i2&K$o#<_1f5}Qztg+nl1yNu~@A3Qf0;F^o-14 zS4T8#_()P+RmE$%##$^E(yO3w%akXlKGdtAPgmms0D{27>9E0S5h3s#C@54_LpUO# ztvw7?`%#@d$D*{P7+bddW8LwihnLyx_6WM zYNXq0NL)!t!(FZJ&HGd$11nP7!zjyEGxOhH>m z7=}TSlbeh5^z=dL>6y6z%5MvRuIc@gTu!999Z)qLW|M%Er%qwd7kkmGXHSeAF$|*F zf=EOLAwZ(tf{KcAl$D)?-|xp?{`?rcSy_n16!1KUZn?S4*T;{J_|3rIR-8U{(zqo6 ztJU(s`3o2RxMAbwp%W)Oj88uO6o(ET`r+8IBa6Cs&l@4jvF9FnbP^&_IZnBuW6Rd< z(!tULFR?5eYw`J3j2~B&a?jm^ux!dLee%XX zG~wV=PtR0_{C@cRJkRGiT`tk<%_29R^Rr{qu;C-ww6t`qD2lekM5ie`Czqj=V(Ro6 z|2lA>l!ihf8V-l)y1#!w`}XVqvLi83q?F>0zWqo+??NFhE!{1OqCFwOVM=_?o0EB2HM(p5JFM_5JgcMKmY8L5iVEKmD<{xE*++(rV&lo(CYWoUp<`OY>m8c uG;cDQ91O#_1wly4$jCH#JYMok^ZXYefTwJ@pv(jS00003(@C?;41Z7cN651i^iHJXS%w3V@$$#l}0 zd(Y=y%ZGE%xt~b`R(s&WIs5Lt)_<-4f335Qm>F;774jBe4S=&xT>e>6mY@7TfJ#;U z55D^4&wm|2%#8CtdAgP5dHRJ%KFxnk$Qu|a%7P0QpWc1$nV;|5-rmkb0C5tE2xjo) z>UFMeWW3qZ5P^3s$2{`DKFo-ox_G{G|B(;+3IIaw@$c7D9{uP&Ak#)Vfg_UH!Opz5 z;k^Lop8pqKt@ahYwsk|odgt(vV!+izr?T00%7IpZ+R%|v*)wLX4ej3Ba$t&xG^?sw z0WdSFax~2Atl$UgflQ51UH?XWEnQ7yrKrnVZcj?$4~IE?TtAx455i*!qMn6gJ&Nb=KYwj2EdR4Fz+cn z)C5Z9v#mHq;<1Y6?cHfblA5GEhQ4GrSFrFGj-4uMgSF za|kiaWX!S7aBc>9S=qKb5uutu73WJ`&Q>=nwR;n;T(U8Yh!%y{S?H&#y7erdoYMYR|@A#~#%5F5T-DiGBk%ut=t z2L>Df@ZLjr@tfz@2m^ zy&rb=Pki|8=;$zDlQV|h(d_ZkM#f)W$-#_|9bTXnJDkWE1zxoV;7hNHh_P>Z{!JM` zw)z1%4m0KMP zKAlcSfSvcfb9wvT1ABZgHD2pE(jsW)F+ni1O4#Zxiei85+EtZVA0{VGoRG3Co9Bog zcf}h#c=wfyOP%uL7?c*wM{(?|Oh%9T?Ie6^b>rQSZl%j)vKJ9)euFWLBuO}P=8QFC z`O%|CFGNxF{@Z;eIWfNYo@Wm~@VT!*^bklDT@bbgBWH>4|C--k__3b*+rw9!t3(%u zVJirNNnP2_&d!>uel|RL@}zXT-4CstS~;Yqw-%33GTOm_!| zX@@j3Ha0eypPwTLg4qfV0?f>-7sub27ne&fU+!Z0jr-e)DW-|zpq-EMm^GmacN60NPRbyPLF6##(meQE!b?|57M z@NKHx|MlhkS1V6ke;nuox8l@9q&Rr+VA51Ux7&4QHnS?`TCjgnC`upxb3N^po;jcm y#6U1`Q~()}bUUu^T#)A)+N>-L<_}AfME?VCG#udxGv}HB0000Co!leP;S@pf++X46{cOfUHXEfAlMa!PlQ}~MBjL|g8EEy3gB}%frk+UiW zU!s)i3d4{p00>uv;4nC?Mi87f@@A0#t_crJ8Xr-mp=x2NV13nB#hzYE|CxivXsYWj>iv*=?U zEN7lA=46bnv5_G?BBex$`X8zm(fKpVhC87WsCKgI6Y!woM5oWPA+fzzshJO9`@HFU zl%W|O`#x2n`M?SDU*YkEJTN!NBlR>3MmzDq1#QGnZXqtI?da8MF3GV6kvK9Qm_IPK z?OOaox7axAQ%(OwAN$1ip6$Q&iMwmAzn<#?rO-Z3hguzt`0l-+tk~-=h^)pHYt>^Q zal&QC?(ah5O*XmScY5TCO|E$RBeeUW4SXwJvAGHDH+|rOTtKc3A9s!92O8!A$JYKv zh+EB=#I57*Ph<7?x(W$56b$}yS+ZmS+P*nGA0md=cP3{&79b(gj<~YZicB3T405&I z1ve_#4O+^0{@KwPXZBxX)=vt@X~Gwg3Et%AzTiSN5;;9>*wq}y{M-4pQXNp~6G}Z` ztNb!FVn+9yy9KUzBmMK@?F4Tot|FG6Pr%arfQ~gvedQW+-hgbWR84$<*%Rjjv03zM G?%`hu7A1oK literal 0 HcmV?d00001 diff --git a/trunk/Pithos.Client.WPF/Images/TraySynching.ico b/trunk/Pithos.Client.WPF/Images/TraySynching.ico new file mode 100644 index 0000000000000000000000000000000000000000..d246fbd9ae3bed556e7f722698038070f4c4a596 GIT binary patch literal 1078 zcmb_byG{a85IxHhmtqt71GX~!1r$UnjNd?Eh=mD_$y%6j3xl^X;g@cr<$eTomUL`k zyq=l6uVA!tU>@hpnccm^0z~LxI2;1#V;lh&tguV>M3!^|=Nu(ozwllvIzK{5ST4x`gVpiAaKLJ_Qes`^c|ju2w@2yQ(w0S0V6ZJ; znH{Xvlrqw&NQLE*1WHj`#RETRA>Q~1W<)JBk}AjKxC2LQSeNYYSj*!|{YjTvIN4K1 zpVI3+alMWG+n)L}xkYPBSzLS8vpc_8@TfG^TykHxtr}N8&mTH?ZmoY-d05tb+h8RU z>+MtMhbunXm(Do%Je#IfKkzjo>Byw-RaX*;v;)H;dw9`^@p_!s@*CSqQcnN? literal 0 HcmV?d00001 diff --git a/trunk/Pithos.Client.WPF/MainWindow.xaml b/trunk/Pithos.Client.WPF/MainWindow.xaml new file mode 100644 index 0000000..04fd36a --- /dev/null +++ b/trunk/Pithos.Client.WPF/MainWindow.xaml @@ -0,0 +1,8 @@ + + + + + diff --git a/trunk/Pithos.Client.WPF/MainWindow.xaml.cs b/trunk/Pithos.Client.WPF/MainWindow.xaml.cs new file mode 100644 index 0000000..0eab58c --- /dev/null +++ b/trunk/Pithos.Client.WPF/MainWindow.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Pithos.Client.WPF +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj b/trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj new file mode 100644 index 0000000..e7b4db9 --- /dev/null +++ b/trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj @@ -0,0 +1,183 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {4D9406A3-50ED-4672-BB97-A0B3EA4946FE} + WinExe + Properties + Pithos.Client.WPF + Pithos.Client.WPF + v4.0 + + + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + False + ..\packages\System.Data.SQLite.1.0.66.1\lib\System.Data.SQLite.DLL + + + + + + ..\packages\Caliburn.Micro.1.2.0\lib\Net40\System.Windows.Interactivity.dll + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + + + + PreferencesView.xaml + + + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + MainWindow.xaml + Code + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + + + + {B633FE8C-B40E-4122-A763-F94C8B1A70F8} + Caliburn.Micro.WPF + + + {7AC63864-7638-41C4-969C-D3197EF2BED9} + NotifyIconWpf + + + {142AF135-DF30-4563-B0AC-B604235AE874} + Pithos.Core + + + {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4} + Pithos.Interfaces + + + {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD} + Pithos.Network + + + {240B432F-1030-4623-BCC3-FF351D6C1B63} + Pithos.ShellExtensions + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/Pithos.Client.WPF/PithosCommand.cs b/trunk/Pithos.Client.WPF/PithosCommand.cs new file mode 100644 index 0000000..22591d0 --- /dev/null +++ b/trunk/Pithos.Client.WPF/PithosCommand.cs @@ -0,0 +1,45 @@ +// ----------------------------------------------------------------------- +// +// TODO: Update copyright text. +// +// ----------------------------------------------------------------------- + +using System.Windows.Input; + +namespace Pithos.Client.WPF +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// + /// TODO: Update summary. + /// + public class PithosCommand:ICommand + { + private Action _action; + private Func _condition; + + public PithosCommand(Action execute,Func canExecute=null ) + { + _action = execute; + _condition = canExecute; + + } + + public void Execute(object parameter) + { + _action(); + } + + public bool CanExecute(object parameter) + { + if (_condition == null) + return true; + return _condition(); + } + + public event EventHandler CanExecuteChanged; + } +} diff --git a/trunk/Pithos.Client.WPF/PithosStyles.xaml b/trunk/Pithos.Client.WPF/PithosStyles.xaml new file mode 100644 index 0000000..95f67ae --- /dev/null +++ b/trunk/Pithos.Client.WPF/PithosStyles.xaml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/trunk/Pithos.Client.WPF/PreferencesView.xaml b/trunk/Pithos.Client.WPF/PreferencesView.xaml new file mode 100644 index 0000000..de29ef9 --- /dev/null +++ b/trunk/Pithos.Client.WPF/PreferencesView.xaml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +