10
10
using Windows . Win32 . UI . WindowsAndMessaging ;
11
11
using CommunityToolkit . Mvvm . Input ;
12
12
using Microsoft . Extensions . Logging ;
13
+ using Microsoft . Extensions . Options ;
13
14
using PropertyChanged . SourceGenerator ;
14
15
using WinSyncScroll . Enums ;
15
16
using WinSyncScroll . Extensions ;
@@ -24,6 +25,7 @@ namespace WinSyncScroll.ViewModels;
24
25
public sealed partial class MainViewModel : IDisposable
25
26
{
26
27
private readonly ILogger < MainViewModel > _logger ;
28
+ private readonly IOptions < GeneralOptions > _options ;
27
29
private readonly WinApiService _winApiService ;
28
30
private readonly MouseHook _mouseHook ;
29
31
@@ -79,12 +81,16 @@ public sealed partial class MainViewModel : IDisposable
79
81
private int _smCxScreen ;
80
82
private int _smCyScreen ;
81
83
84
+ private static readonly int SizeOfInput = Marshal . SizeOf ( typeof ( INPUT ) ) ;
85
+
82
86
public MainViewModel (
83
87
ILogger < MainViewModel > logger ,
88
+ IOptions < GeneralOptions > options ,
84
89
WinApiService winApiService ,
85
90
MouseHook mouseHook )
86
91
{
87
92
_logger = logger ;
93
+ _options = options ;
88
94
_winApiService = winApiService ;
89
95
_mouseHook = mouseHook ;
90
96
@@ -166,9 +172,16 @@ private static Point CalculateCenterOfWindow(WindowRect rect)
166
172
rect . Top + ( ( rect . Bottom - rect . Top ) / 2 ) ) ;
167
173
}
168
174
169
- // protection is disabled because MS Word reports a different process ID for the window
170
- [ SuppressMessage ( "Performance" , "CA1802:Use literals where appropriate" , Justification = "This is an option" ) ]
171
- private static readonly bool IsStrictProcessIdCheckEnabled = false ;
175
+ private void LogSendInput ( INPUT [ ] inputs )
176
+ {
177
+ _logger . LogTrace ( "Sending input to target window: {NewLine}{Inputs}" ,
178
+ Environment . NewLine ,
179
+ string . Join (
180
+ Environment . NewLine ,
181
+ inputs . Select ( ( item , index ) =>
182
+ $ "{ index . ToStringInvariant ( ) } : { item . ToLogString ( ) } ") )
183
+ ) ;
184
+ }
172
185
173
186
private async Task RunMouseEventProcessingLoopAsync (
174
187
Channel < MouseMessageInfo > channel ,
@@ -224,7 +237,7 @@ private async Task RunMouseEventProcessingLoopAsync(
224
237
continue ;
225
238
}
226
239
227
- if ( IsStrictProcessIdCheckEnabled )
240
+ if ( _options . Value . IsStrictProcessIdCheckEnabled )
228
241
{
229
242
var actualSourceWindowHwnd = PInvoke . WindowFromPoint ( new Point ( sourceEventX , sourceEventY ) ) ;
230
243
var ( _, actualSourceProcessId , _) = PInvoke . GetWindowThreadProcessId ( actualSourceWindowHwnd ) ;
@@ -250,7 +263,7 @@ private async Task RunMouseEventProcessingLoopAsync(
250
263
targetY = centerOfTarget . Y ;
251
264
}
252
265
253
- if ( IsStrictProcessIdCheckEnabled )
266
+ if ( _options . Value . IsStrictProcessIdCheckEnabled )
254
267
{
255
268
var actualTargetWindowHwnd = PInvoke . WindowFromPoint ( new Point ( targetX , targetY ) ) ;
256
269
var ( _, actualTargetWindowProcessId , _) = PInvoke . GetWindowThreadProcessId ( actualTargetWindowHwnd ) ;
@@ -285,18 +298,23 @@ private async Task RunMouseEventProcessingLoopAsync(
285
298
var inputMoveToSource = CreateMoveInput ( sourceAbsoluteX , sourceAbsoluteY ) ;
286
299
287
300
var inputs = new [ ] { inputMoveToTarget , inputScrollTarget , inputMoveToSource } ;
288
- var sizeOfInput = Marshal . SizeOf ( typeof ( INPUT ) ) ;
289
301
290
302
_mouseHook . SetPreventRealScrollEvents ( ) ;
291
303
292
- _logger . LogTrace ( "Sending input to target window: {NewLine}{Inputs}" ,
293
- Environment . NewLine ,
294
- string . Join (
295
- Environment . NewLine ,
296
- inputs . Select ( ( item , index ) =>
297
- $ "{ index . ToStringInvariant ( ) } : { item . ToLogString ( ) } ") )
298
- ) ;
299
- PInvoke . SendInput ( inputs . AsSpan ( ) , sizeOfInput ) ;
304
+ LogSendInput ( inputs ) ;
305
+
306
+ if ( _options . Value . InputDelay == 0 )
307
+ {
308
+ PInvoke . SendInput ( inputs . AsSpan ( ) , SizeOfInput ) ;
309
+ }
310
+ else
311
+ {
312
+ PInvoke . SendInput ( inputs . AsSpan ( ) . Slice ( 0 , 1 ) , SizeOfInput ) ;
313
+ await Task . Delay ( _options . Value . InputDelay , cancellationToken ) ;
314
+ PInvoke . SendInput ( inputs . AsSpan ( ) . Slice ( 1 , 1 ) , SizeOfInput ) ;
315
+ await Task . Delay ( _options . Value . InputDelay , cancellationToken ) ;
316
+ PInvoke . SendInput ( inputs . AsSpan ( ) . Slice ( 2 , 1 ) , SizeOfInput ) ;
317
+ }
300
318
}
301
319
catch ( Exception e )
302
320
{
0 commit comments