1+ using System ;
2+ using System . Runtime . InteropServices ;
3+ using System . Windows ;
4+ using System . Windows . Forms ;
5+ using System . Windows . Interop ;
6+
7+ namespace CSharpRegexTools4Npp . PluginInfrastructure
8+ {
9+ public class KeyboardHookManager
10+ {
11+ private const int WH_KEYBOARD_LL = 13 ;
12+ private const int WM_KEYDOWN = 0x0100 ;
13+ private const int WM_SYSKEYDOWN = 0x0104 ;
14+
15+ private static IntPtr _hookID = IntPtr . Zero ;
16+ private static Window _targetWindow ;
17+ private static LowLevelKeyboardProc _proc ;
18+ private static bool _isHookInstalled = false ;
19+
20+ public static event EventHandler < KeyPressedEventArgs > KeyPressed ;
21+
22+ public static void Initialize ( Window window )
23+ {
24+ _targetWindow = window ;
25+ _proc = HookCallback ;
26+
27+ // S'abonner aux événements de focus de la fenêtre
28+ window . Activated += Window_Activated ;
29+ window . Deactivated += Window_Deactivated ;
30+ }
31+
32+ private static void Window_Activated ( object sender , EventArgs e )
33+ {
34+ InstallHook ( ) ;
35+ }
36+
37+ private static void Window_Deactivated ( object sender , EventArgs e )
38+ {
39+ UninstallHook ( ) ;
40+ }
41+
42+ private static void InstallHook ( )
43+ {
44+ if ( ! _isHookInstalled )
45+ {
46+ _hookID = SetHook ( _proc ) ;
47+ _isHookInstalled = true ;
48+ }
49+ }
50+
51+ private static void UninstallHook ( )
52+ {
53+ if ( _isHookInstalled )
54+ {
55+ UnhookWindowsHookEx ( _hookID ) ;
56+ _isHookInstalled = false ;
57+ }
58+ }
59+
60+ private static IntPtr SetHook ( LowLevelKeyboardProc proc )
61+ {
62+ using ( var curProcess = System . Diagnostics . Process . GetCurrentProcess ( ) )
63+ using ( var curModule = curProcess . MainModule )
64+ {
65+ return SetWindowsHookEx ( WH_KEYBOARD_LL , proc ,
66+ GetModuleHandle ( curModule . ModuleName ) , 0 ) ;
67+ }
68+ }
69+
70+ private delegate IntPtr LowLevelKeyboardProc ( int nCode , IntPtr wParam , IntPtr lParam ) ;
71+
72+ private static IntPtr HookCallback ( int nCode , IntPtr wParam , IntPtr lParam )
73+ {
74+ if ( nCode >= 0 )
75+ {
76+ var windowHandle = GetForegroundWindow ( ) ;
77+ var activeWindow = HwndSource . FromHwnd ( windowHandle ) ? . RootVisual as Window ;
78+
79+ // Vérifier si la fenêtre active est notre fenêtre cible
80+ if ( activeWindow == _targetWindow )
81+ {
82+ if ( ( wParam == ( IntPtr ) WM_KEYDOWN ) || ( wParam == ( IntPtr ) WM_SYSKEYDOWN ) )
83+ {
84+ int vkCode = Marshal . ReadInt32 ( lParam ) ;
85+ bool isCtrlPressed = ( GetKeyState ( VK_CONTROL ) & 0x8000 ) != 0 ;
86+ bool isAltPressed = ( GetKeyState ( VK_MENU ) & 0x8000 ) != 0 ;
87+ bool isShiftPressed = ( GetKeyState ( VK_SHIFT ) & 0x8000 ) != 0 ;
88+
89+ var args = new KeyPressedEventArgs (
90+ ( Keys ) vkCode ,
91+ isCtrlPressed ,
92+ isAltPressed ,
93+ isShiftPressed
94+ ) ;
95+
96+ KeyPressed ? . Invoke ( null , args ) ;
97+
98+ // Si l'événement a été géré, on empêche sa propagation
99+ if ( args . Handled )
100+ {
101+ return ( IntPtr ) 1 ;
102+ }
103+ }
104+ }
105+ }
106+ return CallNextHookEx ( _hookID , nCode , wParam , lParam ) ;
107+ }
108+
109+ private const int VK_CONTROL = 0x11 ;
110+ private const int VK_MENU = 0x12 ; // ALT
111+ private const int VK_SHIFT = 0x10 ;
112+
113+ [ DllImport ( "user32.dll" ) ]
114+ private static extern IntPtr GetForegroundWindow ( ) ;
115+
116+ [ DllImport ( "user32.dll" ) ]
117+ private static extern short GetKeyState ( int nVirtKey ) ;
118+
119+ [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , SetLastError = true ) ]
120+ private static extern IntPtr SetWindowsHookEx ( int idHook , LowLevelKeyboardProc lpfn ,
121+ IntPtr hMod , uint dwThreadId ) ;
122+
123+ [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , SetLastError = true ) ]
124+ private static extern bool UnhookWindowsHookEx ( IntPtr hhk ) ;
125+
126+ [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , SetLastError = true ) ]
127+ private static extern IntPtr CallNextHookEx ( IntPtr hhk , int nCode ,
128+ IntPtr wParam , IntPtr lParam ) ;
129+
130+ [ DllImport ( "kernel32.dll" , CharSet = CharSet . Auto , SetLastError = true ) ]
131+ private static extern IntPtr GetModuleHandle ( string lpModuleName ) ;
132+ }
133+
134+ public class KeyPressedEventArgs : EventArgs
135+ {
136+ public Keys Key { get ; private set ; }
137+ public bool Control { get ; private set ; }
138+ public bool Alt { get ; private set ; }
139+ public bool Shift { get ; private set ; }
140+ public bool Handled { get ; set ; }
141+
142+ public KeyPressedEventArgs ( Keys key , bool control , bool alt , bool shift )
143+ {
144+ Key = key ;
145+ Control = control ;
146+ Alt = alt ;
147+ Shift = shift ;
148+ Handled = false ;
149+ }
150+ }
151+ }
0 commit comments