Skip to content

Commit 8e0d845

Browse files
committed
解决快捷键可能延迟响应的问题
1 parent a2fd8ea commit 8e0d845

File tree

5 files changed

+118
-61
lines changed

5 files changed

+118
-61
lines changed

src/ComputerLock/App.xaml.cs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
using System.Globalization;
2-
using System.IO;
3-
using Microsoft.Extensions.DependencyInjection;
4-
using MudBlazor.Services;
5-
using System.Windows;
6-
using ComputerLock.Interfaces;
1+
using ComputerLock.Interfaces;
72
using ComputerLock.Update;
83
using JiuLing.TitleBarKit;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using MudBlazor.Services;
96
using MudExtensions.Services;
7+
using System.Globalization;
8+
using System.IO;
9+
using System.Windows;
1010
using Application = System.Windows.Application;
1111

1212
namespace ComputerLock;
@@ -17,8 +17,11 @@ public partial class App : Application
1717
{
1818
private static Mutex _mutex = default!;
1919
private WindowMain? _mainWindow;
20+
private ILogger _logger;
2021
protected override void OnStartup(StartupEventArgs e)
2122
{
23+
base.OnStartup(e);
24+
2225
_mutex = new Mutex(true, AppBase.FriendlyName);
2326
if (!_mutex.WaitOne(0, false))
2427
{
@@ -30,7 +33,6 @@ protected override void OnStartup(StartupEventArgs e)
3033
Environment.CurrentDirectory = Path.GetDirectoryName(AppBase.ExecutablePath);
3134

3235
Init();
33-
base.OnStartup(e);
3436
}
3537

3638
private void Init()
@@ -96,11 +98,36 @@ private void Init()
9698
System.Windows.Media.RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
9799
}
98100

101+
_logger = sp.GetRequiredService<ILogger>();
102+
// 确保 HotkeyHook 已被创建
103+
sp.GetRequiredService<HotkeyHook>();
104+
KeepMessageLive();
105+
99106
_mainWindow = sp.GetRequiredService<WindowMain>();
100107
Application.Current.MainWindow = _mainWindow;
101108
_mainWindow.Show();
102109
}
103110

111+
private void KeepMessageLive()
112+
{
113+
// 启动后台消息循环,防止主线程被挂起
114+
Task.Run(() =>
115+
{
116+
try
117+
{
118+
while (WinApi.GetMessage(out var msg, IntPtr.Zero, 0, 0))
119+
{
120+
WinApi.TranslateMessage(ref msg);
121+
WinApi.DispatchMessage(ref msg);
122+
}
123+
}
124+
catch (Exception ex)
125+
{
126+
_logger.Error("热键消息保活服务异常", ex);
127+
}
128+
});
129+
}
130+
104131
protected override void OnExit(ExitEventArgs e)
105132
{
106133
_mainWindow?.Dispose();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace ComputerLock.Interfaces;
22

3-
internal interface IWindowsMessageBox
3+
public interface IWindowsMessageBox
44
{
55
void Show(string message);
66
}

src/ComputerLock/Platforms/WinApi.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,26 @@ public struct LUID_AND_ATTRIBUTES
146146
public const uint SE_PRIVILEGE_ENABLED = 0x00000002;
147147

148148
#endregion
149+
150+
#region 消息相关
151+
[StructLayout(LayoutKind.Sequential)]
152+
public struct ApiMessage
153+
{
154+
public IntPtr hwnd;
155+
public uint message;
156+
public IntPtr wParam;
157+
public IntPtr lParam;
158+
public uint time;
159+
public Point pt;
160+
}
161+
162+
[DllImport("user32.dll")]
163+
public static extern bool GetMessage(out ApiMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
164+
165+
[DllImport("user32.dll")]
166+
public static extern bool TranslateMessage([In] ref ApiMessage lpMsg);
167+
168+
[DllImport("user32.dll")]
169+
public static extern IntPtr DispatchMessage([In] ref ApiMessage lpMsg);
170+
#endregion
149171
}

src/ComputerLock/Shared/MainLayout.razor.cs

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using JiuLing.TitleBarKit;
44

55
namespace ComputerLock.Shared;
6+
67
public partial class MainLayout
78
{
89
private bool _isDarkMode;
@@ -31,9 +32,6 @@ public partial class MainLayout
3132
[Inject]
3233
private IGlobalLockService GlobalLockService { get; set; } = null!;
3334

34-
[Inject]
35-
private HotkeyHook HotkeyHook { get; set; } = null!;
36-
3735
[Inject]
3836
private ILogger Logger { get; set; } = null!;
3937

@@ -144,39 +142,6 @@ private void InitializeEventBinding()
144142
}
145143
_isInitialized = true;
146144

147-
if (AppSettings.LockHotkeyString.IsNotEmpty())
148-
{
149-
RegisterLockHotkey();
150-
}
151-
152-
HotkeyHook.HotkeyPressed += (id) =>
153-
{
154-
if (id == (int)HotkeyType.Lock)
155-
{
156-
if (!GlobalLockService.IsLocked)
157-
{
158-
Logger.Info("快捷键锁定");
159-
GlobalLockService.Lock();
160-
}
161-
else
162-
{
163-
if (AppSettings.ScreenUnlockMethod == ScreenUnlockMethods.Hotkey && AppSettings.IsUnlockUseLockHotkey)
164-
{
165-
Logger.Info("快捷键解锁");
166-
GlobalLockService.Unlock();
167-
}
168-
}
169-
}
170-
else if (id == (int)HotkeyType.Unlock)
171-
{
172-
if (GlobalLockService.IsLocked)
173-
{
174-
Logger.Info("快捷键解锁(独立解锁)");
175-
GlobalLockService.Unlock();
176-
}
177-
}
178-
};
179-
180145
ThemeSwitchService.OnThemeChanged += async theme =>
181146
{
182147
await SwitchThemeAsync(theme);
@@ -194,20 +159,5 @@ private async Task OpenDonationDialog()
194159
await Dialog.ShowAsync<Donation>("", options);
195160
}
196161

197-
public void RegisterLockHotkey()
198-
{
199-
try
200-
{
201-
if (AppSettings.LockHotkey != null)
202-
{
203-
Logger.Info("注册锁屏热键");
204-
HotkeyHook.Register((int)HotkeyType.Lock, AppSettings.LockHotkey);
205-
}
206-
}
207-
catch (Exception ex)
208-
{
209-
Logger.Error($"绑定锁屏热键失败", ex);
210-
Snackbar.Add($"{Lang["ExRegistFailed"]}{ex.Message}", Severity.Error);
211-
}
212-
}
162+
213163
}

