[RESOLVED] SendMessage for a game
Hi,
I'm part of a MMORPG gaming community. Some time ago I decided to write a very simple but useful tool for the players. Let me tell you how should it work ideally. As a generic MMORPG one of its parts is levelling up, namely just holding down right mouse button while your character kills monsters around it. You can even put something on your right mouse button and go outside, but unfortunately you will have to buy a new mouse quite often then. It would be very good to hide the game and let players browsing Internet while their character is levelling up. So, this is an abstract algorithm of my application actions:
1. User starts the procedure by hitting a "start" key
2. Hide the game window and send a right mouse button signal to it
3. User does whatever he wants, e.g. doing his homework on PC, but nothing should stop the right mouse button signal in the game window
4. User stops the procedure by hitting a "stop" key
5. Restore the game window and stop "holding" right mouse button in it
This tool is legit, it's not a bot, because the levelling is not the most important part of the game. Also, the game has an anti-cheat system.
So, I divided my task to few small functions and started to write them, but I have problems with it. I was trying to test a part which should send right mouse button signals if user presses a key. Assuming that hMU is the valid handle to the game window, this is my WndProc
Code:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
{
if (wParam == VK_F11)
{
SendMessage(hMU, WM_RBUTTONDOWN, 0, 0);
}
else if (wParam == VK_F12)
{
SendMessage(hMU, WM_RBUTTONUP, 0, 0);
}
break;
}
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
The problem is that nothing happens when I press F11 or F12. Neither PostMessage, SendMessage, nor SendInput worked for me (I used SendInput for testing only, it's definitely not what I need for my application). Why it is so, what should I do for reaching my goal? I'm using GNU C compiler.
Any help will be greatly appreciated. Thank you!
P.S. I'm sorry for my English which is far from good, and also I'm sorry for the lenght of my post, however I tried to make it smaller.
Re: SendMessage for a game
Quote:
Originally Posted by
PointToZero
The problem is that nothing happens when I press F11 or F12. Neither PostMessage, SendMessage, nor SendInput worked for me ...
How did you test it? Did you debug this code?
Re: SendMessage for a game
Quote:
Originally Posted by
VictorN
How did you test it? Did you debug this code?
Yes, I ran the game, then run this code. I pressed F11/F12 while my application window was on top, but nothing changed in the game.
Re: SendMessage for a game
"run" and "debug" are two absolutely different things!
Re: SendMessage for a game
Quote:
Originally Posted by
VictorN
"run" and "debug" are two absolutely different things!
I'm sorry, now I got what you mean. The handle to the game window is correct, Spy++ showed the same. This code works perfectly with notepad:
Code:
HWND hMU = FindWindow(NULL, "Untitled - Notepad");
hMU = FindWindowEx(hMU, NULL, "EDIT", NULL);
The game window has several child windows, they all are "EDIT"s. I tried to loop through them using EnumChildWindows, each time sending both WM_RBUTTONDOWN and WM_RBUTTONUP, but each time I was getting the click outside the game, on the line that divides desktop from taskbar.
Re: SendMessage for a game
Re: SendMessage for a game
I recently created a similar tool for a friend of mine. I used PostMessage() instead of SendMessage().
I wish I could give a good reference but I had to lose myself in google to find the information I was looking for and eventually just looked at enough examples.
I think you need to give your mouseclick some coordinates. Try something like this:
Code:
int mouseX = 200;
int mouseY = 100;
PostMessage(hMU, WM_LBUTTONDOWN, 0, MAKELPARAM(mouseX,mouseY))
Victor, I also tried to put this through a debugger without an LPARAM to see what would happen. I stepped through it until reaching the PostMessage call but had no idea what I was looking for....What sort of thing should you see that is out of the ordinary from the debugger?
Re: SendMessage for a game
Quote:
Originally Posted by
Austin.Soucy
I recently created a similar tool for a friend of mine. I used PostMessage() instead of SendMessage().
I wish I could give a good reference but I had to lose myself in google to find the information I was looking for and eventually just looked at enough examples.
I think you need to give your mouseclick some coordinates. Try something like this:
Code:
int mouseX = 200;
int mouseY = 100;
PostMessage(hMU, WM_LBUTTONDOWN, 0, MAKELPARAM(mouseX,mouseY))
Victor, I also tried to put this through a debugger without an LPARAM to see what would happen. I stepped through it until reaching the PostMessage call but had no idea what I was looking for....What sort of thing should you see that is out of the ordinary from the debugger?
Thanks, but unfortunately this didn't work either. I checked in Spy++ if the message reaches the window, and yes, it does.
Re: SendMessage for a game
Re: SendMessage for a game
Quote:
Originally Posted by
Marc G
This is how I modified my WndProc according to your advice:
Code:
if (wParam == VK_F11)
{
SetWindowPos(hMU, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
INPUT input;
memset(&input, 0, sizeof(INPUT));
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
SendInput(1, &input, sizeof(INPUT));
}
The code worked because of SetWindowPos, but I don't need the game window to be HWND_TOP all the time. When I added this line to the end of my if statement, it stopped to work:
Code:
SetWindowPos(hMU, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
Re: SendMessage for a game
Yes, sorry my mistake. The window should be focussed for SendInput.
Are you sure you are giving the correct coordinates to your postmessage mouse messages? Are you sure the coordinates you send are in client coordinates?
Are you sure you are posting them to the correct child window of the target window, if any child windows?
Re: SendMessage for a game
Quote:
Originally Posted by
Marc G
Yes, sorry my mistake. The window should be focussed for SendInput.
Are you sure you are giving the correct coordinates to your postmessage mouse messages? Are you sure the coordinates you send are in client coordinates?
Are you sure you are posting them to the correct child window of the target window, if any child windows?
Yes, I'm sure the coordinates are correct, I also tried ScreenToClient:
Code:
POINT pt;
pt.x = 100;
pt.y = 100;
ScreenToClient(hMU, &pt);
SendMessage(hMU, WM_RBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
SendMessage(hMU, WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
The window I'm trying to post the messages is the main game window. It has seven or eight child windows, and when I tried to call the above function for each of them, I got a popup menu like Edit controls have on my desktop.
Re: SendMessage for a game
Quote:
Originally Posted by
PointToZero
Yes, I'm sure the coordinates are correct, I also tried ScreenToClient:
Code:
POINT pt;
pt.x = 100;
pt.y = 100;
ScreenToClient(hMU, &pt);
SendMessage(hMU, WM_RBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
SendMessage(hMU, WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
The window I'm trying to post the messages is the main game window. It has seven or eight child windows, and when I tried to call the above function for each of them, I got a popup menu like Edit controls have on my desktop.
You are using WM_RBUTTONDOWN, don't you need WM_LBUTTONDOWN?
Try looping through the child windows and storing them in HWND hWnd[10]; Then use PostMessage() to send a WM_LBUTTONDOWN to each child window one at a time with coords like 100x100(something that will not extend outside the window you need it, you can always adjust later).
When you detect the click in the window you want it take note of the array index you are on. Change your code to focus on that index and then play with your X and Y to aim your shot.
1 Attachment(s)
Re: SendMessage for a game
Quote:
Originally Posted by
Austin.Soucy
You are using WM_RBUTTONDOWN, don't you need WM_LBUTTONDOWN?
Try looping through the child windows and storing them in HWND hWnd[10]; Then use PostMessage() to send a WM_LBUTTONDOWN to each child window one at a time with coords like 100x100(something that will not extend outside the window you need it, you can always adjust later).
When you detect the click in the window you want it take note of the array index you are on. Change your code to focus on that index and then play with your X and Y to aim your shot.
Yes, I need to send right mouse button click. So, I followed your advice and modified a little my code:
Code:
HWND handles[10];
int i;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) { return (BOOL)(handles[i++] = hwnd); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
...
case WM_KEYDOWN:
{
if (wParam == VK_F11)
{
EnumChildWindows(hMU, EnumChildProc, 0);
i = 0;
}
else if (wParam == VK_F12)
{
POINT pt;
pt.x = 100;
pt.y = 100;
ScreenToClient(hMU, &pt);
SendMessage(handles[i], WM_RBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
SendMessage(handles[i++], WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
}
else if (wParam == VK_F1)
{
char index[2];
sprintf(index, "%d", i);
MessageBox(NULL, index, NULL, 0);
}
break;
...
Then I run it and pressed F11 so it found all child windows of the game. Then I was pressing F12 for each of them, but each time I received a click outside the game. I've attached the screenshot of it. I was clicking around that place, but I couldn't call the same menu!
Re: SendMessage for a game
Quote:
Originally Posted by
PointToZero
ScreenToClient(hMU, &pt);
Try passing your child windows to this before the click.
Code:
ScreenToClient(handles[i], &pt);
You can also use ShowWindow() to maximize your window and then work with screen coords(probably not the best way, but it works).
EDIT: How do you find hMU?
if you are using this like in your previous post it might be a source for error.
Code:
HWND hMU = FindWindow(NULL, "Untitled - Notepad");
hMU = FindWindowEx(hMU, NULL, "EDIT", NULL);
you should only need
Code:
HWND hMU = FindWindow(NULL, "APP TITLE");
and then find the child windows normally with EnumChildWindow