From 7bc297abc403f08746d769208113e16ca5780693 Mon Sep 17 00:00:00 2001 From: Aigio Liu Date: Sun, 28 Feb 2021 15:47:56 +0800 Subject: [PATCH] JumpList --- .../App.axaml.cs | 71 ++++- .../FluentWindow.cs | 10 + .../Program.cs | 6 + .../Startup.cs | 124 ++++++++ ...amTools.Client.Desktop.Avalonia.App.csproj | 4 + .../Views/MainWindow.axaml.cs | 9 + .../Services/IMessageBoxCompatService.cs | 21 ++ .../{NotifyIconHelper.cs => INotifyIcon.cs} | 0 .../Windows/MessageBox.cs | 119 -------- ...BoxButton.cs => MessageBoxButtonCompat.cs} | 4 +- .../Windows/MessageBoxCompat.cs | 137 +++++++++ ...geBoxImage.cs => MessageBoxImageCompat.cs} | 2 +- ...BoxResult.cs => MessageBoxResultCompat.cs} | 4 +- .../{ResizeMode.cs => ResizeModeCompat.cs} | 2 +- .../Windows/WpfCompatExtensions.cs | 10 +- .../Application/UI/NotifyIcon.cs | 63 ++-- .../Application/UI/WpfApp.xaml | 25 ++ .../Application/UI/WpfApp.xaml.cs | 20 ++ .../{ => Internals}/MouseHook.cs | 1 + .../{ => Internals}/NativeMethods.cs | 1 + .../{ => Internals}/NativeWindow.cs | 1 + .../{ => Internals}/PointInt32.cs | 1 + .../{ => Internals}/RECT.cs | 1 + .../{ => Internals}/UnmanagedMethods.cs | 1 + .../{ => Internals}/User32Window.cs | 1 + .../{ => Internals}/WinHttp.cs | 1 + .../{ => Internals}/WinInet.cs | 1 + ...n.SteamTools.Client.Desktop.Windows.csproj | 3 +- .../Windows/Point.Generated.cs | 282 ------------------ .../Windows/Point.cs | 44 --- .../UI/Views/INotifyIconWindow.cs | 12 + 31 files changed, 495 insertions(+), 486 deletions(-) create mode 100644 System.Application.SteamTools.Client.Desktop.Avalonia/Application/Services/IMessageBoxCompatService.cs rename System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/{NotifyIconHelper.cs => INotifyIcon.cs} (100%) delete mode 100644 System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs rename System.Application.SteamTools.Client.Desktop.Avalonia/Windows/{MessageBoxButton.cs => MessageBoxButtonCompat.cs} (80%) create mode 100644 System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxCompat.cs rename System.Application.SteamTools.Client.Desktop.Avalonia/Windows/{MessageBoxImage.cs => MessageBoxImageCompat.cs} (97%) rename System.Application.SteamTools.Client.Desktop.Avalonia/Windows/{MessageBoxResult.cs => MessageBoxResultCompat.cs} (78%) rename System.Application.SteamTools.Client.Desktop.Avalonia/Windows/{ResizeMode.cs => ResizeModeCompat.cs} (97%) create mode 100644 System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml create mode 100644 System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml.cs rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/MouseHook.cs (99%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/NativeMethods.cs (87%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/NativeWindow.cs (98%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/PointInt32.cs (88%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/RECT.cs (85%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/UnmanagedMethods.cs (99%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/User32Window.cs (99%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/WinHttp.cs (94%) rename System.Application.SteamTools.Client.Desktop.Windows/{ => Internals}/WinInet.cs (99%) delete mode 100644 System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.Generated.cs delete mode 100644 System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.cs create mode 100644 System.Application.SteamTools.Client.Desktop/UI/Views/INotifyIconWindow.cs diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs index be3212805..4d9cde735 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs @@ -1,4 +1,5 @@ -using Avalonia.Controls; +#pragma warning disable CA1416 // 验证平台兼容性 +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using ReactiveUI; @@ -10,6 +11,13 @@ using System.IO; using System.Properties; using System.Windows; using AvaloniaApplication = Avalonia.Application; +using ShutdownMode = Avalonia.Controls.ShutdownMode; +using Window = Avalonia.Controls.Window; +using WindowState = Avalonia.Controls.WindowState; +#if WINDOWS +using System.Windows.Shell; +using WpfApplication = System.Windows.Application; +#endif namespace System.Application.UI { @@ -37,6 +45,13 @@ namespace System.Application.UI public ContextMenu? NotifyIconContextMenu { get; private set; } + static void IsNotOfficialChannelPackageWarning() + { + var text = "The program currently running is not from the official channel."; + var title = "Warning"; + MessageBoxCompat.Show(text, title, MessageBoxButtonCompat.OK, MessageBoxImageCompat.Warning); + } + public override void OnFrameworkInitializationCompleted() { // 在UI预览中,ApplicationLifetime 为 null @@ -47,9 +62,7 @@ namespace System.Application.UI { if (!AppHelper.IsOfficialChannelPackage) { - MessageBox.Show("The program currently running is not from the official channel.", "Warning", - MessageBoxButton.OK, - MessageBoxImage.Warning); + IsNotOfficialChannelPackageWarning(); } #region NotifyIcon var notifyIcon = INotifyIcon.Instance; @@ -95,9 +108,25 @@ namespace System.Application.UI }); #endregion +#if WINDOWS + AddJumpTask(); +#endif + desktop.MainWindow = MainWindow; desktop.Exit += Desktop_Exit; desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown; + +#if DEBUG + AreYouOk(); + static async void AreYouOk() + { + await MessageBoxCompat.ShowAsync( + "Are You Ok?", + "title", + MessageBoxButtonCompat.OK, + MessageBoxImageCompat.Information); + } +#endif } @@ -157,6 +186,37 @@ namespace System.Application.UI { desktop.Shutdown(0); } +#if WINDOWS + WpfApplication.Current.Shutdown(); +#endif + } + +#if WINDOWS + + // JumpList + // 表示作为菜单显示在 Windows 7 任务栏按钮上的项和任务的列表。 + // https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.shell.jumplist?view=net-5.0 + + // Taskbar Extensions + // https://docs.microsoft.com/zh-cn/windows/win32/shell/taskbar-extensions?redirectedfrom=MSDN + + static void AddJumpTask() + { + // Configure a new JumpTask. + var jumpTask1 = new JumpTask + { + // Get the path to Calculator and set the JumpTask properties. + ApplicationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), + IconResourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), + Title = "Calculator", + Description = "Open Calculator.", + CustomCategory = "User Added Tasks" + }; + // Get the JumpList from the application and update it. + JumpList jumpList1 = JumpList.GetJumpList(WpfApplication.Current); + jumpList1.JumpItems.Add(jumpTask1); + JumpList.AddToRecentCategory(jumpTask1); + jumpList1.Apply(); } /// /// Exits the app by calling Shutdown() on the IClassicDesktopStyleApplicationLifetime. @@ -177,4 +237,5 @@ namespace System.Application.UI } #endregion } -} \ No newline at end of file +} +#pragma warning restore CA1416 // 验证平台兼容性 \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/FluentWindow.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/FluentWindow.cs index 599bdb2d2..6cbd7055f 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/FluentWindow.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/FluentWindow.cs @@ -11,6 +11,16 @@ namespace Avalonia.Controls Type IStyleable.StyleKey => typeof(Window); public FluentWindow() + { + Constructor(); + } + + public FluentWindow(IWindowImpl impl) : base(impl) + { + Constructor(); + } + + void Constructor() { ExtendClientAreaToDecorationsHint = true; ExtendClientAreaTitleBarHeightHint = -1; diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs index df9f44082..7541b4c7e 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs @@ -1,6 +1,7 @@ using Avalonia; using Avalonia.ReactiveUI; using NLog; +using System.Threading.Tasks; namespace System.Application.UI { @@ -18,6 +19,11 @@ namespace System.Application.UI var logger = LogManager.GetCurrentClassLogger(); try { +#if WINDOWS + var app = new WpfApp(); + app.InitializeComponent(); + Task.Factory.StartNew(app.Run); +#endif BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } catch (Exception ex) diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Startup.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Startup.cs index 747102d34..a40a6a604 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Startup.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Startup.cs @@ -1,7 +1,12 @@ using Avalonia.Controls; using Microsoft.Extensions.DependencyInjection; using System.Application.Models; +using System.Application.Services; using System.Application.Services.Implementation; +using System.Application.UI.Views; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using System.Windows; namespace System.Application.UI { @@ -70,9 +75,128 @@ namespace System.Application.UI services.AddAppUpdateService(); // 托盘图标 +#if WINDOWS + services.AddTransient, Win32NotifyIconWindow>(); +#endif services.AddNotifyIcon(); + + #region MessageBox + + /* System.Windows.MessageBox 在 WPF 库中,仅支持 Win 平台 + * 改为 System.Windows.MessageBoxCompat 可跨平台兼容 + * 在其他平台上使用 MessageBox.Avalonia 库实现 + * API变更说明: + * - 如果需要获取返回值,即点击那个按钮,则使用异步版本 ShowAsync + * - 如果不需要获取返回值,则可直接使用 同步版本 Show + * 注意事项: + * - 图标(Icon)与按钮(Button)不要使用标记为 Obsolete 的 + * - WPF 中 显示窗口(Show)会锁死父窗口等,类似 ShowDialog + * - MessageBox.Avalonia 中则不会锁死窗口 + * 已知问题: + * - 在 MessageBox.Avalonia 中 + * - 如果内容文本(messageBoxText)过短 UI 上的文字显示不全 + * - 点击窗口按 Ctrl+C 无法复制弹窗中的文本内容 + * - 按钮文本(ButtonText)缺少本地化翻译(Translate) + * - 某些图标图片与枚举值不太匹配,例如 Information + */ + +#if WINDOWS + // 可选项,在 Win 平台使用 WPF 实现的 MessageBox + //services.AddSingleton(); +#endif + + #endregion } sealed class NotifyIconImpl : NotifyIcon, INotifyIcon { } + +#if WINDOWS + sealed class Win32NotifyIconWindow : MainWindow, INotifyIconWindow + { + sealed class Win32WindowImpl : Avalonia.Win32.WindowImpl + { + public Win32NotifyIconWindow? Window { get; set; } + + protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + { + var _notifyIcon = Window?.NotifyIcon; + var value = _notifyIcon == null ? null : NotifyIcon.WndProc(_notifyIcon, msg, wParam, lParam); + return value ?? base.WndProc(hWnd, msg, wParam, lParam); + } + } + + public Win32NotifyIconWindow() : base(new Win32WindowImpl()) + { + if (PlatformImpl is Win32WindowImpl impl) + { + impl.Window = this; + } + else + { + throw new PlatformNotSupportedException(); + } + } + + public IntPtr Handle => PlatformImpl.Handle.Handle; + + [NotNull, DisallowNull] // C# 8 not null + public NotifyIcon? NotifyIcon { get; private set; } + + public void Initialize(INotifyIcon notifyIcon) + { + if (notifyIcon is NotifyIcon _notifyIcon) + { + NotifyIcon = _notifyIcon; + } + else + { + throw new PlatformNotSupportedException(); + } + //Content = NotifyIcon; + } + } + + sealed class WPFMessageBoxCompatService : IMessageBoxCompatService + { + static MessageBoxButton GetButtonEnum(MessageBoxButtonCompat button) => button switch + { + MessageBoxButtonCompat.OK => MessageBoxButton.OK, + MessageBoxButtonCompat.OKCancel => MessageBoxButton.OKCancel, + MessageBoxButtonCompat.YesNo => MessageBoxButton.YesNo, + MessageBoxButtonCompat.YesNoCancel => MessageBoxButton.YesNoCancel, + _ => throw new ArgumentOutOfRangeException(nameof(button), $"value: {button}"), + }; + + static MessageBoxImage GetIcon(MessageBoxImageCompat icon) => icon switch + { + MessageBoxImageCompat.Asterisk => MessageBoxImage.Asterisk, + MessageBoxImageCompat.Error => MessageBoxImage.Error, + MessageBoxImageCompat.Exclamation => MessageBoxImage.Exclamation, + MessageBoxImageCompat.None => MessageBoxImage.None, +#pragma warning disable CS0618 // 类型或成员已过时 + MessageBoxImageCompat.Question => MessageBoxImage.Question, +#pragma warning restore CS0618 // 类型或成员已过时 + _ => throw new ArgumentOutOfRangeException(nameof(icon), $"value: {icon}"), + }; + + static MessageBoxResultCompat GetResult(MessageBoxResult result) => result switch + { + MessageBoxResult.OK => MessageBoxResultCompat.OK, + MessageBoxResult.Yes => MessageBoxResultCompat.Yes, + MessageBoxResult.No => MessageBoxResultCompat.No, + MessageBoxResult.Cancel => MessageBoxResultCompat.Cancel, + MessageBoxResult.None => MessageBoxResultCompat.None, + _ => throw new ArgumentOutOfRangeException(nameof(result), $"value: {result}"), + }; + + public Task ShowAsync(string messageBoxText, string caption, MessageBoxButtonCompat button, MessageBoxImageCompat icon) + { + var button_ = GetButtonEnum(button); + var icon_ = GetIcon(icon); + var result = MessageBox.Show(messageBoxText, caption, button_, icon_); + return Task.FromResult(GetResult(result)); + } + } +#endif } } \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj b/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj index 7f8118ca3..cb2881a41 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj @@ -11,6 +11,10 @@ Properties\app.manifest + + net5.0-windows + + Properties\AssemblyInfo.cs diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs index 7db73ef44..8f2099045 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs @@ -3,6 +3,7 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; using System.Application.UI.ViewModels; using System.ComponentModel; +using Avalonia.Platform; namespace System.Application.UI.Views { @@ -16,6 +17,14 @@ namespace System.Application.UI.Views #endif } + public MainWindow(IWindowImpl impl) : base(impl) + { + InitializeComponent(); +#if DEBUG + this.AttachDevTools(); +#endif + } + protected override void OnClosing(CancelEventArgs e) { e.Cancel = true; diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/Services/IMessageBoxCompatService.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/Services/IMessageBoxCompatService.cs new file mode 100644 index 000000000..7c1e99072 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/Services/IMessageBoxCompatService.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using System.Windows; + +namespace System.Application.Services +{ + /// + /// System.Windows.MessageBoxCompat.ShowAsync + /// + public interface IMessageBoxCompatService + { + /// + /// 显示一个消息框,该消息框包含消息、标题栏标题、按钮和图标,并且返回结果。 + /// + /// 一个 ,用于指定要显示的文本。 + /// 一个 ,用于指定要显示的标题栏标题。 + /// 一个 值,用于指定要显示哪个按钮或哪些按钮。 + /// 一个 值,用于指定要显示的图标。 + /// 一个 值,用于指定用户单击了哪个消息框按钮。 + Task ShowAsync(string messageBoxText, string caption, MessageBoxButtonCompat button, MessageBoxImageCompat icon); + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/NotifyIconHelper.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/INotifyIcon.cs similarity index 100% rename from System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/NotifyIconHelper.cs rename to System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/INotifyIcon.cs diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs deleted file mode 100644 index 3ed732fe4..000000000 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs +++ /dev/null @@ -1,119 +0,0 @@ -extern alias MessageBox_Avalonia; - -using Avalonia.Controls; -using MessageBox_Avalonia::MessageBox.Avalonia; -using MessageBox_Avalonia::MessageBox.Avalonia.BaseWindows.Base; -using MessageBox_Avalonia::MessageBox.Avalonia.DTO; -using MessageBox_Avalonia::MessageBox.Avalonia.Enums; -using System.Reflection; -using System.Threading.Tasks; - -namespace System.Windows -{ - /// - /// 显示消息框。 - /// - public static class MessageBox - { - static ButtonEnum GetButtonEnum(this MessageBoxButton button) => button switch - { - MessageBoxButton.OK => ButtonEnum.Ok, - MessageBoxButton.OKCancel => ButtonEnum.OkCancel, - MessageBoxButton.YesNo => ButtonEnum.YesNo, - MessageBoxButton.YesNoCancel => ButtonEnum.YesNoCancel, -#pragma warning disable CS0618 // 类型或成员已过时 - MessageBoxButton.OkAbort => ButtonEnum.OkAbort, - MessageBoxButton.YesNoAbort => ButtonEnum.YesNoAbort, -#pragma warning restore CS0618 // 类型或成员已过时 - _ => throw new ArgumentOutOfRangeException(nameof(button), $"value: {button}"), - }; - - static Icon GetIcon(this MessageBoxImage icon) => icon switch - { - MessageBoxImage.Asterisk => Icon.Info, - MessageBoxImage.Error => Icon.Error, - MessageBoxImage.Exclamation => Icon.Warning, - MessageBoxImage.None => Icon.None, -#pragma warning disable CS0618 // 类型或成员已过时 - MessageBoxImage.Question => Icon.Info, - MessageBoxImage.Battery => Icon.Battery, - MessageBoxImage.Database => Icon.Database, - MessageBoxImage.Folder => Icon.Folder, - MessageBoxImage.Forbidden => Icon.Forbidden, - MessageBoxImage.Plus => Icon.Plus, - MessageBoxImage.Setting => Icon.Setting, - MessageBoxImage.SpeakerLess => Icon.SpeakerLess, - MessageBoxImage.SpeakerMore => Icon.SpeakerMore, - MessageBoxImage.Stop2 => Icon.Stop, - MessageBoxImage.Stopwatch => Icon.Stopwatch, - MessageBoxImage.Wifi => Icon.Wifi, -#pragma warning restore CS0618 // 类型或成员已过时 - _ => throw new ArgumentOutOfRangeException(nameof(icon), $"value: {icon}"), - }; - - static MessageBoxResult GetResult(this ButtonResult result) => result switch - { - ButtonResult.Ok => MessageBoxResult.OK, - ButtonResult.Yes => MessageBoxResult.Yes, - ButtonResult.No => MessageBoxResult.No, -#pragma warning disable CS0618 // 类型或成员已过时 - ButtonResult.Abort => MessageBoxResult.Abort, -#pragma warning restore CS0618 // 类型或成员已过时 - ButtonResult.Cancel => MessageBoxResult.Cancel, - ButtonResult.None => MessageBoxResult.None, - _ => throw new ArgumentOutOfRangeException(nameof(result), $"value: {result}"), - }; - - /// - /// 显示一个消息框,该消息框包含消息、标题栏标题、按钮和图标,并且返回结果。 - /// - /// 一个 ,用于指定要显示的文本。 - /// 一个 ,用于指定要显示的标题栏标题。 - /// 一个 值,用于指定要显示哪个按钮或哪些按钮。 - /// 一个 值,用于指定要显示的图标。 - /// 一个 值,用于指定用户单击了哪个消息框按钮。 - public static async Task ShowAsync( - string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon) - { - var parms = new MessageBoxStandardParams - { - ButtonDefinitions = button.GetButtonEnum(), - ContentTitle = caption, - ContentMessage = messageBoxText, - Icon = icon.GetIcon(), - Style = Style.None, - WindowStartupLocation = WindowStartupLocation.CenterScreen, - }; - var msBoxStandardWindow = MessageBoxManager.GetMessageBoxStandardWindow(parms); - var window = GetWindow(msBoxStandardWindow); - if (window != null) - { - window.Topmost = true; - window.SetResizeMode(ResizeMode.NoResize); - window.SetDefaultFontFamily(); - } - var result = await msBoxStandardWindow.Show(); - return GetResult(result); - } - - /// - public static async void Show( - string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon) - { - await ShowAsync(messageBoxText, caption, button, icon); - } - - static Window? GetWindow(IMsBoxWindow window) - { - var _window = window.GetType().GetField("_window", BindingFlags.NonPublic | BindingFlags.Instance); - if (_window != null && _window.FieldType.IsSubclassOf(typeof(Window))) - { - if (_window.GetValue(window) is Window w) - { - return w; - } - } - return null; - } - } -} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButton.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButtonCompat.cs similarity index 80% rename from System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButton.cs rename to System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButtonCompat.cs index 25c79cc3c..44bddc174 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButton.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxButtonCompat.cs @@ -1,9 +1,9 @@ namespace System.Windows { /// - /// 指定显示在消息框上的按钮。 用作 .Show... 方法的参数。 + /// 指定显示在消息框上的按钮。 用作 .Show... 方法的参数。 /// - public enum MessageBoxButton + public enum MessageBoxButtonCompat { OK = 0, OKCancel = 1, diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxCompat.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxCompat.cs new file mode 100644 index 000000000..0264f7fa9 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxCompat.cs @@ -0,0 +1,137 @@ +extern alias MessageBox_Avalonia; + +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using MessageBox_Avalonia::MessageBox.Avalonia; +using MessageBox_Avalonia::MessageBox.Avalonia.BaseWindows.Base; +using MessageBox_Avalonia::MessageBox.Avalonia.DTO; +using MessageBox_Avalonia::MessageBox.Avalonia.Enums; +using System.Application.Services; +using System.Reflection; +using System.Threading.Tasks; +using AvaloniaApplication = Avalonia.Application; + +namespace System.Windows +{ + /// + /// 显示消息框。 + /// + public static class MessageBoxCompat + { + static ButtonEnum GetButtonEnum(this MessageBoxButtonCompat button) => button switch + { + MessageBoxButtonCompat.OK => ButtonEnum.Ok, + MessageBoxButtonCompat.OKCancel => ButtonEnum.OkCancel, + MessageBoxButtonCompat.YesNo => ButtonEnum.YesNo, + MessageBoxButtonCompat.YesNoCancel => ButtonEnum.YesNoCancel, +#pragma warning disable CS0618 // 类型或成员已过时 + MessageBoxButtonCompat.OkAbort => ButtonEnum.OkAbort, + MessageBoxButtonCompat.YesNoAbort => ButtonEnum.YesNoAbort, +#pragma warning restore CS0618 // 类型或成员已过时 + _ => throw new ArgumentOutOfRangeException(nameof(button), $"value: {button}"), + }; + + static Icon GetIcon(this MessageBoxImageCompat icon) => icon switch + { + MessageBoxImageCompat.Asterisk => Icon.Info, + MessageBoxImageCompat.Error => Icon.Error, + MessageBoxImageCompat.Exclamation => Icon.Warning, + MessageBoxImageCompat.None => Icon.None, +#pragma warning disable CS0618 // 类型或成员已过时 + MessageBoxImageCompat.Question => Icon.Info, + MessageBoxImageCompat.Battery => Icon.Battery, + MessageBoxImageCompat.Database => Icon.Database, + MessageBoxImageCompat.Folder => Icon.Folder, + MessageBoxImageCompat.Forbidden => Icon.Forbidden, + MessageBoxImageCompat.Plus => Icon.Plus, + MessageBoxImageCompat.Setting => Icon.Setting, + MessageBoxImageCompat.SpeakerLess => Icon.SpeakerLess, + MessageBoxImageCompat.SpeakerMore => Icon.SpeakerMore, + MessageBoxImageCompat.Stop2 => Icon.Stop, + MessageBoxImageCompat.Stopwatch => Icon.Stopwatch, + MessageBoxImageCompat.Wifi => Icon.Wifi, +#pragma warning restore CS0618 // 类型或成员已过时 + _ => throw new ArgumentOutOfRangeException(nameof(icon), $"value: {icon}"), + }; + + static MessageBoxResultCompat GetResult(this ButtonResult result) => result switch + { + ButtonResult.Ok => MessageBoxResultCompat.OK, + ButtonResult.Yes => MessageBoxResultCompat.Yes, + ButtonResult.No => MessageBoxResultCompat.No, +#pragma warning disable CS0618 // 类型或成员已过时 + ButtonResult.Abort => MessageBoxResultCompat.Abort, +#pragma warning restore CS0618 // 类型或成员已过时 + ButtonResult.Cancel => MessageBoxResultCompat.Cancel, + ButtonResult.None => MessageBoxResultCompat.None, + _ => throw new ArgumentOutOfRangeException(nameof(result), $"value: {result}"), + }; + + /// + public static async Task ShowAsync( + string messageBoxText, string caption, MessageBoxButtonCompat button, MessageBoxImageCompat icon) + { + var f = DI.Get_Nullable(); + + if (f != null) + { + return await f.ShowAsync(messageBoxText, caption, button, icon); + } + + var parms = new MessageBoxStandardParams + { + ButtonDefinitions = button.GetButtonEnum(), + ContentTitle = caption, + ContentMessage = messageBoxText, + Icon = icon.GetIcon(), + Style = Style.None, + WindowStartupLocation = WindowStartupLocation.CenterScreen, + }; + var msBoxStandardWindow = MessageBoxManager.GetMessageBoxStandardWindow(parms); + var window = GetWindow(msBoxStandardWindow); + if (window != null) + { + window.Topmost = true; + window.SetResizeMode(ResizeModeCompat.NoResize); + window.SetDefaultFontFamily(); + } + + ButtonResult? result = null; + + if (AvaloniaApplication.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + var ownerWindow = desktop.MainWindow; + if (ownerWindow != null && ownerWindow.IsInitialized && ownerWindow.IsVisible) + { + result = await msBoxStandardWindow.ShowDialog(ownerWindow); + } + } + + if (!result.HasValue) + { + result = await msBoxStandardWindow.Show(); + } + + return GetResult(result.Value); + } + + /// + public static async void Show(string messageBoxText, string caption, MessageBoxButtonCompat button, MessageBoxImageCompat icon) + { + await ShowAsync(messageBoxText, caption, button, icon); + } + + static Window? GetWindow(IMsBoxWindow window) + { + var _window = window.GetType().GetField("_window", BindingFlags.NonPublic | BindingFlags.Instance); + if (_window != null && _window.FieldType.IsSubclassOf(typeof(Window))) + { + if (_window.GetValue(window) is Window w) + { + return w; + } + } + return null; + } + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImage.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImageCompat.cs similarity index 97% rename from System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImage.cs rename to System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImageCompat.cs index bfe803f8a..7febb3182 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImage.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxImageCompat.cs @@ -3,7 +3,7 @@ /// /// 指定消息框所显示的图标。 /// - public enum MessageBoxImage + public enum MessageBoxImageCompat { #pragma warning disable CA1069 // 不应复制枚举值 Asterisk = 64, diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResult.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResultCompat.cs similarity index 78% rename from System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResult.cs rename to System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResultCompat.cs index 86b3d1fba..16a6edab3 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResult.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBoxResultCompat.cs @@ -1,9 +1,9 @@ namespace System.Windows { /// - /// 指定用户单击的消息框按钮。 由 .Show... 方法返回。 + /// 指定用户单击的消息框按钮。 由 .Show... 方法返回。 /// - public enum MessageBoxResult + public enum MessageBoxResultCompat { Cancel = 2, No = 7, diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeMode.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeModeCompat.cs similarity index 97% rename from System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeMode.cs rename to System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeModeCompat.cs index fe1c0dbe5..300afc3fd 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeMode.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/ResizeModeCompat.cs @@ -5,7 +5,7 @@ namespace System.Windows /// /// 指定是否可以调整窗口大小,并在可调整大小的情况下指定如何调整窗口大小。由 SetResizeMode 使用。 /// - public enum ResizeMode + public enum ResizeModeCompat { /// /// 用户无法调整窗口的大小。 不显示 "最大化" 和 "最小化" 框。 diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs index a5ebeb4b5..d650b8d5d 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs @@ -53,18 +53,18 @@ namespace System.Windows /// /// /// - public static void SetResizeMode(this Window window, ResizeMode value) + public static void SetResizeMode(this Window window, ResizeModeCompat value) { var p = DI.Get(); switch (value) { - case ResizeMode.NoResize: - case ResizeMode.CanMinimize: + case ResizeModeCompat.NoResize: + case ResizeModeCompat.CanMinimize: window.CanResize = false; break; - case ResizeMode.CanResize: + case ResizeModeCompat.CanResize: #pragma warning disable CS0618 // 类型或成员已过时 - case ResizeMode.CanResizeWithGrip: + case ResizeModeCompat.CanResizeWithGrip: #pragma warning restore CS0618 // 类型或成员已过时 window.CanResize = true; break; diff --git a/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/NotifyIcon.cs b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/NotifyIcon.cs index 0db0bd9f8..a5e4c73eb 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/NotifyIcon.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/NotifyIcon.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Application.UI.Views; +using System.Collections.Generic; using System.Drawing; namespace System.Application.UI @@ -9,8 +10,7 @@ namespace System.Application.UI public class NotifyIcon : INotifyIcon { const string TAG = "NotifyIcon"; - - NotifyIconHelperWindow? _helperWindow = null; + readonly INotifyIconWindow? _window = null; readonly int _uID = 0; static int _nextUID = 0; bool _iconAdded = false; @@ -108,7 +108,17 @@ namespace System.Application.UI public NotifyIcon() { _uID = ++_nextUID; - _helperWindow = new NotifyIconHelperWindow(this); + + var notifyIconWindow = DI.Get_Nullable>(); + if (notifyIconWindow != null) + { + notifyIconWindow.Initialize(this); + _window = notifyIconWindow; + } + else + { + _window = new NotifyIconWindow(this); + } } ~NotifyIcon() @@ -122,10 +132,10 @@ namespace System.Application.UI /// If set to true, the notify icon will be removed. void UpdateIcon(bool remove = false) { - if (_helperWindow == null) throw new ArgumentNullException(nameof(_helperWindow)); + if (_window == null) throw new ArgumentNullException(nameof(_window)); UnmanagedMethods.NOTIFYICONDATA iconData = new UnmanagedMethods.NOTIFYICONDATA() { - hWnd = _helperWindow.Handle, + hWnd = _window.Handle, uID = _uID, uFlags = UnmanagedMethods.NIF.TIP | UnmanagedMethods.NIF.MESSAGE, uCallbackMessage = (int)UnmanagedMethods.CustomWindowsMessage.WM_TRAYMOUSE, @@ -194,7 +204,7 @@ namespace System.Application.UI i++; }); - if (_helperWindow == null) throw new ArgumentNullException(nameof(_helperWindow)); + if (_window == null) throw new ArgumentNullException(nameof(_window)); // To display a context menu for a notification icon, the current window // must be the foreground window before the application calls TrackPopupMenu @@ -202,7 +212,7 @@ namespace System.Application.UI // clicks outside of the menu or the window that created the menu (if it is // visible). If the current window is a child window, you must set the // (top-level) parent window as the foreground window. - _ = UnmanagedMethods.SetForegroundWindow(_helperWindow.Handle); + _ = UnmanagedMethods.SetForegroundWindow(_window.Handle); // Get the mouse cursor position _ = UnmanagedMethods.GetCursorPos(out UnmanagedMethods.POINT pt); @@ -214,7 +224,7 @@ namespace System.Application.UI UnmanagedMethods.UFLAGS.TPM_RIGHTALIGN | UnmanagedMethods.UFLAGS.TPM_NONOTIFY | UnmanagedMethods.UFLAGS.TPM_RETURNCMD, - pt.X, pt.Y, _helperWindow.Handle, IntPtr.Zero); + pt.X, pt.Y, _window.Handle, IntPtr.Zero); // If we have a result, execute the corresponding command if (commandId != 0) @@ -265,15 +275,31 @@ namespace System.Application.UI } } + public static IntPtr? WndProc(NotifyIcon notifyIcon, uint msg, IntPtr wParam, IntPtr lParam) + { + Log.Info(TAG, "WndProc called on NotifyIcon helper window: MSG = {0}", + ((UnmanagedMethods.WindowsMessage)msg).ToString()); + + switch (msg) + { + case (uint)UnmanagedMethods.CustomWindowsMessage.WM_TRAYMOUSE: + // Forward WM_TRAYMOUSE messages to the tray icon's window procedure + notifyIcon.WndProc(msg, wParam, lParam); + break; + } + + return null; + } + /// /// A native Win32 helper window encapsulation for dealing with the window /// messages sent by the notification icon. /// - sealed class NotifyIconHelperWindow : NativeWindow + sealed class NotifyIconWindow : NativeWindow, INotifyIconWindow { readonly NotifyIcon _notifyIcon; - public NotifyIconHelperWindow(NotifyIcon notifyIcon) : base() + public NotifyIconWindow(NotifyIcon notifyIcon) : base() { _notifyIcon = notifyIcon; } @@ -283,19 +309,8 @@ namespace System.Application.UI /// protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { - Log.Info(TAG, "WndProc called on NotifyIcon helper window: MSG = {0}", - ((UnmanagedMethods.WindowsMessage)msg).ToString()); - - switch (msg) - { - case (uint)UnmanagedMethods.CustomWindowsMessage.WM_TRAYMOUSE: - // Forward WM_TRAYMOUSE messages to the tray icon's window procedure - _notifyIcon.WndProc(msg, wParam, lParam); - break; - default: - return base.WndProc(hWnd, msg, wParam, lParam); - } - return IntPtr.Zero; + var value = NotifyIcon.WndProc(_notifyIcon, msg, wParam, lParam); + return value ?? base.WndProc(hWnd, msg, wParam, lParam); } } } diff --git a/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml new file mode 100644 index 000000000..35917ca26 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml.cs b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml.cs new file mode 100644 index 000000000..68220e133 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop.Windows/Application/UI/WpfApp.xaml.cs @@ -0,0 +1,20 @@ +using System.Windows; +using System.Windows.Shell; +using WpfApplication = System.Windows.Application; + +namespace System.Application.UI +{ + /// + /// Interaction logic for App.xaml + /// + public partial class WpfApp : WpfApplication + { + void JumpList_JumpItemsRejected(object sender, JumpItemsRejectedEventArgs e) + { + } + + void JumpList_JumpItemsRemovedByUser(object sender, JumpItemsRemovedEventArgs e) + { + } + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Windows/MouseHook.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/MouseHook.cs similarity index 99% rename from System.Application.SteamTools.Client.Desktop.Windows/MouseHook.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/MouseHook.cs index 8eca72ef6..59eeb6851 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/MouseHook.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/MouseHook.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; +// ReSharper disable once CheckNamespace namespace System { internal static class MouseHook diff --git a/System.Application.SteamTools.Client.Desktop.Windows/NativeMethods.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeMethods.cs similarity index 87% rename from System.Application.SteamTools.Client.Desktop.Windows/NativeMethods.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeMethods.cs index 56426c95e..90532c6ff 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/NativeMethods.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeMethods.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; +// ReSharper disable once CheckNamespace namespace System { internal static class NativeMethods diff --git a/System.Application.SteamTools.Client.Desktop.Windows/NativeWindow.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeWindow.cs similarity index 98% rename from System.Application.SteamTools.Client.Desktop.Windows/NativeWindow.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeWindow.cs index 701776e52..725176c4c 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/NativeWindow.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/NativeWindow.cs @@ -1,6 +1,7 @@ using System.ComponentModel; using System.Runtime.InteropServices; +// ReSharper disable once CheckNamespace namespace System { /// diff --git a/System.Application.SteamTools.Client.Desktop.Windows/PointInt32.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/PointInt32.cs similarity index 88% rename from System.Application.SteamTools.Client.Desktop.Windows/PointInt32.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/PointInt32.cs index 153cb029f..890db0436 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/PointInt32.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/PointInt32.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; +// ReSharper disable once CheckNamespace namespace System { [Serializable] diff --git a/System.Application.SteamTools.Client.Desktop.Windows/RECT.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/RECT.cs similarity index 85% rename from System.Application.SteamTools.Client.Desktop.Windows/RECT.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/RECT.cs index e942867f2..a556046b5 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/RECT.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/RECT.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; +// ReSharper disable once CheckNamespace namespace System { [StructLayout(LayoutKind.Sequential)] diff --git a/System.Application.SteamTools.Client.Desktop.Windows/UnmanagedMethods.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/UnmanagedMethods.cs similarity index 99% rename from System.Application.SteamTools.Client.Desktop.Windows/UnmanagedMethods.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/UnmanagedMethods.cs index b8d1ee727..ee76b649b 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/UnmanagedMethods.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/UnmanagedMethods.cs @@ -10,6 +10,7 @@ using System.Text; #nullable disable +// ReSharper disable once CheckNamespace namespace System { internal static class UnmanagedMethods diff --git a/System.Application.SteamTools.Client.Desktop.Windows/User32Window.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/User32Window.cs similarity index 99% rename from System.Application.SteamTools.Client.Desktop.Windows/User32Window.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/User32Window.cs index 2ac0199b6..dd7c4f93d 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/User32Window.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/User32Window.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; using System.Text; +// ReSharper disable once CheckNamespace namespace System { internal static class User32Window diff --git a/System.Application.SteamTools.Client.Desktop.Windows/WinHttp.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/WinHttp.cs similarity index 94% rename from System.Application.SteamTools.Client.Desktop.Windows/WinHttp.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/WinHttp.cs index fda5ea225..ec7c4436c 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/WinHttp.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/WinHttp.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; +// ReSharper disable once CheckNamespace namespace System { internal static class WinHttp diff --git a/System.Application.SteamTools.Client.Desktop.Windows/WinInet.cs b/System.Application.SteamTools.Client.Desktop.Windows/Internals/WinInet.cs similarity index 99% rename from System.Application.SteamTools.Client.Desktop.Windows/WinInet.cs rename to System.Application.SteamTools.Client.Desktop.Windows/Internals/WinInet.cs index bb26b6e4b..24137f3b5 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/WinInet.cs +++ b/System.Application.SteamTools.Client.Desktop.Windows/Internals/WinInet.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using System.Text; +// ReSharper disable once CheckNamespace namespace System { internal class WinInet diff --git a/System.Application.SteamTools.Client.Desktop.Windows/System.Application.SteamTools.Client.Desktop.Windows.csproj b/System.Application.SteamTools.Client.Desktop.Windows/System.Application.SteamTools.Client.Desktop.Windows.csproj index 05b0742ea..7eec44d38 100644 --- a/System.Application.SteamTools.Client.Desktop.Windows/System.Application.SteamTools.Client.Desktop.Windows.csproj +++ b/System.Application.SteamTools.Client.Desktop.Windows/System.Application.SteamTools.Client.Desktop.Windows.csproj @@ -1,8 +1,9 @@  - net5.0 + net5.0-windows System + true diff --git a/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.Generated.cs b/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.Generated.cs deleted file mode 100644 index cd3ab2e04..000000000 --- a/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.Generated.cs +++ /dev/null @@ -1,282 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// -// This file was generated, please do not edit it directly. -// -// Please see MilCodeGen.html for more information. -// - -// These types are aliased to match the unamanaged names used in interop - -namespace System.Windows -{ - [Serializable] - partial struct Point : IFormattable - { - //------------------------------------------------------ - // - // Public Methods - // - //------------------------------------------------------ - - #region Public Methods - - /// - /// Compares two Point instances for exact equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which are logically equal may fail. - /// Furthermore, using this equality operator, Double.NaN is not equal to itself. - /// - /// - /// bool - true if the two Point instances are exactly equal, false otherwise - /// - /// The first Point to compare - /// The second Point to compare - public static bool operator ==(Point point1, Point point2) - { - return point1.X == point2.X && - point1.Y == point2.Y; - } - - /// - /// Compares two Point instances for exact inequality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which are logically equal may fail. - /// Furthermore, using this equality operator, Double.NaN is not equal to itself. - /// - /// - /// bool - true if the two Point instances are exactly unequal, false otherwise - /// - /// The first Point to compare - /// The second Point to compare - public static bool operator !=(Point point1, Point point2) - { - return !(point1 == point2); - } - /// - /// Compares two Point instances for object equality. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if the two Point instances are exactly equal, false otherwise - /// - /// The first Point to compare - /// The second Point to compare - public static bool Equals(Point point1, Point point2) - { - return point1.X.Equals(point2.X) && - point1.Y.Equals(point2.Y); - } - - /// - /// Equals - compares this Point with the passed in object. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if the object is an instance of Point and if it's equal to "this". - /// - /// The object to compare to "this" - public override bool Equals(object o) - { - if ((null == o) || !(o is Point)) - { - return false; - } - - Point value = (Point)o; - return Point.Equals(this, value); - } - - /// - /// Equals - compares this Point with the passed in object. In this equality - /// Double.NaN is equal to itself, unlike in numeric equality. - /// Note that double values can acquire error when operated upon, such that - /// an exact comparison between two values which - /// are logically equal may fail. - /// - /// - /// bool - true if "value" is equal to "this". - /// - /// The Point to compare to "this" - public bool Equals(Point value) - { - return Point.Equals(this, value); - } - /// - /// Returns the HashCode for this Point - /// - /// - /// int - the HashCode for this Point - /// - public override int GetHashCode() - { - // Perform field-by-field XOR of HashCodes - return X.GetHashCode() ^ - Y.GetHashCode(); - } - - #endregion Public Methods - - //------------------------------------------------------ - // - // Public Properties - // - //------------------------------------------------------ - - #region Public Properties - - /// - /// X - double. Default value is 0. - /// - public double X - { - get - { - return _x; - } - - set - { - _x = value; - } - } - - /// - /// Y - double. Default value is 0. - /// - public double Y - { - get - { - return _y; - } - - set - { - _y = value; - } - } - - #endregion Public Properties - - //------------------------------------------------------ - // - // Protected Methods - // - //------------------------------------------------------ - - //------------------------------------------------------ - // - // Internal Methods - // - //------------------------------------------------------ - - //------------------------------------------------------ - // - // Internal Properties - // - //------------------------------------------------------ - - #region Internal Properties - - /// - /// Creates a string representation of this object based on the current culture. - /// - /// - /// A string representation of this object. - /// - public override string ToString() - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(null /* format string */, null /* format provider */); - } - - /// - /// Creates a string representation of this object based on the IFormatProvider - /// passed in. If the provider is null, the CurrentCulture is used. - /// - /// - /// A string representation of this object. - /// - public string ToString(IFormatProvider provider) - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(null /* format string */, provider); - } - - /// - /// Creates a string representation of this object based on the format string - /// and IFormatProvider passed in. - /// If the provider is null, the CurrentCulture is used. - /// See the documentation for IFormattable for more information. - /// - /// - /// A string representation of this object. - /// - string IFormattable.ToString(string format, IFormatProvider provider) - { - // Delegate to the internal method which implements all ToString calls. - return ConvertToString(format, provider); - } - - /// - /// Creates a string representation of this object based on the format string - /// and IFormatProvider passed in. - /// If the provider is null, the CurrentCulture is used. - /// See the documentation for IFormattable for more information. - /// - /// - /// A string representation of this object. - /// - internal string ConvertToString(string format, IFormatProvider provider) - { - // Helper to get the numeric list separator for a given culture. - const char separator = ','; - return String.Format(provider, - "{1:" + format + "}{0}{2:" + format + "}", - separator, - _x, - _y); - } - - #endregion Internal Properties - - //------------------------------------------------------ - // - // Dependency Properties - // - //------------------------------------------------------ - - //------------------------------------------------------ - // - // Internal Fields - // - //------------------------------------------------------ - - #region Internal Fields - - internal double _x; - internal double _y; - - #endregion Internal Fields - - #region Constructors - - //------------------------------------------------------ - // - // Constructors - // - //------------------------------------------------------ - - #endregion Constructors - } -} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.cs b/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.cs deleted file mode 100644 index c0ae8b2cd..000000000 --- a/System.Application.SteamTools.Client.Desktop.Windows/Windows/Point.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// - -namespace System.Windows -{ - /// - /// Point - Defaults to 0,0 - /// - public partial struct Point - { - #region Constructors - - /// - /// Constructor which accepts the X and Y values - /// - /// The value for the X coordinate of the new Point - /// The value for the Y coordinate of the new Point - public Point(double x, double y) - { - _x = x; - _y = y; - } - - #endregion Constructors - - #region Public Methods - - /// - /// Offset - update the location by adding offsetX to X and offsetY to Y - /// - /// The offset in the x dimension - /// The offset in the y dimension - public void Offset(double offsetX, double offsetY) - { - _x += offsetX; - _y += offsetY; - } - - #endregion Public Methods - } -} \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop/UI/Views/INotifyIconWindow.cs b/System.Application.SteamTools.Client.Desktop/UI/Views/INotifyIconWindow.cs new file mode 100644 index 000000000..78f1d73a4 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop/UI/Views/INotifyIconWindow.cs @@ -0,0 +1,12 @@ +namespace System.Application.UI.Views +{ + public interface INotifyIconWindow + { + IntPtr Handle { get; } + } + + public interface INotifyIconWindow : INotifyIconWindow + { + void Initialize(INotifyIcon notifyIcon); + } +} \ No newline at end of file