c#全局鼠标事件以及鼠标事件模拟

c#全局⿏标事件以及⿏标事件模拟
最近在编写Max插件时,其主容器FlowLayoutPanel由于隐藏了滚动条,要实现按住⿏标中键上下拖动的功能,因此尝试了全局⿏标事件、以及⿏标勾⼦,可惜由于Max不争⽓?都未能实现,于是代码报废,故将其分享于此。
⼀、全局⿏标事件,⾸先构建⿏标事件处理器
public delegate void MouseMovedEvent();
public delegate void MouseMDownEvent();
public delegate void MouseMUpEvent();
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_MBUTTONDOWN = 0x0207;
private const int WM_MBUTTONUP = 0x0208;
public event MouseMovedEvent TheMouseMoved;
public event MouseMDownEvent TheMouseMDown;
public event MouseMUpEvent TheMouseMUp;
#region IMessageFilter Members
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
if (TheMouseMoved != null)
TheMouseMoved();
if (m.Msg == WM_MBUTTONDOWN)
if (TheMouseMDown != null)
TheMouseMDown();
if (m.Msg == WM_MBUTTONUP)
if (TheMouseMUp != null)
TheMouseMUp();
// Always allow message to continue to the next filter control
return false;
}
#endregion
}
瓶花木View Code
然后在FlowLayoutPanel的构造函数中添加如下代码(其事件,我这⾥使⽤的Lambda表达式)
GlobalMouseHandler gmh = new GlobalMouseHandler();
bool mFlag = false;
int scY = 0;
int msY = 0;
Cursor tempCur = null;
gmh.TheMouseMDown += () =>
{
mFlag = true;
scY = VerticalScroll.Value;
msY = Cursor.Position.Y;
tempCur = Cursor;
Cursor = RCurs.Pan;
};
gmh.TheMouseMoved += () =>
{
if (mFlag)
{
int val = scY + msY - Cursor.Position.Y;
if (val < VerticalScroll.Minimum) val = VerticalScroll.Minimum;
if (val > VerticalScroll.Maximum) val = VerticalScroll.Maximum;
VerticalScroll.Value = val;
}
};
gmh.TheMouseMUp += () =>
{
mFlag = false;
Cursor = tempCur;
};
Application.AddMessageFilter(gmh); //Application在Max中⽆效
View Code
⼆、⿏标勾⼦,此法亦在Max中⾏不通(后来是通过对FlowLayoutPanel中的各个控件实⾏事件穿透解决的)
public class MouseHook
{
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;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209;
/
/全局的事件
public event MouseEventHandler OnMouseActivity;
static int hMouseHook = 0; //⿏标钩⼦句柄
//⿏标常量
public const int WH_MOUSE_LL = 14; //mouse hook constant
HookProc MouseHookProcedure; //声明⿏标钩⼦事件类型.
//声明⼀个Point的封送类型
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
//声明⿏标钩⼦的封送结构类型
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
}碳纤维增强尼龙
/
/装置钩⼦的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//卸下钩⼦的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
kvm管理系统
public static extern bool UnhookWindowsHookEx(int idHook);
//下⼀个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
///<summary>
/
//墨认的构造函数构造当前类的实例.多向指示牌
///</summary>
public MouseHook()
{
}
//析构函数.
~MouseHook()
{
Stop();
}
public void Start()
{
//安装⿏标钩⼦
if (hMouseHook == 0)
{
//⽣成⼀个HookProc的实例.
MouseHookProcedure = new HookProc(MouseHookProc);
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
//如果装置失败停⽌钩⼦
if (hMouseHook == 0)
{
Stop();
throw new Exception("SetWindowsHookEx failed.");  //Max中会抛出异常
}
}
}
public void Stop()
{
bool retMouse = true;
if (hMouseHook != 0)
{
retMouse = UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
}
//如果卸下钩⼦失败空调控制板
if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed.");
}
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//如果正常运⾏并且⽤户要监听⿏标的消息
if ((nCode >= 0) && (OnMouseActivity != null))
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
switch (wParam)
{
case WM_MBUTTONDOWN:
button = MouseButtons.Middle;
clickCount = 1;
break;
case WM_MBUTTONUP:
button = MouseButtons.Middle;
clickCount = 0;
break;
}
//从回调函数中得到⿏标的信息
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));            MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
//if(e.X>700)return 1;//如果想要限制⿏标在屏幕中的移动区域可以在此处设置
OnMouseActivity(this, e);
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
}
View Code
调⽤的⽅法为:
MouseHook mouse = new MouseHook();
mouse.OnMouseActivity += (s, e) =>
{
string str = "X:" + e.X + "  Y:" + e.Y + "" + e.Button + "" + e.Clicks;
this.Text = str;
};
mouse.Start();
三、⿏标事件模拟
//切换到窗⼝
[DllImport("user32.dll")]
public static extern bool SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
//获取⿏标所在窗⼝名柄
[DllImport("user32.dll")]
internal static extern IntPtr WindowFromPoint(Point Point);
[DllImport("user32.dll")]
internal static extern bool GetCursorPos(out Point lpPoint);
public static IntPtr GetMouseWindow()
{
Point p;
GetCursorPos(out p);
return WindowFromPoint(p);
}
//获取前台窗⼝
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
///<summary>
///模拟⿏标操作
///</summary>
[DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动⿏标
const int MOUSEEVENTF_MOVE = 0x0001;
/
/模拟⿏标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟⿏标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟⿏标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟⿏标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
等离子割//模拟⿏标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟⿏标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标⽰是否采⽤绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000;
public static void MouseMove(int x, int y)
{
mouse_event(MOUSEEVENTF_MOVE, x, y, 0, 0);
}
public static void MouseClick()
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); //再复制⼀份则为双击
}
public static void MouseDown()
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
}
public static void MouseUp()
{
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); }
View Code

本文发布于:2024-09-23 18:20:15,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/287756.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:事件   模拟   函数   标钩
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议