1+ using System . Runtime . InteropServices ;
2+ using System . Windows ;
3+ using System . Windows . Input ;
4+ using System . Windows . Interop ;
5+
6+ namespace Upsilon . Apps . Passkey . GUI . WPF . Helper
7+ {
8+ public static class HotkeyHelper
9+ {
10+ private static int _id = 0 ;
11+
12+ public static event EventHandler < HotkeyEventArgs > ? HotkeyPressed ;
13+
14+ public static int Register ( Window window , ModifierKeys modifiers , Key key )
15+ {
16+ int hotkeyId = Interlocked . Increment ( ref _id ) ;
17+ uint virtualKey = ( uint ) KeyInterop . VirtualKeyFromKey ( key ) ;
18+
19+ IntPtr hWnd = new WindowInteropHelper ( window ) . Handle ;
20+ if ( hWnd == IntPtr . Zero )
21+ return - 1 ;
22+
23+ bool success = RegisterHotKey ( hWnd , hotkeyId , ( uint ) modifiers , virtualKey ) ;
24+ if ( ! success )
25+ return - 1 ;
26+
27+ if ( PresentationSource . FromVisual ( window ) is HwndSource source )
28+ {
29+ source . AddHook ( ( hwnd , msg , wParam , lParam , ref handled ) =>
30+ {
31+ if ( msg == 0x0312 && ( int ) wParam == hotkeyId )
32+ {
33+ HotkeyEventArgs e = new ( lParam ) ;
34+ HotkeyPressed ? . Invoke ( window , e ) ;
35+ handled = true;
36+ }
37+ return IntPtr . Zero;
38+ } ) ;
39+ }
40+
41+ return hotkeyId ;
42+ }
43+
44+ public static bool Unregister ( Window window , int hotkeyId )
45+ {
46+ if ( window is null )
47+ return false ;
48+
49+ IntPtr hWnd = new WindowInteropHelper ( window ) . Handle ;
50+ return hWnd != nint . Zero && UnregisterHotKey ( hWnd , hotkeyId ) ;
51+ }
52+
53+ public static void Send ( ModifierKeys modifiers , Key key )
54+ {
55+ //byte[] modifiers = [];
56+ byte virtualKey = ( byte ) KeyInterop . VirtualKeyFromKey ( key ) ;
57+
58+ keybd_event ( ( byte ) modifiers , 0 , 0 , UIntPtr . Zero ) ;
59+
60+ keybd_event ( virtualKey , 0 , 0 , UIntPtr . Zero ) ;
61+ keybd_event ( virtualKey , 0 , 0x0002 , UIntPtr . Zero ) ;
62+
63+ keybd_event ( ( byte ) modifiers , 0 , 0x0002 , UIntPtr . Zero ) ;
64+ }
65+
66+ [ DllImport ( "user32.dll" ) ]
67+ private static extern bool RegisterHotKey ( IntPtr hWnd , int id , uint fsModifiers , uint vk ) ;
68+
69+ [ DllImport ( "user32.dll" ) ]
70+ private static extern bool UnregisterHotKey ( IntPtr hWnd , int id ) ;
71+
72+ [ DllImport ( "user32.dll" ) ]
73+ private static extern uint MapVirtualKey ( uint uCode , uint uMapType ) ;
74+
75+ [ DllImport ( "user32.dll" ) ]
76+ private static extern void keybd_event ( byte bVk , byte bScan , uint dwFlags , UIntPtr dwExtraInfo ) ;
77+ }
78+
79+ public class HotkeyEventArgs : EventArgs
80+ {
81+ public readonly Key Key ;
82+ public readonly ModifierKeys Modifiers ;
83+
84+ internal HotkeyEventArgs ( IntPtr hotKeyParam )
85+ {
86+ uint param = ( uint ) hotKeyParam . ToInt64 ( ) ;
87+ int virtualKey = ( int ) ( ( param & 0xffff0000 ) >> 16 ) ;
88+ Key = KeyInterop . KeyFromVirtualKey ( virtualKey ) ;
89+ Modifiers = ( ModifierKeys ) ( param & 0x0000ffff ) ;
90+ }
91+ }
92+ }
0 commit comments