2020-07-23 07:55:04 +08:00
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
2020-10-08 23:45:09 +08:00
using System ;
2020-10-23 00:45:48 +08:00
using System.Diagnostics.CodeAnalysis ;
2020-06-12 03:59:36 +08:00
using interop ;
2020-10-23 00:45:48 +08:00
namespace Microsoft.PowerToys.Settings.UI.Library
2020-06-12 03:59:36 +08:00
{
public delegate void KeyEvent ( int key ) ;
2020-06-24 08:19:36 +08:00
2020-06-12 03:59:36 +08:00
public delegate bool IsActive ( ) ;
2020-10-08 23:45:09 +08:00
public delegate bool FilterAccessibleKeyboardEvents ( int key , UIntPtr extraInfo ) ;
2020-10-20 04:32:05 +08:00
public class HotkeySettingsControlHook : IDisposable
2020-06-12 03:59:36 +08:00
{
2020-07-24 04:08:20 +08:00
private const int WmKeyDown = 0x100 ;
private const int WmKeyUp = 0x101 ;
private const int WmSysKeyDown = 0x0104 ;
private const int WmSysKeyUp = 0x0105 ;
2020-06-12 03:59:36 +08:00
2020-10-23 00:45:48 +08:00
[SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "This class conforms to the IDisposable pattern, and the Dispose and C++ destructor does get called when debugging. Looks like a false positive from FxCop.")]
2020-07-24 04:08:20 +08:00
private KeyboardHook _hook ;
private KeyEvent _keyDown ;
private KeyEvent _keyUp ;
private IsActive _isActive ;
2020-10-20 04:32:05 +08:00
private bool disposedValue ;
2020-06-12 03:59:36 +08:00
2020-10-08 23:45:09 +08:00
private FilterAccessibleKeyboardEvents _filterKeyboardEvent ;
public HotkeySettingsControlHook ( KeyEvent keyDown , KeyEvent keyUp , IsActive isActive , FilterAccessibleKeyboardEvents filterAccessibleKeyboardEvents )
2020-06-12 03:59:36 +08:00
{
2020-07-24 04:08:20 +08:00
_keyDown = keyDown ;
_keyUp = keyUp ;
_isActive = isActive ;
2020-10-08 23:45:09 +08:00
_filterKeyboardEvent = filterAccessibleKeyboardEvents ;
_hook = new KeyboardHook ( HotkeySettingsHookCallback , IsActive , FilterKeyboardEvents ) ;
2020-07-24 04:08:20 +08:00
_hook . Start ( ) ;
2020-06-12 03:59:36 +08:00
}
private bool IsActive ( )
{
2020-07-24 04:08:20 +08:00
return _isActive ( ) ;
2020-06-12 03:59:36 +08:00
}
private void HotkeySettingsHookCallback ( KeyboardEvent ev )
{
switch ( ev . message )
{
2020-07-24 04:08:20 +08:00
case WmKeyDown :
case WmSysKeyDown :
_keyDown ( ev . key ) ;
2020-06-12 03:59:36 +08:00
break ;
2020-07-24 04:08:20 +08:00
case WmKeyUp :
case WmSysKeyUp :
_keyUp ( ev . key ) ;
2020-06-12 03:59:36 +08:00
break ;
}
}
2020-06-24 08:19:36 +08:00
2020-10-08 23:45:09 +08:00
private bool FilterKeyboardEvents ( KeyboardEvent ev )
{
return _filterKeyboardEvent ( ev . key , ( UIntPtr ) ev . dwExtraInfo ) ;
}
2020-10-20 04:32:05 +08:00
protected virtual void Dispose ( bool disposing )
{
if ( ! disposedValue )
{
if ( disposing )
{
// Dispose the KeyboardHook object to terminate the hook threads
_hook . Dispose ( ) ;
}
disposedValue = true ;
}
}
2020-06-24 08:19:36 +08:00
public void Dispose ( )
{
2020-10-20 04:32:05 +08:00
Dispose ( disposing : true ) ;
GC . SuppressFinalize ( this ) ;
2020-06-24 08:19:36 +08:00
}
2020-06-12 03:59:36 +08:00
}
}