Add HotKeyListener
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public record HotKeyDescriptor(ModifierKey Modifiers, VirtualKey VirtualKey);
|
||||
@@ -0,0 +1,49 @@
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public class HotKeyListener(ICache<int, HotKeyDescriptor> cache,
|
||||
IMessenger messenger) :
|
||||
IHotKeyListener,
|
||||
IRecipient<WndProcEventArgs>
|
||||
{
|
||||
private bool isDisposed;
|
||||
|
||||
~HotKeyListener()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
messenger.RegisterAll(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(WndProcEventArgs message)
|
||||
{
|
||||
const int WM_HOTKEY = 0x0312;
|
||||
if (message.Message == WM_HOTKEY)
|
||||
{
|
||||
int key = (int)message.WParam;
|
||||
if (cache.Contains(key))
|
||||
{
|
||||
messenger.Send(new HotKeyPressedEventArgs(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using Toolkit.Foundation;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.UI.Input.KeyboardAndMouse;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public class HotKeyManager(IWndProc wndProc,
|
||||
ICache<int, HotKeyDescriptor> cache) :
|
||||
IHotKeyManager
|
||||
{
|
||||
public void Add(int key, HotKeyDescriptor descriptor)
|
||||
{
|
||||
HOT_KEY_MODIFIERS modifiers = 0;
|
||||
|
||||
if ((descriptor.Modifiers & ModifierKey.Alt) == ModifierKey.Alt)
|
||||
modifiers |= HOT_KEY_MODIFIERS.MOD_ALT;
|
||||
if ((descriptor.Modifiers & ModifierKey.Ctrl) == ModifierKey.Ctrl)
|
||||
modifiers |= HOT_KEY_MODIFIERS.MOD_CONTROL;
|
||||
if ((descriptor.Modifiers & ModifierKey.Shift) == ModifierKey.Shift)
|
||||
modifiers |= HOT_KEY_MODIFIERS.MOD_SHIFT;
|
||||
if ((descriptor.Modifiers & ModifierKey.Win) == ModifierKey.Win)
|
||||
modifiers |= HOT_KEY_MODIFIERS.MOD_WIN;
|
||||
|
||||
uint vk = (uint)descriptor.VirtualKey;
|
||||
if (PInvoke.RegisterHotKey(new HWND(wndProc.Handle), key, modifiers, vk))
|
||||
{
|
||||
cache.Add(key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(int key) =>
|
||||
cache.Contains(key);
|
||||
|
||||
public void Remove(int key)
|
||||
{
|
||||
PInvoke.UnregisterHotKey(new HWND(wndProc.Handle), key);
|
||||
cache.Remove(key);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HWND hwnd = new(wndProc.Handle);
|
||||
foreach (KeyValuePair<int, HotKeyDescriptor> item in cache)
|
||||
{
|
||||
PInvoke.UnregisterHotKey(hwnd, item.Key);
|
||||
}
|
||||
|
||||
cache.Clear();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~HotKeyManager()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public record HotKeyPressedEventArgs(int Key);
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public interface ITaskbarButtonMonitor :
|
||||
public interface IHotKeyListener :
|
||||
IInitialization,
|
||||
IDisposable;
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public interface IHotKeyManager :
|
||||
IDisposable
|
||||
{
|
||||
void Add(int key, HotKeyDescriptor descriptor);
|
||||
|
||||
bool Contains(int key);
|
||||
|
||||
void Remove(int key);
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public interface IPointer :
|
||||
public interface IPointerListener :
|
||||
IInitialization,
|
||||
IDisposable;
|
||||
@@ -0,0 +1,7 @@
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public interface ITaskbarButtonListener :
|
||||
IInitialization,
|
||||
IDisposable;
|
||||
@@ -48,4 +48,6 @@ TranslateMessage
|
||||
DispatchMessage
|
||||
PostQuitMessage
|
||||
DestroyWindow
|
||||
GetModuleHandle
|
||||
GetModuleHandle
|
||||
RegisterHotKey
|
||||
UnregisterHotKey
|
||||
@@ -62,7 +62,7 @@ public class NotifyIcon(IWndProc wndProc,
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public unsafe PointerLocation GetPointerPosition()
|
||||
public static unsafe PointerLocation GetPointerPosition()
|
||||
{
|
||||
Point point = new();
|
||||
_ = PInvoke.GetCursorPos(&point);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public class Pointer(IMessenger messenger) :
|
||||
IPointer
|
||||
public class PointerListener(IMessenger messenger) :
|
||||
IPointerListener
|
||||
{
|
||||
private bool isDisposed;
|
||||
private bool isPointerDrag;
|
||||
@@ -16,7 +15,7 @@ public class Pointer(IMessenger messenger) :
|
||||
private HOOKPROC? mouseEventDelegate;
|
||||
private UnhookWindowsHookExSafeHandle? mouseHandle;
|
||||
|
||||
~Pointer()
|
||||
~PointerListener()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
@@ -27,25 +26,22 @@ public class Pointer(IMessenger messenger) :
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public unsafe void Initialize() =>
|
||||
InitializeHook();
|
||||
public unsafe void Initialize()
|
||||
{
|
||||
mouseEventDelegate = new HOOKPROC(MouseProc);
|
||||
mouseHandle = PInvoke.SetWindowsHookEx(WINDOWS_HOOK_ID.WH_MOUSE_LL, mouseEventDelegate,
|
||||
PInvoke.GetModuleHandle("user32.dll"), 0);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
RemoveHook();
|
||||
Remove();
|
||||
isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void InitializeHook()
|
||||
{
|
||||
mouseEventDelegate = new HOOKPROC(MouseProc);
|
||||
mouseHandle = PInvoke.SetWindowsHookEx(WINDOWS_HOOK_ID.WH_MOUSE_LL, mouseEventDelegate,
|
||||
PInvoke.GetModuleHandle("user32.dll"), 0);
|
||||
}
|
||||
|
||||
private LRESULT MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0)
|
||||
@@ -82,7 +78,7 @@ public class Pointer(IMessenger messenger) :
|
||||
return PInvoke.CallNextHookEx(mouseHandle, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
private unsafe void RemoveHook()
|
||||
private unsafe void Remove()
|
||||
{
|
||||
if (mouseHandle is not null && mouseHandle.DangerousGetHandle() != nint.Zero)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ public class TaskbarButton :
|
||||
|
||||
public void Receive(PointerReleasedEventArgs args)
|
||||
{
|
||||
if (!isDrag && isWithinBounds)
|
||||
if (args.Button is PointerButton.Left && !isDrag && isWithinBounds)
|
||||
{
|
||||
messenger.Send(new TaskbarButtonInvokedEventArgs(this));
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ using UIAutomationClient;
|
||||
|
||||
namespace Toolkit.Windows;
|
||||
|
||||
public class TaskbarButtonMonitor :
|
||||
ITaskbarButtonMonitor
|
||||
public class TaskbarButtonListener :
|
||||
ITaskbarButtonListener
|
||||
{
|
||||
private readonly IDispatcherTimer dispatcherTimer;
|
||||
private readonly IDispatcherTimerFactory dispatcherTimerFactory;
|
||||
@@ -19,7 +19,7 @@ public class TaskbarButtonMonitor :
|
||||
private IUIAutomationElement? taskListElement;
|
||||
private IntPtr taskListHandle;
|
||||
|
||||
public TaskbarButtonMonitor(ITaskbarList taskbarList,
|
||||
public TaskbarButtonListener(ITaskbarList taskbarList,
|
||||
IMessenger messenger,
|
||||
IDispatcherTimerFactory dispatcherTimerFactory,
|
||||
IServiceFactory serviceFactory,
|
||||
Reference in New Issue
Block a user