using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace RichCreator.Utility
{
///
/// 鼠标全局钩子
///
public class MouseHook:IDisposable
{
public MouseHook(MouseEvent mouseEvent)
{
this.OnMouseActivity = mouseEvent;
}
public enum MouseButton:Int32
{
None =0,
MouseMove = 0x200,
LeftButtonDown = 0x201,
RightButtonDown = 0x204,
middleButtonDown = 0x207,
LeftButtonUp = 0x202,
RightButtonUp = 0x205,
MiddleButtonUp = 0x208,
LeftButtonClick = 0x203,
RightButtonClick = 0x206,
MiddleButtonClick = 0x209,
}
///
/// 鼠标事件
///
///
///
///
///
public delegate void MouseEvent(Int32 x,Int32 y,Int32 clickCount,MouseButton button);
///
/// 点
///
[StructLayout(LayoutKind.Sequential)]
private class POINT
{
public int x;
public int y;
}
///
/// 钩子结构体
///
[StructLayout(LayoutKind.Sequential)]
private class MouseHookStruct
{
public POINT pt;
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
}
// 钩子回调函数
private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
private const int WH_MOUSE_LL = 14; // mouse hook constant
// 装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
// 卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
// 下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
private event MouseEvent OnMouseActivity; // 全局的鼠标事件
private HookProc mouseHookProcedure;// 声明鼠标钩子事件类型
private static int hMouseHook = 0; // 鼠标钩子句柄
private bool isFinalize=false;//是否已主动释放
///
/// 启动全局钩子
///
public void Start()
{
// 安装鼠标钩子
if (hMouseHook == 0)
{
mouseHookProcedure = new HookProc(MouseHookProc);
Module module = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0];
// 生成一个HookProc的实例.
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProcedure, Marshal.GetHINSTANCE(module), 0);
//假设装置失败停止钩子
if (hMouseHook == 0)
{
Close();
throw new Exception("SetWindowsHookEx failed.");
}
}
}
///
/// 停止全局钩子
///
public void Close()
{
if (isFinalize)
{
return;
}
bool retMouse = true;
if (hMouseHook != 0)
{
retMouse = UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
}
// 假设卸下钩子失败
if (!(retMouse))
{
throw new Exception("UnhookWindowsHookEx failed.");
}
isFinalize = true;
GC.SuppressFinalize(this);
}
///
/// 鼠标钩子回调函数
///
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// 假设正常执行而且用户要监听鼠标的消息
if ((nCode >= 0) && (OnMouseActivity != null))
{
MouseButton button = MouseButton.None;
Enum.TryParse(wParam.ToString(), out button);
int clickCount = 0;
switch (button)
{
case MouseButton.LeftButtonDown:
clickCount = 1;
break;
case MouseButton.LeftButtonUp:
clickCount = 1;
break;
case MouseButton.LeftButtonClick:
clickCount = 2;
break;
case MouseButton.RightButtonDown:
clickCount = 1;
break;
case MouseButton.RightButtonUp:
clickCount = 1;
break;
case MouseButton.RightButtonClick:
clickCount = 2;
break;
}
// 从回调函数中得到鼠标的信息
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
//MouseEvent e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
//// 假设想要限制鼠标在屏幕中的移动区域能够在此处设置
//// 后期须要考虑实际的x、y的容差
//if (!Screen.PrimaryScreen.Bounds.Contains(e.X, e.Y))
//{
// //return 1;
//}
OnMouseActivity(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y,clickCount, button);
}
// 启动下一次钩子
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
public void Dispose()
{
Close();
}
}
}