A:增加复古右键菜单
This commit is contained in:
1 parent
49b8b424b7
commit
5a4f8ebc24
1 file changed
+244
-199
@@ -1,9 +1,12 @@
|
|||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using Shell.UserControls;
|
using Shell.Views;
|
||||||
|
|
||||||
namespace Shell.Utils;
|
namespace Shell.Utils;
|
||||||
|
|
||||||
@@ -11,7 +14,7 @@ public class TrayIconManager : IDisposable
|
|||||||
{
|
{
|
||||||
private NotifyIcon _notifyIcon;
|
private NotifyIcon _notifyIcon;
|
||||||
private Window _mainWindow;
|
private Window _mainWindow;
|
||||||
private TrayMenuWindow _trayMenu;
|
private ContextMenu _contextMenu;
|
||||||
private DispatcherTimer _clickTimer;
|
private DispatcherTimer _clickTimer;
|
||||||
private bool _isDoubleClick = false;
|
private bool _isDoubleClick = false;
|
||||||
|
|
||||||
@@ -74,6 +77,7 @@ public class TrayIconManager : IDisposable
|
|||||||
_mainWindow = mainWindow;
|
_mainWindow = mainWindow;
|
||||||
InitializeTrayIcon();
|
InitializeTrayIcon();
|
||||||
InitializeClickTimer();
|
InitializeClickTimer();
|
||||||
|
InitializeContextMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeTrayIcon()
|
private void InitializeTrayIcon()
|
||||||
@@ -98,6 +102,119 @@ public class TrayIconManager : IDisposable
|
|||||||
_clickTimer.Tick += OnClickTimerTick;
|
_clickTimer.Tick += OnClickTimerTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeContextMenu()
|
||||||
|
{
|
||||||
|
_contextMenu = new ContextMenu();
|
||||||
|
|
||||||
|
// 添加失去焦点时关闭事件
|
||||||
|
_contextMenu.Closed += (s, e) =>
|
||||||
|
{
|
||||||
|
/* 菜单关闭 */
|
||||||
|
};
|
||||||
|
_contextMenu.LostFocus += (s, e) => _contextMenu.IsOpen = false;
|
||||||
|
|
||||||
|
// 展示主窗口(可勾选)
|
||||||
|
var showMainWindowItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "展示主窗口",
|
||||||
|
IsCheckable = true,
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
showMainWindowItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
ToggleMainWindow();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(showMainWindowItem);
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
_contextMenu.Items.Add(new Separator());
|
||||||
|
|
||||||
|
// 重置主窗口位置
|
||||||
|
var resetPositionItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "重置主窗口位置",
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
resetPositionItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
ResetNetViewPosition();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(resetPositionItem);
|
||||||
|
|
||||||
|
// 切换监控网络
|
||||||
|
var networkSelectionItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "切换监控网络",
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(networkSelectionItem);
|
||||||
|
|
||||||
|
// 显示详细信息
|
||||||
|
var detailedInfoItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "显示详细信息",
|
||||||
|
IsCheckable = true,
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
detailedInfoItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
ToggleDetailedInfo();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(detailedInfoItem);
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
_contextMenu.Items.Add(new Separator());
|
||||||
|
|
||||||
|
// 流量统计与分析
|
||||||
|
var trafficAnalysisItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "流量统计与分析",
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
trafficAnalysisItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
OpenTrafficAnalysis();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(trafficAnalysisItem);
|
||||||
|
|
||||||
|
// 设置
|
||||||
|
var settingsItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "设置",
|
||||||
|
Icon = new TextBlock { Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons") }
|
||||||
|
};
|
||||||
|
settingsItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
OpenSettings();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(settingsItem);
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
_contextMenu.Items.Add(new Separator());
|
||||||
|
|
||||||
|
// 退出程序
|
||||||
|
var exitItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = "退出程序",
|
||||||
|
Icon = new TextBlock
|
||||||
|
{
|
||||||
|
Text = "", FontFamily = new System.Windows.Media.FontFamily("Segoe Fluent Icons"),
|
||||||
|
Foreground = new SolidColorBrush(Colors.Red)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exitItem.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
ExitApplication();
|
||||||
|
_contextMenu.IsOpen = false;
|
||||||
|
};
|
||||||
|
_contextMenu.Items.Add(exitItem);
|
||||||
|
}
|
||||||
|
|
||||||
private Icon LoadIcon()
|
private Icon LoadIcon()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -114,15 +231,7 @@ public class TrayIconManager : IDisposable
|
|||||||
{
|
{
|
||||||
if (e.Button == MouseButtons.Right)
|
if (e.Button == MouseButtons.Right)
|
||||||
{
|
{
|
||||||
try
|
ShowContextMenu();
|
||||||
{
|
|
||||||
ShowContextMenu();
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
Console.WriteLine(exception);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (e.Button == MouseButtons.Left)
|
else if (e.Button == MouseButtons.Left)
|
||||||
{
|
{
|
||||||
@@ -150,6 +259,74 @@ public class TrayIconManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowContextMenu()
|
||||||
|
{
|
||||||
|
// 更新菜单状态
|
||||||
|
UpdateContextMenuStates();
|
||||||
|
|
||||||
|
// 直接设置菜单位置为鼠标位置,不使用临时窗口
|
||||||
|
_contextMenu.PlacementTarget = null;
|
||||||
|
_contextMenu.Placement = PlacementMode.MousePoint;
|
||||||
|
_contextMenu.StaysOpen = false;
|
||||||
|
|
||||||
|
// 使用 PreviewMouseDown 事件来处理点击外部关闭
|
||||||
|
_contextMenu.PreviewMouseDown += OnContextMenuPreviewMouseDown;
|
||||||
|
|
||||||
|
// 当菜单关闭时,清理事件
|
||||||
|
RoutedEventHandler closedHandler = null;
|
||||||
|
closedHandler = (s, e) =>
|
||||||
|
{
|
||||||
|
_contextMenu.PreviewMouseDown -= OnContextMenuPreviewMouseDown;
|
||||||
|
_contextMenu.Closed -= closedHandler;
|
||||||
|
};
|
||||||
|
_contextMenu.Closed += closedHandler;
|
||||||
|
|
||||||
|
_contextMenu.IsOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnContextMenuPreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
// 如果点击的是菜单项,让事件继续处理
|
||||||
|
// 这个方法主要是为了确保菜单行为正常
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateContextMenuStates()
|
||||||
|
{
|
||||||
|
if (_mainWindow is Shell.Views.NetView netView)
|
||||||
|
{
|
||||||
|
// 获取各个菜单项并更新状态
|
||||||
|
foreach (var item in _contextMenu.Items.OfType<MenuItem>())
|
||||||
|
{
|
||||||
|
switch (item.Header.ToString())
|
||||||
|
{
|
||||||
|
case "展示主窗口":
|
||||||
|
item.IsChecked = netView.IsVisible;
|
||||||
|
break;
|
||||||
|
case "显示详细信息":
|
||||||
|
item.IsChecked = GetNetViewMenuItemState(netView, "DetailedInfoMenuItem");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetNetViewMenuItemState(Shell.Views.NetView netView, string menuItemName)
|
||||||
|
{
|
||||||
|
var contextMenu = netView.ContextMenu;
|
||||||
|
if (contextMenu?.Items != null)
|
||||||
|
{
|
||||||
|
foreach (var item in contextMenu.Items)
|
||||||
|
{
|
||||||
|
if (item is MenuItem menuItem && menuItem.Name == menuItemName)
|
||||||
|
{
|
||||||
|
return menuItem.IsChecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowMainWindow()
|
private void ShowMainWindow()
|
||||||
{
|
{
|
||||||
if (_mainWindow != null)
|
if (_mainWindow != null)
|
||||||
@@ -161,151 +338,19 @@ public class TrayIconManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowContextMenu()
|
|
||||||
{
|
|
||||||
Console.WriteLine("=== TrayIconManager ShowContextMenu ===");
|
|
||||||
|
|
||||||
if (_trayMenu == null)
|
|
||||||
{
|
|
||||||
_trayMenu = new TrayMenuWindow();
|
|
||||||
_trayMenu.OnShowMainWindow += () => ShowMainWindow();
|
|
||||||
_trayMenu.OnExitApplication += () => System.Windows.Application.Current.Shutdown();
|
|
||||||
_trayMenu.OnHideToTray += () => _mainWindow?.Hide();
|
|
||||||
|
|
||||||
// Connect new NetView-specific functionality
|
|
||||||
_trayMenu.OnShowNetMonitor += () => ShowNetMonitor();
|
|
||||||
_trayMenu.OnResetWindowPosition += () => ResetNetViewPosition();
|
|
||||||
_trayMenu.OnToggleClickThrough += () => ToggleNetViewClickThrough();
|
|
||||||
_trayMenu.OnToggleTopmost += () => ToggleNetViewTopmost();
|
|
||||||
|
|
||||||
Console.WriteLine("创建新的TrayMenuWindow");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update menu states before showing
|
|
||||||
UpdateTrayMenuStates();
|
|
||||||
|
|
||||||
// 使用Win32 API获取鼠标位置
|
|
||||||
if (GetCursorPos(out POINT mousePos))
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Win32 API获取鼠标物理位置: X={mousePos.X}, Y={mousePos.Y}");
|
|
||||||
|
|
||||||
// 获取鼠标所在显示器的工作区域和DPI信息
|
|
||||||
var (workArea, dpiScaleX, dpiScaleY) = GetMouseMonitorInfoWithDpi(mousePos);
|
|
||||||
Console.WriteLine(
|
|
||||||
$"显示器工作区域: Left={workArea.Left}, Top={workArea.Top}, Right={workArea.Right}, Bottom={workArea.Bottom}");
|
|
||||||
Console.WriteLine($"DPI缩放比例: ScaleX={dpiScaleX:F2}, ScaleY={dpiScaleY:F2}");
|
|
||||||
|
|
||||||
// 将物理坐标转换为WPF逻辑坐标
|
|
||||||
var logicalMouseX = mousePos.X / dpiScaleX;
|
|
||||||
var logicalMouseY = mousePos.Y / dpiScaleY;
|
|
||||||
|
|
||||||
// 将工作区域也转换为逻辑坐标
|
|
||||||
var logicalWorkArea = new RECT
|
|
||||||
{
|
|
||||||
Left = (int)(workArea.Left / dpiScaleX),
|
|
||||||
Top = (int)(workArea.Top / dpiScaleY),
|
|
||||||
Right = (int)(workArea.Right / dpiScaleX),
|
|
||||||
Bottom = (int)(workArea.Bottom / dpiScaleY)
|
|
||||||
};
|
|
||||||
|
|
||||||
Console.WriteLine($"逻辑鼠标位置: X={logicalMouseX:F1}, Y={logicalMouseY:F1}");
|
|
||||||
Console.WriteLine(
|
|
||||||
$"逻辑工作区域: Left={logicalWorkArea.Left}, Top={logicalWorkArea.Top}, Right={logicalWorkArea.Right}, Bottom={logicalWorkArea.Bottom}");
|
|
||||||
|
|
||||||
_trayMenu.ShowAtWithWorkArea((int)logicalMouseX, (int)logicalMouseY, logicalWorkArea);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("获取鼠标位置失败,使用默认位置");
|
|
||||||
// 如果获取鼠标位置失败,使用托盘图标的估计位置
|
|
||||||
var workArea = SystemParameters.WorkArea;
|
|
||||||
var defaultX = (int)workArea.Right - 50;
|
|
||||||
var defaultY = (int)workArea.Bottom - 50;
|
|
||||||
Console.WriteLine($"使用默认位置: X={defaultX}, Y={defaultY}");
|
|
||||||
_trayMenu.ShowAt(defaultX, defaultY);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("=== ShowContextMenu End ===\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private (RECT workArea, double dpiScaleX, double dpiScaleY) GetMouseMonitorInfoWithDpi(POINT mousePos)
|
|
||||||
{
|
|
||||||
// 获取鼠标所在的显示器
|
|
||||||
IntPtr hMonitor = MonitorFromPoint(mousePos, MONITOR_DEFAULTTONEAREST);
|
|
||||||
|
|
||||||
// 获取显示器信息
|
|
||||||
MONITORINFO monitorInfo = new MONITORINFO();
|
|
||||||
monitorInfo.cbSize = (uint)Marshal.SizeOf(monitorInfo);
|
|
||||||
|
|
||||||
RECT workArea;
|
|
||||||
double dpiScaleX = 1.0;
|
|
||||||
double dpiScaleY = 1.0;
|
|
||||||
|
|
||||||
if (GetMonitorInfo(hMonitor, ref monitorInfo))
|
|
||||||
{
|
|
||||||
workArea = monitorInfo.rcWork;
|
|
||||||
|
|
||||||
// 获取该显示器的DPI
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (GetDpiForMonitor(hMonitor, DpiType.Effective, out uint dpiX, out uint dpiY) == 0)
|
|
||||||
{
|
|
||||||
dpiScaleX = dpiX / 96.0; // 96 DPI是标准DPI
|
|
||||||
dpiScaleY = dpiY / 96.0;
|
|
||||||
Console.WriteLine($"显示器DPI: X={dpiX}, Y={dpiY}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 如果GetDpiForMonitor失败,尝试使用系统DPI
|
|
||||||
var systemDpi = GetDpiForSystem();
|
|
||||||
dpiScaleX = dpiScaleY = systemDpi / 96.0;
|
|
||||||
Console.WriteLine($"使用系统DPI: {systemDpi}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"获取DPI失败: {ex.Message},使用默认缩放");
|
|
||||||
// 作为后备方案,使用WPF的DPI信息
|
|
||||||
var source = PresentationSource.FromVisual(System.Windows.Application.Current.MainWindow);
|
|
||||||
if (source?.CompositionTarget != null)
|
|
||||||
{
|
|
||||||
var matrix = source.CompositionTarget.TransformFromDevice;
|
|
||||||
dpiScaleX = 1.0 / matrix.M11;
|
|
||||||
dpiScaleY = 1.0 / matrix.M22;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 如果获取失败,返回主显示器的工作区域
|
|
||||||
var wpfWorkArea = SystemParameters.WorkArea;
|
|
||||||
workArea = new RECT
|
|
||||||
{
|
|
||||||
Left = (int)wpfWorkArea.Left,
|
|
||||||
Top = (int)wpfWorkArea.Top,
|
|
||||||
Right = (int)wpfWorkArea.Right,
|
|
||||||
Bottom = (int)wpfWorkArea.Bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
// 使用WPF的DPI信息作为后备
|
|
||||||
var source = PresentationSource.FromVisual(System.Windows.Application.Current.MainWindow);
|
|
||||||
if (source?.CompositionTarget != null)
|
|
||||||
{
|
|
||||||
var matrix = source.CompositionTarget.TransformFromDevice;
|
|
||||||
dpiScaleX = 1.0 / matrix.M11;
|
|
||||||
dpiScaleY = 1.0 / matrix.M22;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (workArea, dpiScaleX, dpiScaleY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowNetMonitor()
|
private void ShowNetMonitor()
|
||||||
{
|
{
|
||||||
if (_mainWindow != null)
|
if (_mainWindow != null)
|
||||||
{
|
{
|
||||||
_mainWindow.Show();
|
if (_mainWindow.IsVisible)
|
||||||
_mainWindow.Activate();
|
{
|
||||||
|
_mainWindow.Hide();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_mainWindow.Show();
|
||||||
|
_mainWindow.Activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,29 +358,24 @@ public class TrayIconManager : IDisposable
|
|||||||
{
|
{
|
||||||
if (_mainWindow is Shell.Views.NetView netView)
|
if (_mainWindow is Shell.Views.NetView netView)
|
||||||
{
|
{
|
||||||
// Call the public method to reset position
|
|
||||||
var workArea = SystemParameters.WorkArea;
|
var workArea = SystemParameters.WorkArea;
|
||||||
netView.Left = workArea.Right - netView.Width - 20;
|
netView.Left = workArea.Right - netView.Width - 20;
|
||||||
netView.Top = workArea.Top + 20;
|
netView.Top = workArea.Top + 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleNetViewClickThrough()
|
private void ToggleDetailedInfo()
|
||||||
{
|
{
|
||||||
if (_mainWindow is Shell.Views.NetView netView)
|
if (_mainWindow is Shell.Views.NetView netView)
|
||||||
{
|
{
|
||||||
// Access the NetView's private method through a public interface
|
|
||||||
// For now, let's access the property directly if possible
|
|
||||||
var contextMenu = netView.ContextMenu;
|
var contextMenu = netView.ContextMenu;
|
||||||
if (contextMenu?.Items != null)
|
if (contextMenu?.Items != null)
|
||||||
{
|
{
|
||||||
foreach (var item in contextMenu.Items)
|
foreach (var item in contextMenu.Items)
|
||||||
{
|
{
|
||||||
if (item is System.Windows.Controls.MenuItem menuItem &&
|
if (item is MenuItem menuItem && menuItem.Name == "DetailedInfoMenuItem")
|
||||||
menuItem.Name == "ClickThroughMenuItem")
|
|
||||||
{
|
{
|
||||||
menuItem.IsChecked = !menuItem.IsChecked;
|
var routedEventArgs = new RoutedEventArgs(MenuItem.ClickEvent);
|
||||||
var routedEventArgs = new System.Windows.RoutedEventArgs(System.Windows.Controls.MenuItem.ClickEvent);
|
|
||||||
menuItem.RaiseEvent(routedEventArgs);
|
menuItem.RaiseEvent(routedEventArgs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -344,62 +384,67 @@ public class TrayIconManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleNetViewTopmost()
|
private void OpenTrafficAnalysis()
|
||||||
{
|
{
|
||||||
if (_mainWindow is Shell.Views.NetView netView)
|
try
|
||||||
{
|
{
|
||||||
netView.Topmost = !netView.Topmost;
|
TrafficAnalysisWindow.ShowWindow();
|
||||||
|
}
|
||||||
// Update the context menu item
|
catch (Exception ex)
|
||||||
var contextMenu = netView.ContextMenu;
|
{
|
||||||
if (contextMenu?.Items != null)
|
System.Windows.MessageBox.Show($"无法打开流量分析窗口: {ex.Message}", "错误",
|
||||||
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SettingsWindow.ShowWindow();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Windows.MessageBox.Show($"无法打开设置窗口: {ex.Message}", "错误",
|
||||||
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleMainWindow()
|
||||||
|
{
|
||||||
|
if (_mainWindow != null)
|
||||||
|
{
|
||||||
|
if (_mainWindow.IsVisible)
|
||||||
{
|
{
|
||||||
foreach (var item in contextMenu.Items)
|
_mainWindow.Hide();
|
||||||
{
|
}
|
||||||
if (item is System.Windows.Controls.MenuItem menuItem &&
|
else
|
||||||
menuItem.Name == "TopmostMenuItem")
|
{
|
||||||
{
|
_mainWindow.Show();
|
||||||
menuItem.IsChecked = netView.Topmost;
|
_mainWindow.WindowState = WindowState.Normal;
|
||||||
break;
|
_mainWindow.Activate();
|
||||||
}
|
_mainWindow.Focus();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateTrayMenuStates()
|
private void ExitApplication()
|
||||||
{
|
{
|
||||||
if (_mainWindow is Shell.Views.NetView netView && _trayMenu != null)
|
var result = System.Windows.MessageBox.Show("确定要退出程序吗?", "确认退出",
|
||||||
|
MessageBoxButton.YesNo, MessageBoxImage.Question);
|
||||||
|
if (result == MessageBoxResult.Yes)
|
||||||
{
|
{
|
||||||
// Get current state from NetView
|
if (_mainWindow is Shell.Views.NetView netView)
|
||||||
bool isVisible = netView.IsVisible;
|
|
||||||
bool isTopmost = netView.Topmost;
|
|
||||||
|
|
||||||
// Get click-through state from context menu
|
|
||||||
bool isClickThrough = false;
|
|
||||||
var contextMenu = netView.ContextMenu;
|
|
||||||
if (contextMenu?.Items != null)
|
|
||||||
{
|
{
|
||||||
foreach (var item in contextMenu.Items)
|
netView.ForceClose();
|
||||||
{
|
|
||||||
if (item is System.Windows.Controls.MenuItem menuItem &&
|
|
||||||
menuItem.Name == "ClickThroughMenuItem")
|
|
||||||
{
|
|
||||||
isClickThrough = menuItem.IsChecked;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update tray menu with current states
|
|
||||||
_trayMenu.UpdateMenuStates(isVisible, isClickThrough, isTopmost, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_notifyIcon?.Dispose();
|
_notifyIcon?.Dispose();
|
||||||
_trayMenu?.Close();
|
_contextMenu = null;
|
||||||
_clickTimer?.Stop();
|
_clickTimer?.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user