SendMessage click (работает только при наведении указателя мыши на кнопку)

Я делал это раньше, но с этой конкретной кнопкой это не работает!

Если я нажимаю кнопку вручную, создается новое окно (мини-карта): Изображение

/////// Но программно я могу видеть анимацию на кнопке, как если бы она была нажата gif,

Но окно (мини-карта) не появляется.

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

Мини-карта создается только в том случае, если курсор мыши находится над кнопкой, когда мой код отправляет сообщения.

Вот 10-секундное видео на YouTube: видео,

Примечание: в видео я не нажимал кнопку мышкой, апросто зависал.

ОБНОВЛЕНИЕ 1: изображение сообщений Spy++

UPDATE2: игра использует GetCursorPos и ​​WindowFromPoint, чтобы получить дескриптор окна под курсором и сравнить его с дескриптором кнопки, мне нужно выяснить, как подключить WindowFromPoint для отправки дескриптора кнопки, даже если игра находится в фоновом режиме.

1 ответ

Решение

Я нашел ответ,

Прежде всего, мне пришлось перепроектировать игру,

И я обнаружил, что он использует WindowFromPoint, чтобы получить дескриптор окна под текущей позицией курсора и сравнить его с дескриптором кнопки.

Это означает, что бот не будет работать, пока игра находится в фоновом режиме.

Поэтому мне пришлось выяснить, как перехватить вызов WindowFromPoint и изменить возвращаемое значение, чтобы я мог отправить дескриптор кнопки, даже если игра находится в фоновом режиме.

Для этого я использовал эту библиотеку: Deviare.

А вот краткое руководство по его использованию.

Вот мой код:

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);
    }
}
Другие вопросы по тегам