该代码块内有四个功能,获取鼠标坐标,鼠标点击,鼠标事件监听,键盘事件监听
其鼠标坐标,鼠标点击 可以在窗体范围之外生效
鼠标事件监听,鼠标事件只在窗体范围之内有效
public class MouseAction
{
#region 鼠标坐标
/* 在外部通过以下命令调用
* 开启获取鼠标坐标
* MouseAction.MousePositionStart(textBox1);
* 关闭获取鼠标坐标
* MouseAction.MousePositionStop();
*/
/// <summary>
/// 用于回传鼠标坐标的控制
/// </summary>
private static System.Windows.Forms.TextBox _textBox;
/// <summary>
/// 获取鼠标坐标
/// </summary>
private static void ScreenPoint()
{
while (true)
{
Point mousePosition = Control.MousePosition;
_textBox.Text = $"x:{mousePosition.X} y:{mousePosition.Y}";
}
}
/// <summary>
/// 鼠标事件后移动回原位置
/// </summary>
/// <param name="point"></param>
public static void MouseMoveBack(Point point)
{
SetCursorPos(point.X, point.Y);
}
/// <summary>
/// 获取鼠标坐标
/// </summary>
/// <returns></returns>
public static Point GetScreenPoint()
{
Point mousePosition = Control.MousePosition;
return mousePosition;
}
/// <summary>
/// 以线程的方式跟踪鼠标坐标
/// </summary>
private static Thread _threadMousePosition;
/// <summary>
/// 开启鼠标坐标跟踪
/// </summary>
/// <param name="textBox"></param>
public static void MousePositionStart(System.Windows.Forms.TextBox textBox)
{
_textBox = textBox;
_threadMousePosition = new Thread(new ThreadStart(ScreenPoint));
_threadMousePosition.Start();
}
/// <summary>
/// 停止鼠标坐标跟踪
/// </summary>
public static void MousePositionStop()
{
_threadMousePosition.Abort();
}
~MouseAction()
{
MousePositionStop();
StopHook();
}
#endregion
// ------------------------------------------------------------------------------------
#region 鼠标点击
/*在外部通过以下命令调用
* 获取当前坐标
* Point pointP1 = MouseAction.GetScreenPoint();
目标坐标
Point pointP = new Point(Convert.ToInt32(txtX.Text), Convert.ToInt32(txtY.Text));
鼠标左键
MouseAction.MouseLeftClick(pointP);
鼠标回位
MouseAction.MouseMoveBack(pointP1);
*
*/
/// <summary>
/// 引用user32.dll运态链接库;库中定定了API:SetCursorPos
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
[DllImport("user32.dll")]
/// <summary>
/// 设置鼠标目标位置
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private static extern int SetCursorPos(int x, int y);
[DllImport("user32.dll")]
/// <summary>
/// 设置鼠标事件
/// </summary>
/// <param name="dwFlags"></param>
/// <param name="dx"></param>
/// <param name="dy"></param>
/// <param name="cButtons"></param>
/// <param name="dwExtraInfo"></param>
private extern static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
/// <summary>
/// 鼠标事件枚举
/// </summary>
private enum MouseEventFlags
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
Wheel = 0x0800,
Absolute = 0x8000
}
/// <summary>
/// 鼠标点击左键
/// </summary>
/// <param name="point"></param>
public static void MouseLeftClick(Point point)
{
SetCursorPos(point.X, point.Y);
MouseAction.mouse_event(MouseAction.MouseEventFlags.LeftDown.GetHashCode() | MouseAction.MouseEventFlags.LeftUp.GetHashCode(), point.X, point.Y, 0, 0);
}
#endregion
// ------------------------------------------------------------------------------------
#region 键盘事件监听
/*在外部通过以下命令调用
* MouseAction.StartKeyboardHook(richTextBox1);
*/
/// <summary>
/// 安装钩子
/// </summary>
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
/// <summary>
/// 继续下一个钩子
/// </summary>
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
/// <summary>
/// 卸载钩子
/// </summary>
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
/// <summary>
///获取当前线程编号(线程钩子需要用到)
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
/// <summary>
/// 获取当前实例的函数
/// </summary>
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string name);
/// <summary>
/// 获取按键的状态
/// </summary>
/// <param name="pbKeyState"></param>
/// <returns></returns>
[DllImport("user32")]
private static extern int GetKeyboardState(byte[] pbKeyState);
/// <summary>
/// 将指定的虚拟键码和键盘状态翻译为相应的字符或字符串
/// </summary>
[DllImport("user32")]
private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
/// <summary>
/// 键盘结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private class KeyboardHookStruct
{
public int vkCode; //定一个虚拟键码。该代码必须有一个价值的范围1至254
public int scanCode; // 指定的硬件扫描码的关键
public int flags; // 键标志
public int time; // 指定的时间戳记的这个讯息
public int dwExtraInfo; // 指定额外信息相关的信息
}
//定义为键盘钩子
private static int WH_KEYBOARD_LL = 13;
//相关键盘事件
//private event KeyEventHandler KeyDownEvent;
//private event KeyPressEventHandler KeyPressEvent;
//private event KeyEventHandler KeyUpEvent;
private static void KeyDownEvent(object sender,KeyEventArgs e )
{
//_richTextBox.AppendText(e.KeyData.ToString()+"\n");
}
private static void KeyPressEvent(object sender, KeyPressEventArgs e)
{
_richTextBox.AppendText(e.KeyChar.ToString() + "\n");
}
private static void KeyUpEvent(object sender, KeyEventArgs e)
{
//_richTextBox.AppendText(e.KeyData.ToString() + "\n");
}
//相关动作
private const int WM_KEYDOWN = 0x100;//KEYDOWN
private const int WM_KEYUP = 0x101;//KEYUP
private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
private const int WM_SYSKEYUP = 0x105;//SYSKEYUP
//hookid
private static int hookID = 0;
//向下传递数据
private static Keys NoNextKeyCode;
/// <summary>
/// 安装钩子
/// </summary>
public static void StartKeyboardHook(RichTextBox richTextBox)
{
_richTextBox = richTextBox;
if (hookID == 0)
{
HookProc hookProc = new HookProc(KeyboardHookProc);
hookID = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
if (hookID == 0)
{
StopHook();
throw new Exception("安装键盘钩子失败");
}
}
}
public static void StopHook()
{
bool isStop = true;
if (hookID != 0)
{
isStop = UnhookWindowsHookEx(hookID);
hookID = 0;
}
if (!isStop) throw new Exception("卸载键盘钩子失败!");
}
/// <summary>
/// 监听事件
/// </summary>
private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if ((nCode >= 0) )
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
//按下处理
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyDownEvent(null, e);
//阻止向下传递
if (NoNextKeyCode == keyData)
{
return hookID;
}
}
//按下并抬起处理
if ( wParam == WM_KEYDOWN)
{
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
KeyPressEvent(null, e);
}
}
// 抬起处理
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUpEvent(null, e);
}
}
return CallNextHookEx(hookID, nCode, wParam, lParam);
}
#endregion
//--------------------------------------------------------------------------------
#region 鼠标事件监听
/*在外部通过以下命令调用
* MouseAction.StartMouseHook(richTextBox1);
*/
/// <summary>
/// 鼠标结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private class MouseHookStruct
{
public POINT pt; // 鼠标位置
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
}
/// <summary>
/// 鼠标位置结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private class POINT
{
public int x;
public int y;
}
//定义为鼠标钩子
private static int WH_MOUSE_LL = 14;
//相关鼠标事件
//public event MouseEventHandler MouseDown;
//public event MouseEventHandler MouseUp;
private static void MouseDown(object sender, MouseEventArgs e)
{
_richTextBox.AppendText(string.Format("在{0},{1}位置按下了鼠标{2}键", e.X, e.Y, e.Button.ToString())+"\n");
}
private static void MouseUp(object sender,MouseEventArgs e)
{
//_richTextBox.AppendText(string.Format("在{0},{1}位置松开了鼠标{2}键", e.X, e.Y, e.Button.ToString()) + "\n");
}
//相关动作
private const int WM_MOUSEMOVE = 0x200; // 鼠标移动
private const int WM_LBUTTONDOWN = 0x201;// 鼠标左键按下
private const int WM_RBUTTONDOWN = 0x204;// 鼠标右键按下
private const int WM_MBUTTONDOWN = 0x207;// 鼠标中键按下
private const int WM_LBUTTONUP = 0x202;// 鼠标左键抬起
private const int WM_RBUTTONUP = 0x205;// 鼠标右键抬起
private const int WM_MBUTTONUP = 0x208;// 鼠标中键抬起
//hookid
//private int hookID = 0;
private static int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
if ((nCode >= 0))
{
MouseHookStruct hookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MouseEventArgs e = null;
switch (wParam)
{
case WM_LBUTTONDOWN:
e = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
MouseDown(null, e);
break;
case WM_RBUTTONDOWN:
e = new MouseEventArgs(MouseButtons.Right, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
MouseDown(null, e);
break;
case WM_LBUTTONUP:
e = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
MouseUp(null, e);
break;
case WM_RBUTTONUP:
e = new MouseEventArgs(MouseButtons.Right, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
MouseUp(null, e);
break;
default:
break;
}
}
return CallNextHookEx(hookID, nCode, wParam, lParam);
}
private static System.Windows.Forms.RichTextBox _richTextBox;
/// <summary>
/// 安装钩子
/// </summary>
public static void StartMouseHook(RichTextBox richTextBox)
{
_richTextBox = richTextBox;
if (hookID == 0)
{
HookProc hookProc1 = new HookProc(MouseHookProc);
hookID = SetWindowsHookEx(WH_MOUSE_LL, hookProc1, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
if (hookID == 0)
{
StopHook();
throw new Exception("安装键盘钩子失败");
}
}
}
#endregion
}