SendMessage 单击(仅当鼠标悬停在按钮上时有效)
SendMessage click (works only if the mouse is over the button)
我以前做过这个,但是用这个特定的按钮,它不起作用!
如果我手动单击按钮 ,它会创建一个新的 window(小地图):
Image
///////
但是以编程方式我可以在按钮上看到动画,就好像它被点击了一样gif,
但是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);
只有在我的代码发送消息时鼠标悬停在按钮上才会创建迷你地图。
这是一段 10 秒的 YouTube 视频:Video,
注意:在视频中,我没有用鼠标点击按钮,
刚刚悬停了
更新1: Spy++ Messages Image
UPDATE2:游戏使用GetCursorPos和WindowFromPoint获取光标下window的句柄并与按钮的句柄进行比较,我需要计算了解如何挂钩 WindowFromPoint 以发送按钮的句柄,即使游戏在后台也是如此。
我找到了答案,
首先,我不得不对游戏进行逆向工程,
而且我发现它正在使用 WindowFromPoint 获取当前光标位置 下 window 的句柄并将其与按钮的手柄。
这意味着当游戏在后台运行时,机器人将无法运行。
所以我不得不弄清楚如何 挂钩 WindowFromPoint 调用并更改 return 值,这样我就可以发送按钮的句柄 even如果游戏在后台。
我使用这个库来做到这一点:Deviare.
这里是Quickstart如何使用它。
这是我的代码:
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);
}
}
我以前做过这个,但是用这个特定的按钮,它不起作用!
如果我手动单击按钮 ,它会创建一个新的 window(小地图): Image
/////// 但是以编程方式我可以在按钮上看到动画,就好像它被点击了一样gif,
但是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);
只有在我的代码发送消息时鼠标悬停在按钮上才会创建迷你地图。
这是一段 10 秒的 YouTube 视频:Video,
注意:在视频中,我没有用鼠标点击按钮, 刚刚悬停了
更新1: Spy++ Messages Image
UPDATE2:游戏使用GetCursorPos和WindowFromPoint获取光标下window的句柄并与按钮的句柄进行比较,我需要计算了解如何挂钩 WindowFromPoint 以发送按钮的句柄,即使游戏在后台也是如此。
我找到了答案,
首先,我不得不对游戏进行逆向工程,
而且我发现它正在使用 WindowFromPoint 获取当前光标位置 下 window 的句柄并将其与按钮的手柄。
这意味着当游戏在后台运行时,机器人将无法运行。
所以我不得不弄清楚如何 挂钩 WindowFromPoint 调用并更改 return 值,这样我就可以发送按钮的句柄 even如果游戏在后台。
我使用这个库来做到这一点:Deviare.
这里是Quickstart如何使用它。
这是我的代码:
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);
}
}