简体   繁体   English

SendMessage 单击(仅当鼠标悬停在按钮上时有效)

[英]SendMessage click (works only if the mouse is over the button)

I've done this before, but with this specific button, it doesn't work!我以前做过这个,但是用这个特定的按钮,它不起作用!

If I click the button manually it creates a new window (mini-map): Image如果我手动单击按钮,它会创建一个新的 window (迷你地图): Image

/////// But Programmatically I can see the animation on the button as if it gets clicked gif , /////// 但是以编程方式,我可以在按钮上看到 animation ,就好像它被点击了gif一样,

But the window (mini-map) doesn't show up .但是 window(小地图)没有出现

            int x = 9, y = 8;
            IntPtr lParam = (IntPtr)((y << 16) | x);
            WinAPIs.PostMessage(button, WinAPIs.WM_LBUTTONDOWN, (IntPtr)0x01, lParam);
            WinAPIs.PostMessage(button, WinAPIs.WM_LBUTTONUP, IntPtr.Zero, lParam);

The mini-map is created only if the mouse is over the button when my code sends the messages.仅当我的代码发送消息时鼠标悬停在按钮上时,才会创建迷你地图。

Here's a 10-sec video on YT: Video ,这是 YT 上的 10 秒视频:视频

Notice: In the video, I didn't click the button with the mouse, I've just hovered it.注意:在视频中,我没有用鼠标点击按钮,我只是悬停在它上面。

UPDATE1: Spy++ Messages Image更新 1: Spy++ 消息图像

UPDATE2: the game is using GetCursorPos and WindowFromPoint to get the handle of the window under the cursor and compare it with the button's handle, I need to figure out how to hook WindowFromPoint to send the button's handle even if the game is in the background. UPDATE2:游戏正在使用 GetCursorPos 和 WindowFromPoint 获取 cursor 下的 window 的句柄并将其与按钮的句柄进行比较,我需要弄清楚如何挂钩 WindowFromPoint 以发送按钮的句柄,即使游戏在后台也是如此。

I've found the answer,我找到了答案,

First of all, I had to reverse-engineer the game,首先,我必须对游戏进行逆向工程,

And I've found that it's using WindowFromPoint to get the handle of the window under the current cursor's position and compare it with the button's handle.我发现它使用WindowFromPoint获取当前光标 position 下的 window 的句柄,并将其与按钮的句柄进行比较。

Meaning the bot will not work while the game is in the background.这意味着当游戏在后台运行时,机器人将无法运行。

So I had to figure out how to hook the WindowFromPoint call and change the return value , so I can send the button's handle even if the game is in the background.所以我必须弄清楚如何挂钩 WindowFromPoint 调用并更改返回值,这样即使游戏在后台运行,我也可以发送按钮的句柄。

I used this library to do so: Deviare .我使用这个库来这样做: Deviare

And here is a Quickstart of how to use it.这是如何使用它的快速入门

Here is my code:这是我的代码:

using System;
using System.Windows.Forms;
using Nektra.Deviare2;

public partial class Form1 : Form
{
    private NktSpyMgr _spyMgr;
    public Form1()
    {
        InitializeComponent();

        _spyMgr = new NktSpyMgr();
        _spyMgr.Initialize();
        _spyMgr.OnFunctionCalled += new DNktSpyMgrEvents_OnFunctionCalledEventHandler(OnFunctionCalled);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //Search for the game process
        var processes = System.Diagnostics.Process.GetProcessesByName("Conquer");
        int processID = 0;
        if (processes.Length < 1)
        {
            MessageBox.Show("Couldn't find Conquer", "Error");
            Environment.Exit(0);
        }
        else
        {
            //Found the game
            processID = processes[0].Id;
        }

        //Hook WindowFromPoint with 'flgOnlyPostCall' meaning OnFunctionCalled will be triggered after the api call and before the value returns to the game
        NktHook hook = _spyMgr.CreateHook("user32.dll!WindowFromPoint", (int)(eNktHookFlags.flgRestrictAutoHookToSameExecutable | eNktHookFlags.flgOnlyPostCall));
        hook.Hook(true);
        hook.Attach(processID, true);
        
        //Now send the button click and It works.
        int x = 9, y = 8;
        IntPtr lParam = (IntPtr)((y << 16) | x);
        WinAPIs.PostMessage((IntPtr)0x1D02D0, WinAPIs.WM_LBUTTONDOWN, (IntPtr)0x01, lParam);
        WinAPIs.PostMessage((IntPtr)0x1D02D0, WinAPIs.WM_LBUTTONUP, IntPtr.Zero, lParam);
    }

    private static void OnFunctionCalled(NktHook hook, NktProcess process, NktHookCallInfo hookCallInfo)
    {
        INktParam pRes = hookCallInfo.Result();

        //change the return value to whatever you want.. 0x1D02D0 here for example
        pRes.Value = new IntPtr(0x1D02D0);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM