使用SendMessage模拟鼠标点击

4

我需要什么

模拟消息(主要是鼠标,但也包括键盘)而不移动光标。消息发送到焦点窗口(首先,我想适用于最小化的窗口,但我没有找到如何做到这一点,所以我使用SetForegroundWindow将其聚焦)。

我找到了什么

这个问题上,我发现我需要使用来自user32.dll的pInvoked。我还找到了一个小的代码示例,但它没有起作用。

我还发现了类似的问题。那个人使用了mouse_event,但它已被弃用。此函数以毫米为单位获取X和Y坐标。我尝试使用SendMessage转换我的坐标,但失败了。

你能给一个示例吗?

当然可以。打开notepad.exe,我需要在位于(1210,460)的按钮上执行右键单击。

我尝试过什么

根据我在这里找到的示例,我编写了以下代码:

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);
}

我还尝试在SendMessage中使用之前的句柄 hWnd,但同样无法运作。你可以在这里找到整段代码。
提前致谢。

你没有在 SendMessage 中传递任何位置信息。如果你将他的代码中的答案整合到你的代码中,这个关于鼠标按钮事件导致 SendMessage 崩溃的问题将会得到解决。参考链接:https://dev59.com/FljUa4cB1Zd3GeqPT7ZO。 - user7116
但它确实移动了光标。我尝试了这个答案https://dev59.com/c2sz5IYBdhLWcg3wQFe2#8022534,它有效,但会移动光标。 - Doon
即使使用UIAutomation也会移动光标... - user7116
3个回答

4

没错!我会查看这个链接。谢谢。 - Doon

3

这是我年少时制作的鼠标和键盘处理程序,用于在游戏屏幕上查找颜色并点击||右键+选项:P

也许即使代码是法语的,但其中的一些代码可能对您有所帮助...

        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}");
        }
    }
}

并且
    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);
        }

    }
}

3
Raymond Chen 为你写了一篇博客文章:你不能使用PostMessage模拟键盘输入。我知道你需要的是鼠标,不是键盘,而且你使用的是Send而不是Post,但是同样的问题也适用于你。请阅读这个链接。幸运的是,它还包含了解决方案:使用SendInput函数。

合成按键、鼠标移动和按钮点击。


谢谢。我在这里找到了答案(https://dev59.com/c2sz5IYBdhLWcg3wQFe2#8022534),并且它起作用了,但是会移动光标。我尝试在此行上删除标志`MouseEventFlags.MOUSEEVENTF_MOVE`: mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE | MouseEventFlags.MOUSEEVENTF_ABSOLUTE;,但它停止工作了。 - Doon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接