2026-04-05 15:04:37 +08:00
|
|
|
|
using H.NotifyIcon;
|
2025-08-31 11:43:52 +08:00
|
|
|
|
using Ink_Canvas.Helpers;
|
2026-03-14 17:19:05 +08:00
|
|
|
|
using iNKORE.UI.WPF.Controls;
|
2025-08-31 11:43:52 +08:00
|
|
|
|
using System;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
using System.Diagnostics;
|
2026-04-05 09:53:14 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
2025-07-28 14:40:44 +08:00
|
|
|
|
using System.Windows.Forms;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
using System.Windows.Interop;
|
2026-04-05 15:49:06 +08:00
|
|
|
|
using System.Windows.Threading;
|
2025-07-28 14:40:44 +08:00
|
|
|
|
using Application = System.Windows.Application;
|
|
|
|
|
|
using ContextMenu = System.Windows.Controls.ContextMenu;
|
|
|
|
|
|
using MenuItem = System.Windows.Controls.MenuItem;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
|
|
|
|
|
namespace Ink_Canvas
|
|
|
|
|
|
{
|
2025-08-03 16:46:33 +08:00
|
|
|
|
public partial class App : Application
|
|
|
|
|
|
{
|
2026-04-05 15:49:06 +08:00
|
|
|
|
private const int TrayTemporaryShowMinutes = 2;
|
|
|
|
|
|
|
|
|
|
|
|
private DispatcherTimer _trayTemporaryShowTimer;
|
|
|
|
|
|
|
|
|
|
|
|
private bool _trayTemporaryShowRestoreHideChecked;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 系统托盘菜单打开时的事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理系统托盘菜单打开时的逻辑,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取系统托盘菜单及其相关菜单项和图标
|
|
|
|
|
|
/// 2. 获取主窗口实例
|
|
|
|
|
|
/// 3. 如果主窗口已加载:
|
|
|
|
|
|
/// - 在无焦点模式下,暂时取消主窗口置顶,让系统菜单能够正常显示
|
|
|
|
|
|
/// - 根据浮动栏是否处于收纳模式,更新菜单项图标和文本
|
|
|
|
|
|
/// - 根据浮动栏状态和主窗口是否隐藏,更新重置浮动栏位置菜单项的启用状态
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void SysTrayMenu_Opened(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
var s = (ContextMenu)sender;
|
2026-02-22 10:14:12 +08:00
|
|
|
|
var FoldFloatingBarTrayIconMenuItemIconEyeOff = (Image)((Grid)((MenuItem)s.Items[s.Items.Count - 5]).Icon).Children[0];
|
|
|
|
|
|
var FoldFloatingBarTrayIconMenuItemIconEyeOn = (Image)((Grid)((MenuItem)s.Items[s.Items.Count - 5]).Icon).Children[1];
|
|
|
|
|
|
var FoldFloatingBarTrayIconMenuItemHeaderText = (TextBlock)((SimpleStackPanel)((MenuItem)s.Items[s.Items.Count - 5]).Header).Children[0];
|
2025-05-25 09:29:48 +08:00
|
|
|
|
var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4];
|
2026-04-05 09:53:14 +08:00
|
|
|
|
var HideICCMainWindowTrayIconMenuItem = s.Items.OfType<MenuItem>()
|
|
|
|
|
|
.FirstOrDefault(mi => mi.Name == "HideICCMainWindowTrayIconMenuItem");
|
|
|
|
|
|
if (HideICCMainWindowTrayIconMenuItem == null) return;
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (mainWin.IsLoaded)
|
|
|
|
|
|
{
|
2025-09-06 13:48:44 +08:00
|
|
|
|
// 在无焦点模式下,暂时取消主窗口置顶,让系统菜单能够正常显示
|
2025-09-06 12:38:57 +08:00
|
|
|
|
if (Ink_Canvas.MainWindow.Settings.Advanced.IsAlwaysOnTop && Ink_Canvas.MainWindow.Settings.Advanced.IsNoFocusMode)
|
|
|
|
|
|
{
|
2025-09-06 13:48:44 +08:00
|
|
|
|
mainWin.Topmost = false;
|
2025-09-06 12:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
|
// 判斷是否在收納模式中
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (mainWin.isFloatingBarFolded)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
FoldFloatingBarTrayIconMenuItemIconEyeOff.Visibility = Visibility.Hidden;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItemIconEyeOn.Visibility = Visibility.Visible;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItemHeaderText.Text = "退出收纳模式";
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (!HideICCMainWindowTrayIconMenuItem.IsChecked)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = false;
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.Opacity = 0.5;
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
FoldFloatingBarTrayIconMenuItemIconEyeOff.Visibility = Visibility.Visible;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItemIconEyeOn.Visibility = Visibility.Hidden;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItemHeaderText.Text = "切换为收纳模式";
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (!HideICCMainWindowTrayIconMenuItem.IsChecked)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = true;
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.Opacity = 1;
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 系统托盘菜单关闭时的事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理系统托盘菜单关闭时的逻辑,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载,且在无焦点模式下启用了始终置顶,则恢复主窗口的置顶状态
|
|
|
|
|
|
/// </remarks>
|
2026-04-05 09:53:14 +08:00
|
|
|
|
private bool EnsureMainWindowReadyForSettings(MainWindow mainWin)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mainWin?.IsLoaded != true)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var trayMenu = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu;
|
|
|
|
|
|
var hideMainWindowMenuItem = trayMenu?.Items.OfType<MenuItem>()
|
|
|
|
|
|
.FirstOrDefault(mi => mi.Name == "HideICCMainWindowTrayIconMenuItem");
|
|
|
|
|
|
|
|
|
|
|
|
if (hideMainWindowMenuItem != null && hideMainWindowMenuItem.IsChecked)
|
|
|
|
|
|
{
|
|
|
|
|
|
hideMainWindowMenuItem.IsChecked = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!mainWin.IsVisible)
|
|
|
|
|
|
{
|
|
|
|
|
|
mainWin.Show();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (mainWin.WindowState == WindowState.Minimized)
|
|
|
|
|
|
{
|
|
|
|
|
|
mainWin.WindowState = WindowState.Normal;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mainWin.Activate();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-05 15:49:06 +08:00
|
|
|
|
private void TempShowMainWindowTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var mainWin = Current.MainWindow as MainWindow;
|
|
|
|
|
|
if (mainWin?.IsLoaded != true)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
MenuItem hideItem = null;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var trayMenu = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu;
|
|
|
|
|
|
hideItem = trayMenu?.Items.OfType<MenuItem>()
|
|
|
|
|
|
.FirstOrDefault(mi => mi.Name == "HideICCMainWindowTrayIconMenuItem");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_trayTemporaryShowRestoreHideChecked = hideItem?.IsChecked == true;
|
|
|
|
|
|
|
|
|
|
|
|
EnsureMainWindowReadyForSettings(mainWin);
|
|
|
|
|
|
|
|
|
|
|
|
global::Ink_Canvas.MainWindow.TrayTemporaryShowUntilUtc = DateTime.UtcNow.AddMinutes(TrayTemporaryShowMinutes);
|
|
|
|
|
|
|
|
|
|
|
|
_trayTemporaryShowTimer?.Stop();
|
|
|
|
|
|
if (_trayTemporaryShowTimer == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_trayTemporaryShowTimer = new DispatcherTimer
|
|
|
|
|
|
{
|
|
|
|
|
|
Interval = TimeSpan.FromMinutes(TrayTemporaryShowMinutes)
|
|
|
|
|
|
};
|
|
|
|
|
|
_trayTemporaryShowTimer.Tick += TrayTemporaryShowTimer_OnTick;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_trayTemporaryShowTimer.Interval = TimeSpan.FromMinutes(TrayTemporaryShowMinutes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_trayTemporaryShowTimer.Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void TrayTemporaryShowTimer_OnTick(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
_trayTemporaryShowTimer?.Stop();
|
|
|
|
|
|
global::Ink_Canvas.MainWindow.TrayTemporaryShowUntilUtc = null;
|
|
|
|
|
|
|
|
|
|
|
|
var mainWin = Current.MainWindow as MainWindow;
|
|
|
|
|
|
if (mainWin?.IsLoaded != true)
|
|
|
|
|
|
{
|
|
|
|
|
|
_trayTemporaryShowRestoreHideChecked = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_trayTemporaryShowRestoreHideChecked)
|
|
|
|
|
|
{
|
|
|
|
|
|
var trayMenu = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu;
|
|
|
|
|
|
var hideItem = trayMenu?.Items.OfType<MenuItem>()
|
|
|
|
|
|
.FirstOrDefault(mi => mi.Name == "HideICCMainWindowTrayIconMenuItem");
|
|
|
|
|
|
if (hideItem != null)
|
|
|
|
|
|
hideItem.IsChecked = true;
|
|
|
|
|
|
else
|
|
|
|
|
|
mainWin.Hide();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
mainWin.CheckMainWindowVisibility();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.WriteLogToFile($"托盘临时显示计时结束处理失败: {ex.Message}", LogHelper.LogType.Warning);
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
_trayTemporaryShowRestoreHideChecked = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-05 09:53:14 +08:00
|
|
|
|
private void OpenSettingsTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var mainWin = Current.MainWindow as MainWindow;
|
|
|
|
|
|
if (!EnsureMainWindowReadyForSettings(mainWin))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var method = typeof(MainWindow).GetMethod("BtnSettings_Click", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
|
|
method?.Invoke(mainWin, new object[] { null, null });
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.WriteLogToFile($"Open settings from tray failed: {ex.Message}", LogHelper.LogType.Error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-06 12:38:57 +08:00
|
|
|
|
private void SysTrayMenu_Closed(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-09-06 12:38:57 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 菜单关闭后,恢复主窗口的置顶状态
|
|
|
|
|
|
if (Ink_Canvas.MainWindow.Settings.Advanced.IsAlwaysOnTop && Ink_Canvas.MainWindow.Settings.Advanced.IsNoFocusMode)
|
|
|
|
|
|
{
|
2025-09-06 13:48:44 +08:00
|
|
|
|
mainWin.Topmost = true;
|
2025-09-06 12:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关闭应用程序托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理关闭应用程序托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 设置IsAppExitByUser为true,表示用户主动退出
|
|
|
|
|
|
/// - 关闭应用程序
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void CloseAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
IsAppExitByUser = true;
|
2026-02-22 16:29:30 +08:00
|
|
|
|
mainWin.BtnExit_Click(null, null);
|
2025-06-12 10:34:29 +08:00
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 重启应用程序托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理重启应用程序托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 设置IsAppExitByUser为true,表示用户主动退出
|
|
|
|
|
|
/// - 尝试启动应用程序的新实例,带延迟参数
|
|
|
|
|
|
/// - 捕获并记录启动新实例时可能出现的异常
|
|
|
|
|
|
/// - 关闭当前应用程序实例
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void RestartAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
IsAppExitByUser = true;
|
2025-08-03 16:46:33 +08:00
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-07-29 02:33:19 +08:00
|
|
|
|
// 启动新实例
|
2025-06-18 18:16:48 +08:00
|
|
|
|
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
|
|
|
|
|
ProcessStartInfo startInfo = new ProcessStartInfo();
|
|
|
|
|
|
startInfo.FileName = exePath;
|
|
|
|
|
|
startInfo.UseShellExecute = true;
|
2025-08-03 16:46:33 +08:00
|
|
|
|
|
2025-06-18 18:16:48 +08:00
|
|
|
|
// 启动进程但不等待
|
2025-08-19 17:41:42 +08:00
|
|
|
|
Process.Start(new ProcessStartInfo(exePath, "-delay 2000") { UseShellExecute = true });
|
2025-08-03 16:46:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2025-06-18 18:16:48 +08:00
|
|
|
|
LogHelper.NewLog($"重启程序时出错: {ex.Message}");
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
|
2025-06-18 18:16:48 +08:00
|
|
|
|
// 退出当前实例
|
2025-07-28 14:40:44 +08:00
|
|
|
|
Current.Shutdown();
|
2025-06-13 09:19:44 +08:00
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 强制全屏化托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理强制全屏化托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 调用MoveWindow方法将主窗口移动到屏幕左上角并设置为全屏大小
|
|
|
|
|
|
/// - 显示强制全屏化的消息,包含屏幕分辨率和缩放比例信息
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void ForceFullScreenTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
Ink_Canvas.MainWindow.MoveWindow(new WindowInteropHelper(mainWin).Handle, 0, 0,
|
2025-07-28 14:40:44 +08:00
|
|
|
|
Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, true);
|
|
|
|
|
|
Ink_Canvas.MainWindow.ShowNewMessage($"已强制全屏化:{Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height}(缩放比例为{Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})");
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 切换浮动栏收纳模式托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理切换浮动栏收纳模式托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 如果浮动栏当前处于收纳模式,则调用UnFoldFloatingBar_MouseUp方法退出收纳模式
|
|
|
|
|
|
/// - 否则,调用FoldFloatingBar_MouseUp方法进入收纳模式
|
|
|
|
|
|
/// </remarks>
|
2025-05-25 09:29:48 +08:00
|
|
|
|
private void FoldFloatingBarTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (mainWin.isFloatingBarFolded) mainWin.UnFoldFloatingBar_MouseUp(new object(), null);
|
|
|
|
|
|
else mainWin.FoldFloatingBar_MouseUp(new object(), null);
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 重置浮动栏位置托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理重置浮动栏位置托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 检查是否处于PPT演示模式
|
|
|
|
|
|
/// - 如果浮动栏当前未处于收纳模式:
|
|
|
|
|
|
/// - 如果不处于PPT演示模式,调用PureViewboxFloatingBarMarginAnimationInDesktopMode方法重置浮动栏位置
|
|
|
|
|
|
/// - 否则,调用PureViewboxFloatingBarMarginAnimationInPPTMode方法重置浮动栏位置
|
|
|
|
|
|
/// </remarks>
|
2025-05-25 09:29:48 +08:00
|
|
|
|
private void ResetFloatingBarPositionTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
var isInPPTPresentationMode = false;
|
2025-08-03 16:46:33 +08:00
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
isInPPTPresentationMode = mainWin.BtnPPTSlideShowEnd.Visibility == Visibility.Visible;
|
|
|
|
|
|
});
|
2025-08-03 16:46:33 +08:00
|
|
|
|
if (!mainWin.isFloatingBarFolded)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
if (!isInPPTPresentationMode) mainWin.PureViewboxFloatingBarMarginAnimationInDesktopMode();
|
|
|
|
|
|
else mainWin.PureViewboxFloatingBarMarginAnimationInPPTMode();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 隐藏主窗口托盘菜单项选中事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理隐藏主窗口托盘菜单项的选中事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取菜单项和主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 隐藏主窗口
|
|
|
|
|
|
/// - 获取系统托盘菜单
|
|
|
|
|
|
/// - 禁用并设置半透明效果给以下菜单项:
|
|
|
|
|
|
/// - 重置浮动栏位置
|
|
|
|
|
|
/// - 切换浮动栏收纳模式
|
|
|
|
|
|
/// - 强制全屏化
|
|
|
|
|
|
/// 3. 否则,取消菜单项的选中状态
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void HideICCMainWindowTrayIconMenuItem_Checked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-05 15:49:06 +08:00
|
|
|
|
_trayTemporaryShowTimer?.Stop();
|
|
|
|
|
|
global::Ink_Canvas.MainWindow.TrayTemporaryShowUntilUtc = null;
|
|
|
|
|
|
_trayTemporaryShowRestoreHideChecked = false;
|
|
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
|
var mi = (MenuItem)sender;
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
mainWin.Hide();
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var s = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (s != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4];
|
|
|
|
|
|
var FoldFloatingBarTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 5];
|
|
|
|
|
|
var ForceFullScreenTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 6];
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = false;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItem.IsEnabled = false;
|
|
|
|
|
|
ForceFullScreenTrayIconMenuItem.IsEnabled = false;
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.Opacity = 0.5;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItem.Opacity = 0.5;
|
|
|
|
|
|
ForceFullScreenTrayIconMenuItem.Opacity = 0.5;
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
mi.IsChecked = false;
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 显示主窗口托盘菜单项取消选中事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理显示主窗口托盘菜单项的取消选中事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取菜单项和主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载:
|
|
|
|
|
|
/// - 显示主窗口
|
|
|
|
|
|
/// - 获取系统托盘菜单
|
|
|
|
|
|
/// - 启用并设置正常透明度给以下菜单项:
|
|
|
|
|
|
/// - 重置浮动栏位置
|
|
|
|
|
|
/// - 切换浮动栏收纳模式
|
|
|
|
|
|
/// - 强制全屏化
|
|
|
|
|
|
/// 3. 否则,取消菜单项的选中状态
|
|
|
|
|
|
/// </remarks>
|
2025-08-03 16:46:33 +08:00
|
|
|
|
private void HideICCMainWindowTrayIconMenuItem_UnChecked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
var mi = (MenuItem)sender;
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-08-03 16:46:33 +08:00
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
mainWin.Show();
|
2025-07-28 14:40:44 +08:00
|
|
|
|
var s = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (s != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4];
|
|
|
|
|
|
var FoldFloatingBarTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 5];
|
|
|
|
|
|
var ForceFullScreenTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 6];
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = true;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItem.IsEnabled = true;
|
|
|
|
|
|
ForceFullScreenTrayIconMenuItem.IsEnabled = true;
|
|
|
|
|
|
ResetFloatingBarPositionTrayIconMenuItem.Opacity = 1;
|
|
|
|
|
|
FoldFloatingBarTrayIconMenuItem.Opacity = 1;
|
|
|
|
|
|
ForceFullScreenTrayIconMenuItem.Opacity = 1;
|
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
mi.IsChecked = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-22 10:14:12 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 禁用/启用所有快捷键托盘菜单项点击事件处理方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">事件发送者</param>
|
|
|
|
|
|
/// <param name="e">路由事件参数</param>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 处理禁用/启用所有快捷键托盘菜单项的点击事件,包括以下步骤:
|
|
|
|
|
|
/// 1. 获取主窗口实例
|
|
|
|
|
|
/// 2. 如果主窗口已加载,尝试:
|
|
|
|
|
|
/// - 通过反射获取全局快捷键管理器
|
|
|
|
|
|
/// - 如果获取成功:
|
|
|
|
|
|
/// - 禁用快捷键注册
|
|
|
|
|
|
/// - 更新菜单项文本和状态:
|
|
|
|
|
|
/// - 如果当前文本是"禁用所有快捷键",则更改为"启用所有快捷键"并记录日志
|
|
|
|
|
|
/// - 否则,更改为"禁用所有快捷键",重新启用快捷键注册并记录日志
|
|
|
|
|
|
/// - 如果获取失败,记录错误日志
|
|
|
|
|
|
/// 3. 捕获并记录可能出现的异常
|
|
|
|
|
|
/// </remarks>
|
2025-09-13 14:33:49 +08:00
|
|
|
|
private void DisableAllHotkeysMenuItem_Clicked(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var mainWin = (MainWindow)Current.MainWindow;
|
2026-03-21 23:06:16 +08:00
|
|
|
|
if (mainWin != null && mainWin.IsLoaded)
|
2025-09-13 14:33:49 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取全局快捷键管理器
|
2026-02-22 10:14:12 +08:00
|
|
|
|
var hotkeyManagerField = typeof(MainWindow).GetField("_globalHotkeyManager", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
2025-09-30 19:15:03 +08:00
|
|
|
|
var hotkeyManager = hotkeyManagerField?.GetValue(mainWin) as GlobalHotkeyManager;
|
2025-10-03 17:08:46 +08:00
|
|
|
|
|
2025-09-30 19:15:03 +08:00
|
|
|
|
if (hotkeyManager != null)
|
2025-09-13 14:33:49 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 禁用所有快捷键
|
|
|
|
|
|
hotkeyManager.DisableHotkeyRegistration();
|
2025-10-03 17:08:46 +08:00
|
|
|
|
|
2025-09-13 14:33:49 +08:00
|
|
|
|
// 更新菜单项文本和状态
|
2025-09-30 19:15:03 +08:00
|
|
|
|
var menuItem = sender as MenuItem;
|
|
|
|
|
|
if (menuItem != null)
|
2025-09-13 14:33:49 +08:00
|
|
|
|
{
|
2025-09-30 19:15:03 +08:00
|
|
|
|
var headerPanel = menuItem.Header as SimpleStackPanel;
|
|
|
|
|
|
if (headerPanel != null)
|
2025-09-13 14:33:49 +08:00
|
|
|
|
{
|
2025-09-30 19:15:03 +08:00
|
|
|
|
var textBlock = headerPanel.Children[0] as TextBlock;
|
|
|
|
|
|
if (textBlock != null)
|
2025-09-13 14:33:49 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (textBlock.Text == "禁用所有快捷键")
|
|
|
|
|
|
{
|
|
|
|
|
|
textBlock.Text = "启用所有快捷键";
|
|
|
|
|
|
LogHelper.WriteLogToFile("已禁用所有快捷键", LogHelper.LogType.Event);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
textBlock.Text = "禁用所有快捷键";
|
|
|
|
|
|
// 重新启用快捷键
|
|
|
|
|
|
hotkeyManager.EnableHotkeyRegistration();
|
|
|
|
|
|
LogHelper.WriteLogToFile("已启用所有快捷键", LogHelper.LogType.Event);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.WriteLogToFile("无法获取全局快捷键管理器", LogHelper.LogType.Error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.WriteLogToFile($"禁用/启用快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|