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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:18:28  来源:igfitidea点击:

Using SendMessage to simulate mouse clicks

c#clickmousesimulate

提问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 SetForegroundWindowto 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.exeis 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 hWndin SendMessage, but didn't work as well. The whole code you can find here.

我用我以前的手柄也试过hWndSendMessage,却没有正常工作。你可以在这里找到完整的代码。

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 SendInputfunction.

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