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