C# 使用 SendMessage 模拟鼠标点击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14876345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using SendMessage to simulate mouse clicks
提问by Doon
What I need
我需要的
Simulate messages (mouse mainly, but keyboard too) without moving the cursor. The message goes to the focused window (at first, I want for minimized windows, but I didn't find how to do it, so I use SetForegroundWindow
to focus it).
在不移动光标的情况下模拟消息(主要是鼠标,但也包括键盘)。消息进入聚焦窗口(起初,我想要最小化窗口,但我没有找到如何去做,所以我SetForegroundWindow
用来聚焦它)。
What I've found
我发现了什么
On thisquestion, I've figured out I need to use pInvoked from user32.dll
. Also I found a small code sample, but it didn't work.
在这个问题上,我发现我需要使用 pInvoked from user32.dll
。我还发现了一个小代码示例,但没有用。
I also found thissimilar question. The guy uses mouse_event
, but it is deprecated. This function takes the X and Y cordinates in mickeys. I tried to convert my coordinates (using SendMessage
), but I failed.
我也发现了这个类似的问题。这家伙使用mouse_event
,但它已被弃用。此函数采用米奇中的 X 和 Y 坐标。我试图转换我的坐标(使用SendMessage
),但我失败了。
Icanhaz an example?
伊坎哈兹举个例子?
Sure. The notepad.exe
is opened and I need to peform a right click on a button located at (1210, 460).
当然。将notepad.exe
被打开,我需要对[执行位于(1210,460)按钮右键单击。
What I've tried
我试过的
Based on the sample that I've found here, I did this code:
根据我在此处找到的示例,我执行了以下代码:
IntPtr hWnd = (IntPtr)FindWindow("notepad.exe", null);
SetForegroundWindow(hWnd);
var screenPoint = this.PointToScreen(new Point(1210, 460));
var handle = WindowFromPoint(screenPoint);
if (handle != IntPtr.Zero)
{
//Right Button Down
SendMessage(handle, 0x0204, IntPtr.Zero, IntPtr.Zero);
//Right Button Up
SendMessage(handle, 0x0205, IntPtr.Zero, IntPtr.Zero);
}
I also tried using my previous handle hWnd
in SendMessage
, but didn't work as well. The whole code you can find here.
我用我以前的手柄也试过hWnd
在SendMessage
,却没有正常工作。你可以在这里找到完整的代码。
Thank you in advance.
先感谢您。
回答by Remus Rusanu
Raymond Chen wrote a blog post just for you: You can't simulate keyboard input with PostMessage. I know you want mouse, not keys, and you use Send not Post, but exactly the same problems apply to you. Read the link. Fortunately, it also contains the solution: use SendInput
function.
Raymond Chen 专门为您写了一篇博文:您无法使用 PostMessage 模拟键盘输入。我知道您需要鼠标而不是键,并且您使用的是发送而不是邮寄,但同样的问题也适用于您。阅读链接。幸运的是,它还包含解决方案:使用SendInput
函数。
Synthesizes keystrokes, mouse motions, and button clicks.
合成击键、鼠标动作和按钮点击。
回答by Abyte0
This is some mouse and keyboard handler ive made when I was younger to find a color on a game screen and click ||right click+option :P
这是我小时候在游戏屏幕上找到颜色并单击 || 右键单击+选项时制作的一些鼠标和键盘处理程序:P
Maybe some of the code may help you even if it's in french...
也许一些代码可以帮助你,即使它是法语......
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Abyte0
{
public partial class ClavierVirtuel
{
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string _ClassName, string _WindowName);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
private static extern int SetForegroundWindow(int hwnd);
//int handle = FindWindow(null, "Facebook - Windows Internet Explorer");
//Give focus to the screen with the wanted name
public static void DonnerFocus(string pNomFenetre)
{
//Get the handle of the app you want to send keys to
int handle = FindWindow(null, pNomFenetre);
//Set it to the foreground
SetForegroundWindow(handle);
}
//write the string
public static void Ecrire(string pPhrase)
{
//Send the keys on over
SendKeys.SendWait(pPhrase);
}
//write a string and press enter
public static void ecrire_Enter(string pPhrase)
{
foreach (char lettre in pPhrase)
{
SendKeys.SendWait(lettre.ToString());
}
System.Threading.Thread.Sleep(10);
SendKeys.SendWait("{ENTER}");
}
}
}
And
和
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
namespace Abyte0
{
static class MouseHandler
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
public static void moveMouse(ref int currentx, ref int currenty, string whattodo, int pNombre)
{
switch (whattodo)
{
case "addX":
for (int i = 0; i < pNombre; i++)
{
currentx++;
SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
}
break;
case "addY":
for (int i = 0; i < pNombre; i++)
{
currenty++;
SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
}
break;
case "remX":
for (int i = 0; i < pNombre; i++)
{
currentx--;
SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
}
break;
case "remY":
for (int i = 0; i < pNombre; i++)
{
currenty--;
SetCursorPos(currentx + Form1.m_Border_x, currenty + Form1.m_Border_y);
}
break;
default:
break;
}
}
#region Mouse Left, Right1, Right2 Clicks
public static void DoMouseLeftClick(int nx, int ny)
{
Random objRandom = new Random();
SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
mouse_event(MOUSEEVENTF_LEFTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Thread.Sleep(objRandom.Next(1, 332));
mouse_event(MOUSEEVENTF_LEFTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
// Thread.Sleep(objRandom.Next(objRandom.Next(10, objRandom.Next(180, 600)), objRandom.Next(objRandom.Next(666, 4000), 5102)));
Handler.getFocus();
}
public static void DoMouseLeftClick(int[] pTab)
{
int nx = pTab[0];
int ny = pTab[1];
Random objRandom = new Random();
SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
mouse_event(MOUSEEVENTF_LEFTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Thread.Sleep(objRandom.Next(1, 332));
mouse_event(MOUSEEVENTF_LEFTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
// Thread.Sleep(objRandom.Next(objRandom.Next(10, objRandom.Next(180, 600)), objRandom.Next(objRandom.Next(666, 4000), 5102)));
Handler.getFocus();
}
public static void DoMouseRightClickOp1(int nx, int ny)
{
Random objRandom = new Random();
SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
mouse_event(MOUSEEVENTF_RIGHTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Thread.Sleep(objRandom.Next(6, 237));
mouse_event(MOUSEEVENTF_RIGHTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Handler.getFocus();
Thread.Sleep(objRandom.Next(1, 332));
moveMouse(ref nx, ref ny, "addY", 20);
DoMouseLeftClick(nx, ny);
}
public static void DoMouseRightClickOp2(int nx, int ny)
{
Random objRandom = new Random();
SetCursorPos(nx + Form1.m_Border_x, ny + Form1.m_Border_y);
mouse_event(MOUSEEVENTF_RIGHTDOWN, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Thread.Sleep(objRandom.Next(6, 237));
mouse_event(MOUSEEVENTF_RIGHTUP, nx + Form1.m_Border_x, ny + Form1.m_Border_y, 0, 0);
Handler.getFocus();
Thread.Sleep(objRandom.Next(1, 332));
moveMouse(ref nx, ref ny, "addY", 25);
DoMouseLeftClick(nx, ny);
}
#endregion
public static void DoSimpleClickNoFocus(int x,int y)
{
Random objRandom = new Random();
SetCursorPos(x,y);
mouse_event(MOUSEEVENTF_RIGHTDOWN, x, y, 0, 0);
Thread.Sleep(objRandom.Next(7, 258));
mouse_event(MOUSEEVENTF_LEFTUP, x,y, 0, 0);
}
}
}
回答by Abyte0
If I corectly understand, you want to inject a click event inside an application without having to move the mouse, like a game bot, so the user don't see sumthing is using his mouse and keyboard...
如果我正确理解,您希望在无需移动鼠标的情况下在应用程序中注入一个点击事件,就像游戏机器人一样,这样用户就看不到 sumthing 正在使用他的鼠标和键盘......
If im right, then look at the reply at this link, it may be what you want...
如果我是对的,那么看看这个链接的回复,它可能是你想要的......
its in c++ but well not a big matter I guess...
它在 C++ 中,但我想这不是什么大问题......
http://social.msdn.microsoft.com/Forums/en-SG/vcgeneral/thread/e0071733-286a-4b4d-b294-685f8a788fb8
http://social.msdn.microsoft.com/Forums/en-SG/vcgeneral/thread/e0071733-286a-4b4d-b294-685f8a788fb8