3
3
using System . ComponentModel ;
4
4
using System . Diagnostics ;
5
5
using System . Linq ;
6
- using System . Runtime . InteropServices ;
7
- using System . Windows . Forms ;
8
6
using Rubberduck . Common . Hotkeys ;
9
7
using Rubberduck . Common . WinAPI ;
10
8
using Rubberduck . Settings ;
11
9
using Rubberduck . UI . Command ;
12
10
using NLog ;
13
11
using Rubberduck . VBEditor . SafeComWrappers . Abstract ;
12
+ using Rubberduck . VBEditor . WindowsApi ;
14
13
15
14
namespace Rubberduck . Common
16
15
{
17
- public class RubberduckHooks : IRubberduckHooks
16
+ public class RubberduckHooks : SubclassingWindow , IRubberduckHooks
18
17
{
19
- private readonly IntPtr _mainWindowHandle ;
20
- private readonly IntPtr _oldWndProc ;
21
- // This can't be local - otherwise RawInput can't call it in the subclassing chain.
22
- // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
23
- private readonly User32 . WndProc _newWndProc ;
24
- private RawInput _rawinput ;
25
- private RawKeyboard _kb ;
26
- private RawMouse _mouse ;
27
18
private readonly IGeneralConfigService _config ;
28
19
private readonly IEnumerable < CommandBase > _commands ;
29
20
private readonly IList < IAttachable > _hooks = new List < IAttachable > ( ) ;
30
21
private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
31
22
32
23
public RubberduckHooks ( IVBE vbe , IGeneralConfigService config , IEnumerable < CommandBase > commands )
24
+ : base ( ( IntPtr ) vbe . MainWindow . HWnd , ( IntPtr ) vbe . MainWindow . HWnd )
33
25
{
34
- var mainWindow = vbe . MainWindow ;
35
- {
36
- _mainWindowHandle = ( IntPtr ) mainWindow . HWnd ;
37
- }
38
-
39
- _newWndProc = WindowProc ;
40
- _oldWndProc = User32 . SetWindowLong ( _mainWindowHandle , ( int ) WindowLongFlags . GWL_WNDPROC , Marshal . GetFunctionPointerForDelegate ( _newWndProc ) ) ;
41
-
42
26
_commands = commands ;
43
27
_config = config ;
44
28
}
@@ -56,18 +40,6 @@ public void HookHotkeys()
56
40
var config = _config . LoadConfiguration ( ) ;
57
41
var settings = config . UserSettings . HotkeySettings ;
58
42
59
- _rawinput = new RawInput ( _mainWindowHandle ) ;
60
-
61
- var kb = ( RawKeyboard ) _rawinput . CreateKeyboard ( ) ;
62
- _rawinput . AddDevice ( kb ) ;
63
- kb . RawKeyInputReceived += Keyboard_RawKeyboardInputReceived ;
64
- _kb = kb ;
65
-
66
- var mouse = ( RawMouse ) _rawinput . CreateMouse ( ) ;
67
- _rawinput . AddDevice ( mouse ) ;
68
- mouse . RawMouseInputReceived += Mouse_RawMouseInputReceived ;
69
- _mouse = mouse ;
70
-
71
43
foreach ( var hotkey in settings . Settings . Where ( hotkey => hotkey . IsEnabled ) )
72
44
{
73
45
RubberduckHotkey assigned ;
@@ -76,35 +48,12 @@ public void HookHotkeys()
76
48
var command = Command ( assigned ) ;
77
49
Debug . Assert ( command != null ) ;
78
50
79
- AddHook ( new Hotkey ( _mainWindowHandle , hotkey . ToString ( ) , command ) ) ;
51
+ AddHook ( new Hotkey ( Hwnd , hotkey . ToString ( ) , command ) ) ;
80
52
}
81
53
}
82
54
Attach ( ) ;
83
55
}
84
56
85
- private void Mouse_RawMouseInputReceived ( object sender , RawMouseEventArgs e )
86
- {
87
- if ( e . UlButtons . HasFlag ( UsButtonFlags . RI_MOUSE_LEFT_BUTTON_UP ) || e . UlButtons . HasFlag ( UsButtonFlags . RI_MOUSE_RIGHT_BUTTON_UP ) )
88
- {
89
- OnMessageReceived ( this , HookEventArgs . Empty ) ;
90
- }
91
- }
92
-
93
- // keys that change the current selection.
94
- private static readonly HashSet < Keys > NavKeys = new HashSet < Keys >
95
- {
96
- Keys . Up , Keys . Down , Keys . Left , Keys . Right , Keys . PageDown , Keys . PageUp , Keys . Enter
97
- } ;
98
-
99
- private void Keyboard_RawKeyboardInputReceived ( object sender , RawKeyEventArgs e )
100
- {
101
- // note: handling *all* keys causes annoying RTrim of current line, making editing code a PITA.
102
- if ( e . Message == WM . KEYUP && NavKeys . Contains ( ( Keys ) e . VKey ) )
103
- {
104
- OnMessageReceived ( this , HookEventArgs . Empty ) ;
105
- }
106
- }
107
-
108
57
public IEnumerable < IAttachable > Hooks { get { return _hooks ; } }
109
58
110
59
public void AddHook ( IAttachable hook )
@@ -182,60 +131,41 @@ private void hook_MessageReceived(object sender, HookEventArgs e)
182
131
OnMessageReceived ( sender , e ) ;
183
132
}
184
133
185
- public void Dispose ( )
186
- {
187
- Detach ( ) ;
188
- User32 . SetWindowLong ( _mainWindowHandle , ( int ) WindowLongFlags . GWL_WNDPROC , _oldWndProc ) ;
189
- _mouse . RawMouseInputReceived -= Mouse_RawMouseInputReceived ;
190
- _kb . RawKeyInputReceived -= Keyboard_RawKeyboardInputReceived ;
191
- }
192
-
193
- private IntPtr WindowProc ( IntPtr hWnd , uint uMsg , IntPtr wParam , IntPtr lParam )
134
+ public override int SubClassProc ( IntPtr hWnd , IntPtr msg , IntPtr wParam , IntPtr lParam , IntPtr uIdSubclass , IntPtr dwRefData )
194
135
{
195
- try
196
- {
197
- var suppress = false ;
198
- switch ( ( WM ) uMsg )
199
- {
200
- case WM . HOTKEY :
201
- suppress = hWnd == _mainWindowHandle && HandleHotkeyMessage ( wParam ) ;
202
- break ;
203
- case WM . SETFOCUS :
136
+ var suppress = false ;
137
+ switch ( ( WM ) msg )
138
+ {
139
+ case WM . HOTKEY :
140
+ suppress = hWnd == Hwnd && HandleHotkeyMessage ( wParam ) ;
141
+ break ;
142
+ case WM . SETFOCUS :
143
+ Attach ( ) ;
144
+ break ;
145
+ case WM . RUBBERDUCK_CHILD_FOCUS :
146
+ if ( lParam == IntPtr . Zero )
147
+ {
148
+ Detach ( ) ;
149
+ }
150
+ else
151
+ {
204
152
Attach ( ) ;
205
- break ;
206
- case WM . RUBBERDUCK_CHILD_FOCUS :
207
- if ( lParam == IntPtr . Zero )
208
- {
209
- Detach ( ) ;
210
- }
211
- else
212
- {
213
- Attach ( ) ;
214
- }
215
- return IntPtr . Zero ;
216
- case WM . NCACTIVATE :
217
- if ( wParam == IntPtr . Zero )
218
- {
219
- Detach ( ) ;
220
- }
221
- break ;
222
- case WM . CLOSE :
223
- case WM . RUBBERDUCK_SINKING :
224
- suppress = true ;
153
+ }
154
+ suppress = true ;
155
+ break ;
156
+ case WM . NCACTIVATE :
157
+ if ( wParam == IntPtr . Zero )
158
+ {
225
159
Detach ( ) ;
226
- break ;
227
- }
228
-
229
- return suppress
230
- ? IntPtr . Zero
231
- : User32 . CallWindowProc ( _oldWndProc , hWnd , uMsg , wParam , lParam ) ;
232
- }
233
- catch ( Exception exception )
234
- {
235
- Logger . Error ( exception ) ;
236
- }
237
-
238
- return IntPtr . Zero ;
160
+ }
161
+ break ;
162
+ case WM . CLOSE :
163
+ case WM . DESTROY :
164
+ case WM . RUBBERDUCK_SINKING :
165
+ Detach ( ) ;
166
+ break ;
167
+ }
168
+ return suppress ? 0 : base . SubClassProc ( hWnd , msg , wParam , lParam , uIdSubclass , dwRefData ) ;
239
169
}
240
170
241
171
private bool HandleHotkeyMessage ( IntPtr wParam )
0 commit comments