@@ -12,34 +12,82 @@ public sealed class HotkeyManager : IDisposable
1212 private const int MOD_CONTROL = 0x0002 ;
1313 private const int MOD_SHIFT = 0x0001 ;
1414 private const int VK_RIGHT = 0x27 ;
15- private static readonly int HotkeyId = 1 ;
15+ private const int VK_LEFT = 0x25 ;
16+ private const int HotkeyIdPass = 1 ;
17+ private const int HotkeyIdTakeBack = 2 ;
1618
1719 private nint _hwnd ;
18- private bool _registered ;
20+ private bool _registeredPass ;
21+ private bool _registeredTakeBack ;
1922
20- [ DllImport ( "user32.dll" ) ]
23+ [ DllImport ( "user32.dll" , SetLastError = true ) ]
2124 private static extern bool RegisterHotKey ( nint hWnd , int id , uint fsModifiers , uint vk ) ;
2225
2326 [ DllImport ( "user32.dll" ) ]
2427 private static extern bool UnregisterHotKey ( nint hWnd , int id ) ;
2528
29+ public event Action < string > ? HotkeyConflict ;
30+
2631 public void Register ( nint windowHandle )
2732 {
2833 _hwnd = windowHandle ;
29- _registered = RegisterHotKey ( _hwnd , HotkeyId , ( uint ) ( MOD_CONTROL | MOD_SHIFT ) , VK_RIGHT ) ;
34+ _registeredPass = false ;
35+ _registeredTakeBack = false ;
36+
37+ if ( RegisterHotKey ( _hwnd , HotkeyIdPass , ( uint ) ( MOD_CONTROL | MOD_SHIFT ) , VK_RIGHT ) )
38+ {
39+ _registeredPass = true ;
40+ }
41+ else
42+ {
43+ var err = System . Runtime . InteropServices . Marshal . GetLastWin32Error ( ) ;
44+ HotkeyConflict ? . Invoke ( $ "Hotkey conflict detected — Ctrl+Shift+→ is in use (err={ err } ).") ;
45+ }
46+
47+ if ( RegisterHotKey ( _hwnd , HotkeyIdTakeBack , ( uint ) ( MOD_CONTROL | MOD_SHIFT ) , VK_LEFT ) )
48+ {
49+ _registeredTakeBack = true ;
50+ }
51+ else
52+ {
53+ var err = System . Runtime . InteropServices . Marshal . GetLastWin32Error ( ) ;
54+ HotkeyConflict ? . Invoke ( $ "Hotkey conflict detected — Ctrl+Shift+← is in use (err={ err } ).") ;
55+ }
3056 }
3157
3258 public void Unregister ( )
3359 {
34- if ( _registered && _hwnd != nint . Zero )
60+ if ( _hwnd == nint . Zero ) return ;
61+ if ( _registeredPass )
62+ {
63+ UnregisterHotKey ( _hwnd , HotkeyIdPass ) ;
64+ _registeredPass = false ;
65+ }
66+ if ( _registeredTakeBack )
67+ {
68+ UnregisterHotKey ( _hwnd , HotkeyIdTakeBack ) ;
69+ _registeredTakeBack = false ;
70+ }
71+ if ( ! _registeredPass && ! _registeredTakeBack )
3572 {
36- UnregisterHotKey ( _hwnd , HotkeyId ) ;
37- _registered = false ;
73+ // nothing
3874 }
3975 }
4076
41- public static bool IsHotkeyMessage ( int msg , nint wParam ) =>
42- msg == WM_HOTKEY && wParam == ( nint ) HotkeyId ;
77+ public static bool TryGetHotkey ( int msg , nint wParam , out HotkeyKind kind )
78+ {
79+ kind = HotkeyKind . Pass ;
80+ if ( msg != WM_HOTKEY ) return false ;
81+ if ( wParam == ( nint ) HotkeyIdPass ) { kind = HotkeyKind . Pass ; return true ; }
82+ if ( wParam == ( nint ) HotkeyIdTakeBack ) { kind = HotkeyKind . TakeBack ; return true ; }
83+ return false ;
84+ }
85+
86+ public enum HotkeyKind
87+ {
88+ Pass ,
89+ TakeBack
90+ }
4391
4492 public void Dispose ( ) => Unregister ( ) ;
4593}
0 commit comments