WINAPI SendMessage 到特定区域的 hWnd
WINAPI SendMessage to a hWnd in a specific area
所以基本上我得到了一个 Window 处理程序,它是一个包含 16 个插槽的图片(矩形)。
嗯,所以我想对这个 hWnd 使用 SendMessage 并将 keyPressed 作为消息传递给第一个和第二个插槽(因为它们不是单独的 windows,我不能占用每个插槽window句柄)。问题在于实现这些偏移量以设置我要发送这些消息的区域。
基本上,我正在为一款离线游戏制作培训师,以练习内存管理方面的内容并了解 WINAPI 的工作原理。这是代码(不包括 DllMain 函数)。
#include <windows.h>
#include <stdio.h>
#define VIDAACTUAL 0x70D27E
#define VIDAMAX 0x70D27C
#define MANAACTUAL 0x70D282
#define MANAMAX 0x70D280
void AutoPot(){
Sleep(5000); //Giving myself time to place the cursor.
POINT P;
GetCursorPos(&P);
HWND hwnd = WindowFromPoint(P);
Sleep(50);
while (1){
WORD hpMax = *(WORD*)(VIDAMAX);
WORD hpAct= *(WORD*)(VIDAACTUAL);
WORD mpMax = *(WORD*)(MANAMAX);
WORD mpAct = *(WORD*)(MANAACTUAL);
if (hpAct != 0)
{
if (hpAct != hpMax)
{
SendMessage(hwnd, WM_LBUTTONUP, 0, 0);
//SendMessage(hwnd, WM_LBUTTONDBLCLK, 0, 0);
//SendMessage(hwnd, VK_SPACE, 0, 0);
}
else if (mpAct!= mpMax && mpMax != 0){ //Giving priority to red pots.
SendMessage(hwnd, WM_LBUTTONUP, 0,0);
//SendMessage(hwnd, WM_LBUTTONDBLCLK, 0,0);
//SendMessage(hwnd, VK_SPACE, 0, 0);
}
}
Sleep(50);
}
}
那么,有没有办法 select hWnd 中的特定区域来发送这些消息?
Windows 将鼠标消息发送到基于左上角的 window。所以 window 的左上角是 (0,0)。如果您知道要向其发送消息的项目的位置,则在您的发送消息中传递它们。如果不是,你将不得不调用 getClientRect(hWnd...) 并做一些数学运算:)
//we get the client rect
RECT rect;
GetClientRect(hWnd, &rect);
//rect = { LONG top, left, right bottom }
//i guess here we divide the rect into 4x4 squares (no idea of your layout)
//so pick a square to get xpos and ypos
int x, y; //can't calculate these i have no idea of your layout
LPARAM lParam = MAKELPARAM(x, y);
PostMessage(hWnd, WM_LBUTTONDOWN, 0, lParam); //NOT SendMessage!!!
美中不足的是windows将WM_LBUTTON消息坐标解释为屏幕坐标。在那种情况下,我们必须向后工作。弄清楚我们要在客户区中单击的位置后,我们需要知道该位置的屏幕坐标。在那种情况下,我们使用(一位好心的用户指出它不翻译坐标所以忽略这个位 - 只需发送客户端坐标)
POINT thePointWeWantOnTheClient;
ClientToScreen(hWnd, &thePointWeWantOnTheClient);
并改用这一点。直到明天早上我才能测试这个。
值得指出的是,SendMessage 正在阻塞,因此它会阻塞 GUI。 PostMessage 只是在你想要的消息队列中填充。
您在发送消息时没有指定正确的鼠标坐标。 GetCursorPos()
returns当前鼠标在屏幕坐标中的位置,然后在发送鼠标时需要将其转换为客户端坐标发给 window 的消息,例如:
#include <windows.h>
#include <stdio.h>
#define VIDAACTUAL 0x70D27E
#define VIDAMAX 0x70D27C
#define MANAACTUAL 0x70D282
#define MANAMAX 0x70D280
void AutoPot()
{
Sleep(5000); //Giving myself time to place the cursor.
POINT P;
GetCursorPos(&P);
HWND hwnd = WindowFromPoint(P);
ScreenToClient(hwnd, &P); // <-- here
Sleep(50);
while (1){
WORD hpMax = *(WORD*)(VIDAMAX);
WORD hpAct= *(WORD*)(VIDAACTUAL);
WORD mpMax = *(WORD*)(MANAMAX);
WORD mpAct = *(WORD*)(MANAACTUAL);
if (hpAct != 0)
{
if (hpAct != hpMax)
{
PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(P.x, P.y));
//PostMessage(hwnd, WM_LBUTTONDBLCLK, 0, MAKELPARAM(P.x, P.y));
}
else if ((mpAct != mpMax) && (mpMax != 0)) //Giving priority to red pots.
{
PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(P.x, P.y));
//PostMessage(hwnd, WM_LBUTTONDBLCLK, 0, MAKELPARAM(P.x, P.y));
}
}
Sleep(50);
}
}
仅供参考,VK_SPACE
不是有效的消息标识符(其值为 0x20
,与 WM_SETCURSOR
消息的值相同)。您将不得不使用 WM_KEYDOWN
和 WM_KEYUP
,而是直接使用 and/or WM_CHAR
。然而,you can’t simulate keyboard input with PostMessage.
所以基本上我得到了一个 Window 处理程序,它是一个包含 16 个插槽的图片(矩形)。
嗯,所以我想对这个 hWnd 使用 SendMessage 并将 keyPressed 作为消息传递给第一个和第二个插槽(因为它们不是单独的 windows,我不能占用每个插槽window句柄)。问题在于实现这些偏移量以设置我要发送这些消息的区域。
基本上,我正在为一款离线游戏制作培训师,以练习内存管理方面的内容并了解 WINAPI 的工作原理。这是代码(不包括 DllMain 函数)。
#include <windows.h>
#include <stdio.h>
#define VIDAACTUAL 0x70D27E
#define VIDAMAX 0x70D27C
#define MANAACTUAL 0x70D282
#define MANAMAX 0x70D280
void AutoPot(){
Sleep(5000); //Giving myself time to place the cursor.
POINT P;
GetCursorPos(&P);
HWND hwnd = WindowFromPoint(P);
Sleep(50);
while (1){
WORD hpMax = *(WORD*)(VIDAMAX);
WORD hpAct= *(WORD*)(VIDAACTUAL);
WORD mpMax = *(WORD*)(MANAMAX);
WORD mpAct = *(WORD*)(MANAACTUAL);
if (hpAct != 0)
{
if (hpAct != hpMax)
{
SendMessage(hwnd, WM_LBUTTONUP, 0, 0);
//SendMessage(hwnd, WM_LBUTTONDBLCLK, 0, 0);
//SendMessage(hwnd, VK_SPACE, 0, 0);
}
else if (mpAct!= mpMax && mpMax != 0){ //Giving priority to red pots.
SendMessage(hwnd, WM_LBUTTONUP, 0,0);
//SendMessage(hwnd, WM_LBUTTONDBLCLK, 0,0);
//SendMessage(hwnd, VK_SPACE, 0, 0);
}
}
Sleep(50);
}
}
那么,有没有办法 select hWnd 中的特定区域来发送这些消息?
Windows 将鼠标消息发送到基于左上角的 window。所以 window 的左上角是 (0,0)。如果您知道要向其发送消息的项目的位置,则在您的发送消息中传递它们。如果不是,你将不得不调用 getClientRect(hWnd...) 并做一些数学运算:)
//we get the client rect
RECT rect;
GetClientRect(hWnd, &rect);
//rect = { LONG top, left, right bottom }
//i guess here we divide the rect into 4x4 squares (no idea of your layout)
//so pick a square to get xpos and ypos
int x, y; //can't calculate these i have no idea of your layout
LPARAM lParam = MAKELPARAM(x, y);
PostMessage(hWnd, WM_LBUTTONDOWN, 0, lParam); //NOT SendMessage!!!
美中不足的是windows将WM_LBUTTON消息坐标解释为屏幕坐标。在那种情况下,我们必须向后工作。弄清楚我们要在客户区中单击的位置后,我们需要知道该位置的屏幕坐标。在那种情况下,我们使用(一位好心的用户指出它不翻译坐标所以忽略这个位 - 只需发送客户端坐标)
POINT thePointWeWantOnTheClient;
ClientToScreen(hWnd, &thePointWeWantOnTheClient);
并改用这一点。直到明天早上我才能测试这个。
值得指出的是,SendMessage 正在阻塞,因此它会阻塞 GUI。 PostMessage 只是在你想要的消息队列中填充。
您在发送消息时没有指定正确的鼠标坐标。 GetCursorPos()
returns当前鼠标在屏幕坐标中的位置,然后在发送鼠标时需要将其转换为客户端坐标发给 window 的消息,例如:
#include <windows.h>
#include <stdio.h>
#define VIDAACTUAL 0x70D27E
#define VIDAMAX 0x70D27C
#define MANAACTUAL 0x70D282
#define MANAMAX 0x70D280
void AutoPot()
{
Sleep(5000); //Giving myself time to place the cursor.
POINT P;
GetCursorPos(&P);
HWND hwnd = WindowFromPoint(P);
ScreenToClient(hwnd, &P); // <-- here
Sleep(50);
while (1){
WORD hpMax = *(WORD*)(VIDAMAX);
WORD hpAct= *(WORD*)(VIDAACTUAL);
WORD mpMax = *(WORD*)(MANAMAX);
WORD mpAct = *(WORD*)(MANAACTUAL);
if (hpAct != 0)
{
if (hpAct != hpMax)
{
PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(P.x, P.y));
//PostMessage(hwnd, WM_LBUTTONDBLCLK, 0, MAKELPARAM(P.x, P.y));
}
else if ((mpAct != mpMax) && (mpMax != 0)) //Giving priority to red pots.
{
PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(P.x, P.y));
//PostMessage(hwnd, WM_LBUTTONDBLCLK, 0, MAKELPARAM(P.x, P.y));
}
}
Sleep(50);
}
}
仅供参考,VK_SPACE
不是有效的消息标识符(其值为 0x20
,与 WM_SETCURSOR
消息的值相同)。您将不得不使用 WM_KEYDOWN
和 WM_KEYUP
,而是直接使用 and/or WM_CHAR
。然而,you can’t simulate keyboard input with PostMessage.