mirror of
https://github.com/nsnail/dot.git
synced 2025-06-17 21:13:21 +08:00
82 lines
2.4 KiB
C#
82 lines
2.4 KiB
C#
// ReSharper disable ClassNeverInstantiated.Global
|
|
|
|
#if NET7_0_WINDOWS
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Dot.Color;
|
|
|
|
internal sealed class MouseHook : IDisposable
|
|
{
|
|
private const int _WH_MOUSE_LL = 14;
|
|
private const int _WM_LBUTTONDOWN = 0x0201;
|
|
private const int _WM_MOUSEMOVE = 0x0200;
|
|
private readonly nint _hookId;
|
|
private bool _disposed;
|
|
|
|
public MouseHook()
|
|
{
|
|
_hookId = SetHook(HookCallback);
|
|
}
|
|
|
|
~MouseHook()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public event MouseEventHandler MouseEvent;
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private static nint SetHook(Func<int, nint, nint, nint> proc)
|
|
{
|
|
using var curProcess = Process.GetCurrentProcess();
|
|
using var curModule = curProcess.MainModule!;
|
|
return Win32.SetWindowsHookEx(_WH_MOUSE_LL, proc, Win32.GetModuleHandle(curModule.ModuleName), 0);
|
|
}
|
|
|
|
private void Dispose(bool disposing)
|
|
{
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
|
|
if (disposing) {
|
|
//
|
|
}
|
|
|
|
if (_hookId != default) {
|
|
Win32.UnhookWindowsHookEx(_hookId);
|
|
}
|
|
|
|
_disposed = true;
|
|
}
|
|
|
|
private nint HookCallback(int nCode, nint wParam, nint lParam)
|
|
{
|
|
if (nCode < 0 || (wParam != _WM_MOUSEMOVE && wParam != _WM_LBUTTONDOWN)) {
|
|
return Win32.CallNextHookEx(_hookId, nCode, wParam, lParam);
|
|
}
|
|
|
|
var hookStruct = (Msllhookstruct)Marshal.PtrToStructure(lParam, typeof(Msllhookstruct))!;
|
|
MouseEvent?.Invoke(null, new MouseEventArgs( //
|
|
wParam == _WM_MOUSEMOVE ? MouseButtons.None : MouseButtons.Left //
|
|
, 0 //
|
|
, hookStruct.X //
|
|
, hookStruct.Y //
|
|
, 0));
|
|
return Win32.CallNextHookEx(_hookId, nCode, wParam, lParam);
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
private readonly struct Msllhookstruct
|
|
{
|
|
[FieldOffset(0)] public readonly int X;
|
|
[FieldOffset(4)] public readonly int Y;
|
|
}
|
|
}
|
|
#endif |