实现远程屏幕控制必不可少的函数之一就是mouse_event(或者SendInput),这个函数可以用来模拟鼠标移动、单击、双击等功能,但是描述这个函数的文档可谓少之又少,几段雷同的代码转来转去就是没有一些深入讨论的,MSDN中描述也语焉不详。在昨天试验中发现一个问题,希望有研究的“同志”能够帮我解答,^_^
无论从哪个角度看,上面这段代码也是没啥问题的,过程相当简单,首先进行坐标变换,然后两次调用mouse_event模拟鼠标按下和弹起,然而,代码的运行效果却出乎我的意料,程序并没有在(10, 10)的位置模拟鼠标单击事件,而是在当前位置触发鼠标单击!
经过多次验证,发现对于鼠标点击而言,dx、dy这两个参数好像不起作用,无论对这两个参数设置什么值,鼠标点击事件永远在当前位置触发!
猜测:为什么会这样呢?一个比较合理的解释是为了避免在界面上给用户造成混淆,从而禁止了在非鼠标当前位置处触发鼠标单击事件!具体原因不详!!!
引申:由于不能在任意位置触发鼠标点击事件,假如我有这么一个需要:鼠标不移动,在(10,10)位置点击一下!那我们应该怎么办呢?在上面假设成立的情况下我们是无法直接实现这个需求的,下面提供一个间接的方法:
在上面的代码中,通过隐藏鼠标,最终将鼠标位置移动到最初位置并显示解决这个问题,因为速度很快,用户几乎不会察觉!
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;
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
WindowsApplication2
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public partial class Form1 : Form
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
[DllImport("User32")]
public extern static void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[DllImport("User32")]
public extern static void SetCursorPos(int x, int y);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[DllImport("User32")]
public extern static bool GetCursorPos(out POINT p);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[DllImport("User32")]
public extern static int ShowCursor(bool bShow);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[StructLayout(LayoutKind.Sequential)]
public struct POINT
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public int X;
public int Y;
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[Flags]
public enum MouseEventFlags
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
Wheel = 0x0800,
Absolute = 0x8000
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Form1()
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
InitializeComponent();
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void Test1_Click(object sender, EventArgs e)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int dx = 10 * 65535 / Screen.PrimaryScreen.Bounds.Width;
int dy = 10 * 65535 / Screen.PrimaryScreen.Bounds.Height;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
mouse_event((int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
mouse_event((int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), dx, dy, 0, IntPtr.Zero);
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void Test2_Click(object sender, EventArgs e)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
POINT p = new POINT();
GetCursorPos(out p);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ShowCursor(false);
SetCursorPos(10, 10);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
mouse_event((int)(MouseEventFlags.LeftDown | MouseEventFlags.Absolute), 0, 0, 0, IntPtr.Zero);
mouse_event((int)(MouseEventFlags.LeftUp | MouseEventFlags.Absolute), 0, 0, 0, IntPtr.Zero);
}
finally
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
SetCursorPos(p.X, p.Y);
ShowCursor(true);
}
}
}
}
在如下模拟鼠标单击的代码中,我希望在相对屏幕左上角(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);
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
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](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)