src/ComputerLock/WindowMain.xaml.cs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,72 @@
33
using ComputerLock.Interfaces;
44

55
namespace ComputerLock;
6+
67
public partial class WindowMain : Window, IDisposable
78
{
89
private readonly AppSettings _appSettings;
910
private readonly IGlobalLockService _globalLockService;
1011
private readonly ILogger _logger;
12+
private readonly HotkeyHook _hotkeyHook;
13+
private readonly IStringLocalizer<Lang> _lang;
14+
private readonly IWindowsMessageBox _windowsMessageBox;
1115

1216
private readonly NotifyIcon _notifyIcon = new();
1317
private readonly ContextMenuStrip _contextMenuStrip = new();
1418

15-
public WindowMain(AppSettings appSettings, IGlobalLockService globalLockService, ILogger logger)
19+
public WindowMain(AppSettings appSettings, IGlobalLockService globalLockService, ILogger logger, HotkeyHook hotkeyHook, IStringLocalizer<Lang> lang, IWindowsMessageBox windowsMessageBox)
1620
{
1721
InitializeComponent();
1822

1923
_appSettings = appSettings;
2024
_globalLockService = globalLockService;
2125
_logger = logger;
26+
_hotkeyHook = hotkeyHook;
27+
_lang = lang;
28+
_windowsMessageBox = windowsMessageBox;
2229

2330
InitializeNotifyIcon();
31+
2432
_logger.Info("系统启动");
2533

34+
if (_appSettings.LockHotkeyString.IsNotEmpty())
35+
{
36+
RegisterLockHotkey();
37+
}
38+
_hotkeyHook.HotkeyPressed += (id) =>
39+
{
40+
if (id == (int)HotkeyType.Lock)
41+
{
42+
if (!_globalLockService.IsLocked)
43+
{
44+
_logger.Info("快捷键锁定");
45+
_globalLockService.Lock();
46+
}
47+
else
48+
{
49+
if (_appSettings.ScreenUnlockMethod == ScreenUnlockMethods.Hotkey && _appSettings.IsUnlockUseLockHotkey)
50+
{
51+
_logger.Info("快捷键解锁");
52+
_globalLockService.Unlock();
53+
}
54+
}
55+
}
56+
else if (id == (int)HotkeyType.Unlock)
57+
{
58+
if (_globalLockService.IsLocked)
59+
{
60+
_logger.Info("快捷键解锁(独立解锁)");
61+
_globalLockService.Unlock();
62+
}
63+
}
64+
};
65+
2666
if (_appSettings.LockOnStartup)
2767
{
2868
_logger.Info("程序启动时锁定屏幕");
2969
_globalLockService.Lock();
3070
}
71+
3172
}
3273

3374
private void Window_Loaded(object sender, RoutedEventArgs e)
@@ -109,6 +150,23 @@ private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
109150
}
110151
}
111152
}
153+
154+
private void RegisterLockHotkey()
155+
{
156+
try
157+
{
158+
if (_appSettings.LockHotkey != null)
159+
{
160+
_logger.Info("注册锁屏热键");
161+
_hotkeyHook.Register((int)HotkeyType.Lock, _appSettings.LockHotkey);
162+
}
163+
}
164+
catch (Exception ex)
165+
{
166+
_logger.Error($"绑定锁屏热键失败", ex);
167+
_windowsMessageBox.Show($"{_lang["ExRegistFailed"]}{ex.Message}");
168+
}
169+
}
112170
public void Dispose()
113171
{
114172
_logger.Info("系统资源释放,系统关闭");

0 commit comments

Comments
 (0)