返回提交历史
Modified
HaloPixelToolBox/HaloPixelToolBox/App.xaml.cs
+75
-76
Modified
HaloPixelToolBox/HaloPixelToolBox/Implements/Services/TrayIconService.cs
+1
-0
Modified
HaloPixelToolBox/HaloPixelToolBox/TrayMenuWindow.xaml
+1
-1
Modified
HaloPixelToolBox/HaloPixelToolBox/TrayMenuWindow.xaml.cs
+2
-0
Added
HaloPixelToolBox/HaloPixelToolBox/ViewModels/TrayMenuPageViewModel.cs
+103
-0
Modified
HaloPixelToolBox/HaloPixelToolBox/Views/TrayMenuPage.xaml
+41
-7
Modified
HaloPixelToolBox/HaloPixelToolBox/Views/TrayMenuPage.xaml.cs
+9
-60
XFEstudio/HaloPixelToolBox
优化托盘界面外观
95505c4
代码差异
7 个文件
+232
-144
@@ -8,100 +8,99 @@ using XFEExtension.NetCore.WinUIHelper.Utilities;
8
8
using XFEExtension.NetCore.WinUIHelper.Utilities.Helper;
9
9
using XFEExtension.NetCore.XFEConsole;
10
10
11
namespace HaloPixelToolBox
11
namespace HaloPixelToolBox;
12
13
/// <summary>
14
/// Provides application-specific behavior to supplement the default Application class.
15
/// </summary>
16
public partial class App : Application
12
17
{
18
public ITrayIconService TrayIconService { get; } = ServiceManager.GetService<ITrayIconService>();
19
/// <summary>
20
/// 主页窗口
21
/// </summary>
22
public static MainWindow MainWindow { get; set; } = new();
23
13
24
/// <summary>
14
/// Provides application-specific behavior to supplement the default Application class.
25
/// Initializes the singleton application object. This is the first line of authored code
26
/// executed, and as such is the logical equivalent of main() or WinMain().
15
27
/// </summary>
16
public partial class App : Application
28
public App()
17
29
{
18
public ITrayIconService TrayIconService { get; } = ServiceManager.GetService<ITrayIconService>();
19
/// <summary>
20
/// 主页窗口
21
/// </summary>
22
public static MainWindow MainWindow { get; set; } = new();
30
XFEConsole.UseXFEConsoleLog();
31
XFEConsole.Log.LogPath = Path.Combine(AppPath.LogDictionary, XFEConsole.Log.LogPath);
32
Console.WriteLine("正在初始化应用程序...");
33
this.InitializeComponent();
34
Console.WriteLine("应用程序初始化完成");
35
AppThemeHelper.Theme = SystemProfile.Theme;
36
PageManager.RegisterPage(typeof(AppShellPage));
37
PageManager.RegisterPage(typeof(CloudMusicLyricsToolPage));
38
PageManager.RegisterPage(typeof(MainPage));
39
PageManager.RegisterPage(typeof(SettingPage));
40
UnhandledException += App_UnhandledException;
41
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
42
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
43
}
23
44
24
/// <summary>
25
/// Initializes the singleton application object. This is the first line of authored code
26
/// executed, and as such is the logical equivalent of main() or WinMain().
27
/// </summary>
28
public App()
45
private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
46
{
47
if (e.ExceptionObject is Exception ex)
29
48
{
30
XFEConsole.UseXFEConsoleLog();
31
XFEConsole.Log.LogPath = Path.Combine(AppPath.LogDictionary, XFEConsole.Log.LogPath);
32
Console.WriteLine("正在初始化应用程序...");
33
this.InitializeComponent();
34
Console.WriteLine("应用程序初始化完成");
35
AppThemeHelper.Theme = SystemProfile.Theme;
36
PageManager.RegisterPage(typeof(AppShellPage));
37
PageManager.RegisterPage(typeof(CloudMusicLyricsToolPage));
38
PageManager.RegisterPage(typeof(MainPage));
39
PageManager.RegisterPage(typeof(SettingPage));
40
UnhandledException += App_UnhandledException;
41
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
42
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
49
Console.WriteLine($"[ERROR]{ex.Message}");
50
Console.WriteLine($"[TRACE]{ex.StackTrace}");
43
51
}
44
45
private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
52
else
46
53
{
47
if (e.ExceptionObject is Exception ex)
48
{
49
Console.WriteLine($"[ERROR]{ex.Message}");
50
Console.WriteLine($"[TRACE]{ex.StackTrace}");
51
}
52
else
53
{
54
Console.WriteLine("[ERROR]发生未处理的异常,但无法获取异常信息");
55
Console.WriteLine(e.ExceptionObject.ToString());
56
}
54
Console.WriteLine("[ERROR]发生未处理的异常,但无法获取异常信息");
55
Console.WriteLine(e.ExceptionObject.ToString());
57
56
}
57
}
58
58
59
private void CurrentDomain_ProcessExit(object? sender, EventArgs e)
59
private void CurrentDomain_ProcessExit(object? sender, EventArgs e)
60
{
61
Console.WriteLine("正在退出...");
62
Console.WriteLine("正在保存日志...");
63
var logs = Directory.GetFiles(AppPath.LogDictionary);
64
if (logs.Length > 10)
60
65
{
61
Console.WriteLine("正在退出...");
62
Console.WriteLine("正在保存日志...");
63
var logs = Directory.GetFiles(AppPath.LogDictionary);
64
if (logs.Length > 10)
66
foreach (var log in logs.OrderByDescending(x => x).Skip(10))
65
67
{
66
foreach (var log in logs.OrderByDescending(x => x).Skip(10))
67
{
68
File.Delete(log);
69
}
68
File.Delete(log);
70
69
}
71
Console.WriteLine("日志保存成功");
72
70
}
71
Console.WriteLine("日志保存成功");
72
}
73
73
74
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
74
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
75
{
76
if (ServiceManager.GetService<IMessageService>() is IMessageService messageService)
75
77
{
76
if (ServiceManager.GetService<IMessageService>() is IMessageService messageService)
77
{
78
messageService.ShowMessage(e.Message, "发生错误", InfoBarSeverity.Error);
79
Console.WriteLine($"[ERROR]{e.Message}");
80
Console.WriteLine($"[TRACE]{e.Exception.StackTrace}");
81
e.Handled = true;
82
}
78
messageService.ShowMessage(e.Message, "发生错误", InfoBarSeverity.Error);
79
Console.WriteLine($"[ERROR]{e.Message}");
80
Console.WriteLine($"[TRACE]{e.Exception.StackTrace}");
81
e.Handled = true;
83
82
}
83
}
84
84
85
/// <summary>
86
/// Invoked when the application is launched.
87
/// </summary>
88
/// <param name="args">Details about the launch request and process.</param>
89
protected override void OnLaunched(LaunchActivatedEventArgs args)
90
{
91
TrayIconService.Initilize(DispatcherQueue.GetForCurrentThread());
92
MainWindow.Closed += MainWindow_Closed;
93
MainWindow.Content = new AppShellPage();
94
if (SystemProfile.MinimizeWhenOpen)
95
MainWindow.AppWindow.Hide();
96
else
97
MainWindow.Activate();
98
AppThemeHelper.MainWindow = MainWindow;
99
}
85
/// <summary>
86
/// Invoked when the application is launched.
87
/// </summary>
88
/// <param name="args">Details about the launch request and process.</param>
89
protected override void OnLaunched(LaunchActivatedEventArgs args)
90
{
91
TrayIconService.Initilize(DispatcherQueue.GetForCurrentThread());
92
MainWindow.Closed += MainWindow_Closed;
93
MainWindow.Content = new AppShellPage();
94
if (SystemProfile.MinimizeWhenOpen)
95
MainWindow.AppWindow.Hide();
96
else
97
MainWindow.Activate();
98
AppThemeHelper.MainWindow = MainWindow;
99
}
100
100
101
private void MainWindow_Closed(object sender, WindowEventArgs args)
102
{
103
Win32Helper.ShowWindow(WindowHelper.GetHwndForCurrentWindow(), Win32Helper.SW_HIDE);
104
args.Handled = true;
105
}
101
private void MainWindow_Closed(object sender, WindowEventArgs args)
102
{
103
Win32Helper.ShowWindow(WindowHelper.GetHwndForCurrentWindow(), Win32Helper.SW_HIDE);
104
args.Handled = true;
106
105
}
107
106
}
@@ -56,6 +56,7 @@ public partial class TrayIconService : GlobalServiceBase, ITrayIconService
56
56
var menu = new TrayMenuWindow();
57
57
menu.AppWindow.MoveInZOrderAtTop();
58
58
menu.AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped);
59
menu.AppWindow.IsShownInSwitchers = false;
59
60
if (menu.AppWindow.Presenter is OverlappedPresenter presenter)
60
61
{
61
62
presenter.SetBorderAndTitleBar(true, false);
@@ -11,6 +11,6 @@
11
11
Title="TrayMenuWindow">
12
12
13
13
<Window.SystemBackdrop>
14
<MicaBackdrop />
14
<DesktopAcrylicBackdrop/>
15
15
</Window.SystemBackdrop>
16
16
</Window>
@@ -1,3 +1,5 @@
1
using Microsoft.UI.Xaml.Media;
2
1
3
namespace HaloPixelToolBox;
2
4
3
5
/// <summary>
@@ -0,0 +1,103 @@
1
using CommunityToolkit.Mvvm.Input;
2
using HaloPixelToolBox.Interface.Services;
3
using HaloPixelToolBox.Utilities.Helpers;
4
using HaloPixelToolBox.Utilities.Helpers.Win32;
5
using HaloPixelToolBox.Views;
6
using Microsoft.UI.Dispatching;
7
using System.Runtime.InteropServices;
8
using XFEExtension.NetCore.WinUIHelper.Implements;
9
using XFEExtension.NetCore.WinUIHelper.Utilities;
10
11
namespace HaloPixelToolBox.ViewModels;
12
13
public partial class TrayMenuPageViewModel : ServiceBaseViewModelBase<string>
14
{
15
IntPtr _mouseHook = new();
16
LowLevelMouseProc? _proc;
17
public Window MenuWindow { get; set; }
18
public DispatcherQueue DispatcherQueue => MenuWindow.DispatcherQueue;
19
20
public TrayMenuPageViewModel(Window window)
21
{
22
MenuWindow = window;
23
AutoNavigationParameterService.ParameterChange += AutoNavigationParameterService_ParameterChange;
24
}
25
26
private void AutoNavigationParameterService_ParameterChange(object? sender, string? e)
27
{
28
if (AutoNavigationParameterService.CurrentPage is not null)
29
{
30
AutoNavigationParameterService.CurrentPage.Unloaded += CurrentPage_Unloaded;
31
}
32
InstallMouseHook();
33
}
34
35
private void CurrentPage_Unloaded(object sender, RoutedEventArgs e)
36
{
37
UnInstallMouseHook();
38
}
39
40
void UnInstallMouseHook()
41
{
42
if (_mouseHook != IntPtr.Zero)
43
{
44
Win32Helper.UnhookWindowsHookEx(_mouseHook);
45
_mouseHook = IntPtr.Zero;
46
}
47
}
48
49
void InstallMouseHook()
50
{
51
_proc = HookCallback;
52
_mouseHook = Win32Helper.SetWindowsHookEx(Win32Helper.WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
53
}
54
55
IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
56
{
57
try
58
{
59
if (nCode >= 0 && wParam == Win32Helper.WM_LBUTTONDOWN)
60
{
61
var hook = Marshal.PtrToStructure<MSLLHOOKSTRUCT>(lParam);
62
var pt = hook.pt;
63
64
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(MenuWindow);
65
Win32Helper.GetWindowRect(hwnd, out RECT rect);
66
67
bool inside =
68
pt.x >= rect.Left && pt.x <= rect.Right &&
69
pt.y >= rect.Top && pt.y <= rect.Bottom;
70
71
if (!inside)
72
{
73
DispatcherQueue.TryEnqueue(() =>
74
{
75
MenuWindow.Close();
76
});
77
}
78
}
79
}
80
catch { }
81
82
return Win32Helper.CallNextHookEx(_mouseHook, nCode, wParam, lParam);
83
}
84
85
[RelayCommand]
86
void Show()
87
{
88
ServiceManager.GetGlobalService<ITrayIconService>()?.ShowWindow();
89
NavigationViewService?.NavigateTo<CloudMusicLyricsToolPage>();
90
MenuWindow.Close();
91
}
92
93
[RelayCommand]
94
void OpenSettings()
95
{
96
ServiceManager.GetGlobalService<ITrayIconService>()?.ShowWindow();
97
NavigationViewService?.NavigateTo<SettingPage>();
98
MenuWindow.Close();
99
}
100
101
[RelayCommand]
102
static void Exit() => ServiceManager.GetGlobalService<ITrayIconService>()?.ExitApp();
103
}
@@ -6,16 +6,50 @@
6
6
xmlns:local="using:HaloPixelToolBox.Views"
7
7
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
8
8
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
mc:Ignorable="d">
9
mc:Ignorable="d" Loaded="Page_Loaded" Background="{ThemeResource DesktopAcrylicTransparentBrush}">
10
<Page.Resources>
11
<Style x:Key="MenuButtonStyle" TargetType="Button">
12
<Style.Setters>
13
<Setter Property="Background" Value="Transparent"/>
14
<Setter Property="CornerRadius" Value="0"/>
15
<Setter Property="BorderThickness" Value="0"/>
16
<Setter Property="HorizontalAlignment" Value="Stretch"/>
17
<Setter Property="HorizontalContentAlignment" Value="Left"/>
18
</Style.Setters>
19
</Style>
20
<Style x:Key="MenuSeparatorStyle" TargetType="MenuFlyoutSeparator">
21
<Style.Setters>
22
<Setter Property="Margin" Value="10,5"/>
23
</Style.Setters>
24
</Style>
25
</Page.Resources>
10
26
11
27
<StackPanel x:Name="panel" HorizontalAlignment="Center" VerticalAlignment="Center">
12
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center" Padding="20">
28
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center" Padding="20,20,20,5">
13
29
<Image Source="/Assets/icon.png" HorizontalAlignment="Left" Width="16" Height="16"/>
14
<TextBlock Text="花再音响工具箱" VerticalAlignment="Center"/>
30
<TextBlock Text="花再工具箱" VerticalAlignment="Center"/>
15
31
</StackPanel>
16
<MenuFlyoutSeparator Margin="10,0"/>
17
<Button Content="打开主界面" Click="Show_Click" HorizontalAlignment="Stretch" Style="{StaticResource SubtleButtonStyle}"/>
18
<MenuFlyoutSeparator Margin="10,0"/>
19
<Button Content="退出" Click="Exit_Click" HorizontalAlignment="Stretch" Style="{StaticResource SubtleButtonStyle}"/>
32
<MenuFlyoutSeparator Style="{ThemeResource MenuSeparatorStyle}"/>
33
<Button Command="{x:Bind ViewModel.ShowCommand}" Style="{ThemeResource MenuButtonStyle}">
34
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Left">
35
<FontIcon Glyph="" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="15"/>
36
<TextBlock Grid.Column="1" Text="主页" VerticalAlignment="Center"/>
37
</StackPanel>
38
</Button>
39
<MenuFlyoutSeparator Style="{ThemeResource MenuSeparatorStyle}"/>
40
<Button Command="{x:Bind ViewModel.OpenSettingsCommand}" Style="{ThemeResource MenuButtonStyle}">
41
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Left">
42
<FontIcon Glyph="" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="15"/>
43
<TextBlock Grid.Column="1" Text="设置" VerticalAlignment="Center"/>
44
</StackPanel>
45
</Button>
46
<MenuFlyoutSeparator Style="{ThemeResource MenuSeparatorStyle}"/>
47
<Button Command="{x:Bind ViewModel.ExitCommand}" Style="{ThemeResource MenuButtonStyle}">
48
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Left">
49
<FontIcon Glyph="" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="15"/>
50
<TextBlock Text="退出" VerticalAlignment="Center"/>
51
</StackPanel>
52
</Button>
53
<Grid Margin="0,5"/>
20
54
</StackPanel>
21
55
</Page>
@@ -1,34 +1,24 @@
1
using HaloPixelToolBox.Interface.Services;
2
using HaloPixelToolBox.Utilities.Helpers;
3
using HaloPixelToolBox.Utilities.Helpers.Win32;
4
using System.Runtime.InteropServices;
5
1
using System.Windows.Forms;
6
2
using Windows.Graphics;
7
using XFEExtension.NetCore.WinUIHelper.Utilities;
8
3
9
4
namespace HaloPixelToolBox.Views;
10
5
11
6
/// <summary>
12
/// An empty page that can be used on its own or navigated to within a Frame.
7
/// ���̲˵�ҳ��
13
8
/// </summary>
14
9
public sealed partial class TrayMenuPage : Page
15
10
{
16
IntPtr _mouseHook = new();
17
LowLevelMouseProc? _proc;
18
11
public Window MenuWindow { get; set; }
12
public TrayMenuPageViewModel ViewModel { get; set; }
13
public static TrayMenuPage? Current { get; set; }
19
14
20
15
public TrayMenuPage(Window window)
21
16
{
17
Current = this;
22
18
MenuWindow = window;
19
ViewModel = new(window);
23
20
InitializeComponent();
24
this.Loaded += (_, __) =>
25
{
26
DispatcherQueue.TryEnqueue(() =>
27
{
28
ResizeToContent();
29
});
30
};
31
InstallMouseHook();
21
ViewModel.AutoNavigationParameterService.Initialize(this);
32
22
}
33
23
34
24
void ResizeToContent()
@@ -48,50 +38,9 @@ public sealed partial class TrayMenuPage : Page
48
38
MenuWindow.AppWindow.Move(new PointInt32(Cursor.Position.X + 5, Cursor.Position.Y - h + 10));
49
39
}
50
40
51
private void Show_Click(object _, RoutedEventArgs __)
41
private void Page_Loaded(object sender, RoutedEventArgs e)
52
42
{
53
ServiceManager.GetGlobalService<ITrayIconService>()?.ShowWindow();
54
MenuWindow.Close();
55
}
56
57
private void Exit_Click(object _, RoutedEventArgs __)
58
{
59
ServiceManager.GetGlobalService<ITrayIconService>()?.ExitApp();
60
}
61
62
void InstallMouseHook()
63
{
64
_proc = HookCallback;
65
_mouseHook = Win32Helper.SetWindowsHookEx(Win32Helper.WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
66
}
67
68
IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
69
{
70
try
71
{
72
if (nCode >= 0 && wParam == Win32Helper.WM_LBUTTONDOWN)
73
{
74
var hook = Marshal.PtrToStructure<MSLLHOOKSTRUCT>(lParam);
75
var pt = hook.pt;
76
77
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(MenuWindow);
78
Win32Helper.GetWindowRect(hwnd, out RECT rect);
79
80
bool inside =
81
pt.x >= rect.Left && pt.x <= rect.Right &&
82
pt.y >= rect.Top && pt.y <= rect.Bottom;
83
84
if (!inside)
85
{
86
DispatcherQueue.TryEnqueue(() =>
87
{
88
MenuWindow.Close();
89
});
90
}
91
}
92
}
93
catch { }
94
95
return Win32Helper.CallNextHookEx(_mouseHook, nCode, wParam, lParam);
43
DispatcherQueue.TryEnqueue(ResizeToContent);
44
ViewModel.AutoNavigationParameterService.OnParameterChange(string.Empty);
96
45
}
97
46
}