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
|
{
|
/// <summary>
|
/// 鼠标全局钩子
|
/// </summary>
|
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,
|
}
|
|
/// <summary>
|
/// 鼠标事件
|
/// </summary>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="clickCount"></param>
|
/// <param name="button"></param>
|
public delegate void MouseEvent(Int32 x,Int32 y,Int32 clickCount,MouseButton button);
|
|
|
/// <summary>
|
/// 点
|
/// </summary>
|
[StructLayout(LayoutKind.Sequential)]
|
private class POINT
|
{
|
public int x;
|
public int y;
|
}
|
|
/// <summary>
|
/// 钩子结构体
|
/// </summary>
|
[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;//是否已主动释放
|
|
|
/// <summary>
|
/// 启动全局钩子
|
/// </summary>
|
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.");
|
}
|
}
|
}
|
|
|
|
/// <summary>
|
/// 停止全局钩子
|
/// </summary>
|
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);
|
}
|
|
/// <summary>
|
/// 鼠标钩子回调函数
|
/// </summary>
|
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
|
{
|
// 假设正常执行而且用户要监听鼠标的消息
|
if ((nCode >= 0) && (OnMouseActivity != null))
|
{
|
MouseButton button = MouseButton.None;
|
Enum.TryParse<MouseButton>(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();
|
}
|
}
|
}
|