[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( 10 10 );
 8 
 9      mouse_event(( int )(MouseEventFlags.LeftDown  |  MouseEventFlags.Absolute),  0 0 0 , IntPtr.Zero);
10      mouse_event(( int )(MouseEventFlags.LeftUp  |  MouseEventFlags.Absolute),  0 0 0 , IntPtr.Zero);
11  }
12  finally
13  {
14      SetCursorPos(p.X, p.Y);
15      ShowCursor( true );
16  }
17 

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

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

完整示例代码: //UPDATE: 代码折叠功能有问题,我选择“全部折叠”后居然无法展开了,奇怪!!!
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.ComponentModel;
None.gif
using  System.Data;
None.gif
using  System.Drawing;
None.gif
using  System.Linq;
None.gif
using  System.Text;
None.gif
using  System.Windows.Forms;
None.gif
using  System.Runtime.InteropServices;
None.gif
None.gif
namespace  WindowsApplication2
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public partial class Form1 : Form
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        [DllImport(
"User32")]
InBlock.gif        
public extern static void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);
InBlock.gif
InBlock.gif        [DllImport(
"User32")]
InBlock.gif        
public extern static void SetCursorPos(int x, int y);
InBlock.gif
InBlock.gif        [DllImport(
"User32")]
InBlock.gif        
public extern static bool GetCursorPos(out POINT p);
InBlock.gif
InBlock.gif        [DllImport(
"User32")]
InBlock.gif        
public extern static int ShowCursor(bool bShow);
InBlock.gif
InBlock.gif        [StructLayout(LayoutKind.Sequential)]
InBlock.gif        
public struct POINT
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
public int X;
InBlock.gif            
public int Y;
ExpandedSubBlockEnd.gif        }

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

InBlock.gif
InBlock.gif        
public Form1()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            InitializeComponent();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void Test1_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
int dx = 10 * 65535 / Screen.PrimaryScreen.Bounds.Width;
InBlock.gif            
int dy = 10 * 65535 / Screen.PrimaryScreen.Bounds.Height;
InBlock.gif
InBlock.gif            mouse_event((
int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
InBlock.gif            mouse_event((
int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void Test2_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            POINT p 
= new POINT();
InBlock.gif            GetCursorPos(
out p);
InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ShowCursor(
false);
InBlock.gif                SetCursorPos(
1010);
InBlock.gif
InBlock.gif                mouse_event((
int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), 000, IntPtr.Zero);
InBlock.gif                mouse_event((
int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), 000, IntPtr.Zero);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                SetCursorPos(p.X, p.Y);
InBlock.gif                ShowCursor(
true);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值