• [C#]mouse_event模拟点击时坐标参数无效?!


    实现远程屏幕控制必不可少的函数之一就是mouse_event(或者SendInput),这个函数可以用来模拟鼠标移动、单击、双击等功能,但是描述这个函数的文档可谓少之又少,几段雷同的代码转来转去就是没有一些深入讨论的,MSDN中描述也语焉不详。在昨天试验中发现一个问题,希望有研究的“同志”能够帮我解答,^_^

    在如下模拟鼠标单击的代码中,我希望在相对屏幕左上角(10, 10)的位置点击一下:

    1 int dx = 10 * 65535 / Screen.PrimaryScreen.Bounds.Width;
    2 int dy = 10 * 65535 / Screen.PrimaryScreen.Bounds.Height;
    3 
    4 mouse_event((int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
    5 mouse_event((int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);

    无论从哪个角度看,上面这段代码也是没啥问题的,过程相当简单,首先进行坐标变换,然后两次调用mouse_event模拟鼠标按下和弹起,然而,代码的运行效果却出乎我的意料,程序并没有在(10, 10)的位置模拟鼠标单击事件,而是在当前位置触发鼠标单击!

    经过多次验证,发现对于鼠标点击而言,dx、dy这两个参数好像不起作用,无论对这两个参数设置什么值,鼠标点击事件永远在当前位置触发!

    猜测:为什么会这样呢?一个比较合理的解释是为了避免在界面上给用户造成混淆,从而禁止了在非鼠标当前位置处触发鼠标单击事件!具体原因不详!!!

    引申:由于不能在任意位置触发鼠标点击事件,假如我有这么一个需要:鼠标不移动,在(10,10)位置点击一下!那我们应该怎么办呢?在上面假设成立的情况下我们是无法直接实现这个需求的,下面提供一个间接的方法:

     1 POINT p = new POINT();
     2 GetCursorPos(out p);
     3 
     4 try
     5 {
     6     ShowCursor(false);
     7     SetCursorPos(1010);
     8 
     9     mouse_event((int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), 000, IntPtr.Zero);
    10     mouse_event((int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), 000, IntPtr.Zero);
    11 }
    12 finally
    13 {
    14     SetCursorPos(p.X, p.Y);
    15     ShowCursor(true);
    16 }
    17 

    在上面的代码中,通过隐藏鼠标,最终将鼠标位置移动到最初位置并显示解决这个问题,因为速度很快,用户几乎不会察觉!

    P.S. 假如哪位对mouse_event这个函数比较熟悉的话,望不吝赐教!

    完整示例代码://UPDATE: 代码折叠功能有问题,我选择“全部折叠”后居然无法展开了,奇怪!!!
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    namespace WindowsApplication2
    {
        
    public partial class Form1 : Form
        
    {
            [DllImport(
    "User32")]
            
    public extern static void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);

            [DllImport(
    "User32")]
            
    public extern static void SetCursorPos(int x, int y);

            [DllImport(
    "User32")]
            
    public extern static bool GetCursorPos(out POINT p);

            [DllImport(
    "User32")]
            
    public extern static int ShowCursor(bool bShow);

            [StructLayout(LayoutKind.Sequential)]
            
    public struct POINT
            
    {
                
    public int X;
                
    public int Y;
            }


            [Flags]
            
    public enum MouseEventFlags
            
    {
                Move        
    = 0x0001,
                LeftDown    
    = 0x0002,
                LeftUp      
    = 0x0004,
                RightDown   
    = 0x0008,
                RightUp     
    = 0x0010,
                MiddleDown  
    = 0x0020,
                MiddleUp    
    = 0x0040,
                Wheel       
    = 0x0800,
                Absolute    
    = 0x8000
            }


            
    public Form1()
            
    {
                InitializeComponent();
            }


            
    private void Test1_Click(object sender, EventArgs e)
            
    {
                
    int dx = 10 * 65535 / Screen.PrimaryScreen.Bounds.Width;
                
    int dy = 10 * 65535 / Screen.PrimaryScreen.Bounds.Height;

                mouse_event((
    int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
                mouse_event((
    int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
            }


            
    private void Test2_Click(object sender, EventArgs e)
            
    {
                POINT p 
    = new POINT();
                GetCursorPos(
    out p);

                
    try
                
    {
                    ShowCursor(
    false);
                    SetCursorPos(
    1010);

                    mouse_event((
    int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), 000, IntPtr.Zero);
                    mouse_event((
    int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), 000, IntPtr.Zero);
                }

                
    finally
                
    {
                    SetCursorPos(p.X, p.Y);
                    ShowCursor(
    true);
                }

            }

        }

    }
  • 相关阅读:
    python web 框架的基本逻辑练习题
    jQuery 自定义方法(扩展方法)
    jQuery 的动画效果图片----隐藏打开方法
    jQuery 小练习-拖拉画面
    用jQuery来绑定事件的3种方法和区别
    css用hover制作下拉菜单
    巧用hover改变css样式和背景
    mpvue中按需引入echarts
    webpack配置css浏览器前缀
    Vue中使用Sass全局变量
  • 原文地址:https://www.cnblogs.com/leafyoung/p/799837.html
Copyright © 2020-2023  润新知