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
}

然后在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中无效

二、鼠标勾子,此法亦在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)]
    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);
    }
}

调用的方法为:

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);
}
时间: 2024-10-12 20:40:53

c#全局鼠标事件以及鼠标事件模拟的相关文章

整理之DOM事件阶段、冒泡与捕获、事件委托、ie事件和dom模型事件、鼠标事件

整理之DOM事件阶段 本文主要解决的问题: 事件流 DOM事件流的三个阶段 先理解流的概念 在现今的JavaScript中随处可见.比如说React中的单向数据流,Node中的流,又或是今天本文所讲的DOM事件流.都是流的一种生动体现.用术语说流是对输入输出设备的抽象.以程序的角度说,流是具有方向的数据. 事件流分事件冒泡与事件捕获 在浏览器发展的过程中,开发团队遇到了一个问题.那就是页面中的哪一部分拥有特定的事件? 可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其

jQuery基础(鼠标事件,表单事件,键盘事件,自定义事件 篇)

1.jQuery鼠标事件之click与dbclick事件 方法一:$ele.click()(不带参数) <div id="test">点击触发<div> $("ele").click(function(){ alert('触发指定事件') }) $("#test").click(function(){ $("ele").click() //手动指定触发事件 });   方法二:$ele.click( h

JS事件(7)——事件类型——鼠标与滚轮事件

鼠标与滚轮事件 鼠标事件 “DOM3级事件”中定义了9个鼠标事件. click:在单击主鼠标按钮(一般是左键)或者按下回车时触发:这意味着onclick事件处理程序既可以通过鼠标也可以通过键盘执行. dbclick:双击主鼠标按钮(一般是左键)或者按下回车键时触发. mousedown:按下任意鼠标按钮时触发:不能通过键盘触发. mouseup:释放鼠标按钮时触发:不能通过键盘触发. mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发:这个事件不冒泡,而且光标移动到元素的后代

selenium键盘事件和鼠标事件

模拟鼠标事件 1.from selenium.webdriver.common.action_chains import ActionChains 2:ActionChains(driver):用于生成模拟用户行为 3:perform():执行存储行为 表达式 说明 context_click 右击事件 double_click 双击事件 drag_and_drop 拖动 move_to_element() 鼠标停在一个元素上 click_and_hold 按下鼠标左键在一个元素上 exampl

基于OpenGL编写一个简易的2D渲染框架-07 鼠标事件和键盘事件

这次为程序添加鼠标事件和键盘事件 当检测到鼠标事件和键盘事件的信息时,捕获其信息并将信息传送到需要信息的对象处理.为此,需要一个可以分派信息的对象,这个对象能够正确的把信息交到正确的对象. 实现思路: 要实现以上的功能,需要几个对象: 事件分派器:EventDispatcher,负责将 BaseEvent 分派给 EventListener 对象 事件监听器:EventListener,这只是一个接口类,接受 BaseEvent 的对象,真正的处理在它的子类中实现 事件:BaseEvent,储存

jQuery事件之鼠标事件

鼠标事件是在用户移动鼠标光标或者使用任意鼠标键点击时触发的.   (1):click事件:click事件于用户在元素敲击鼠标左键,并在相同元素上松开左键时触发.        $('p').click(function(){                alert('click function is running !');              });    (2):dbclick事件:dbclick事件在用户完成迅速连续的两次点击之后触发,双击的速度取决于操作系统的设置.一般双击事件

javascript鼠标双击时触发事件大全

javascript事件列表解说 事件 浏览器支持 解说 一般事件 onclick IE3.N2 鼠标点击时触发此事件 ondblclick IE4.N4 鼠标双击时触发此事件 onmousedown IE4.N4 按下鼠标时触发此事件 onmouseup IE4.N4 鼠标按下后松开鼠标时触发此事件 onmouseover IE3.N2 当鼠标移动到某对象范围的上方时触发此事件 onmousemove IE4.N4 鼠标移动时触发此事件 onmouseout IE4.N3 当鼠标离开某对象范围

mfc 鼠标、键盘响应事件

一.基本目标 1.有一个基本的MFC程序,点击“关闭”则“关闭”这个程序,这点没什么好讲的,把自带的“取消”按钮,右键->属性的Caption改成“关闭”二字就可以了 2.鼠标在对话框中移动,则显示其位置信息,这个坐标是窗口内部坐标 3.如果按着鼠标右键移动鼠标,则在这个工程的标题栏会显示“按着鼠标右键移动鼠标”,松开鼠标右键回复如初 4.如果按着键盘上的Ctrl键或者Shift键在对话框的窗口中移动鼠标,标题栏同样会有相应的提示,是否同时按下也会有提示 5.左击对话框,会弹出对话框,显示鼠标位

鼠标事件之鼠标滑过事件MOUSEOVER

来源地址:http://www.g2room.com/jquery/index.php?p=example%2Fevent%2Fmouseover.html&n=%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6%E4%B9%8B%E9%BC%A0%E6%A0%87%E6%BB%91%E8%BF%87%E4%BA%8B%E4%BB%B6MOUSEOVER var i = 0; // 定义当事件触发后执行的方法 function showContent (event){ $(