Files
eveo/Eve-O-Preview/Hotkeys/HotkeyHandler.cs
2019-02-25 21:33:49 +02:00

135 lines
3.0 KiB
C#

using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace EveOPreview.UI.Hotkeys
{
class HotkeyHandler : IMessageFilter, IDisposable
{
private static int _currentId;
private const int MaxId = 0xBFFF;
#region Private fields
private readonly int _hotkeyId;
private readonly IntPtr _hotkeyTarget;
#endregion
public HotkeyHandler(IntPtr target, Keys hotkey)
{
this._hotkeyId = HotkeyHandler._currentId;
HotkeyHandler._currentId = (HotkeyHandler._currentId + 1) & HotkeyHandler.MaxId;
this._hotkeyTarget = target;
// Assign properties
this.IsRegistered = false;
this.KeyCode = hotkey;
}
public void Dispose()
{
this.Unregister();
GC.SuppressFinalize(this);
}
~HotkeyHandler()
{
// Unregister the hotkey if necessary
this.Unregister();
}
public bool IsRegistered { get; private set; }
public Keys KeyCode { get; private set; }
public event HandledEventHandler Pressed;
public bool CanRegister()
{
// Attempt to register
if (this.Register())
{
// Unregister and say we managed it
this.Unregister();
return true;
}
return false;
}
public bool Register()
{
// Check that we have not registered
if (this.IsRegistered)
{
return false;
}
if (this.KeyCode == Keys.None)
{
return false;
}
// Remove all modifiers from the 'main' hotkey
uint key = (uint)this.KeyCode & (~(uint)Keys.Alt) & (~(uint)Keys.Control) & (~(uint)Keys.Shift);
// Get unmanaged version of the modifiers code
uint modifiers = (this.KeyCode.HasFlag(Keys.Alt) ? HotkeyHandlerNativeMethods.MOD_ALT : 0)
| (this.KeyCode.HasFlag(Keys.Control) ? HotkeyHandlerNativeMethods.MOD_CONTROL : 0)
| (this.KeyCode.HasFlag(Keys.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 0);
// Register the hotkey
if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key))
{
return false;
}
Application.AddMessageFilter(this);
this.IsRegistered = true;
// We successfully registered
return true;
}
public void Unregister()
{
// Check that we have registered
if (!this.IsRegistered)
{
return;
}
this.IsRegistered = false;
Application.RemoveMessageFilter(this);
// Clean up after ourselves
if (!HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId))
{
return;
}
}
#region IMessageFilter
public bool PreFilterMessage(ref Message message)
{
return this.IsRegistered
&& (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY)
&& (message.WParam.ToInt32() == this._hotkeyId)
&& this.OnPressed();
}
#endregion
private bool OnPressed()
{
// Fire the event if we can
HandledEventArgs handledEventArgs = new HandledEventArgs(false);
this.Pressed?.Invoke(this, handledEventArgs);
// Return whether we handled the event or not
return handledEventArgs.Handled;
}
}
}