4

I want to set up text in edit box programatically in other program, which is a game app and using directX, but running in window mode. I'm doing this:

HWND hWnd = FindWindow(NULL,"Game");
HWND edit = FindWindowEx(hWnd, NULL, "Edit", NULL);

SendMessage(edit, WM_CHAR, (TCHAR) 'H', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'E', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'L', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'L', 0);
SendMessage(edit, WM_CHAR, (TCHAR) 'O', 0);

this not working for me.... but some how once worked. I think I misunderstood something, maybe it must focus on edit control, then set cursor then paste text and then disable focus... I realy don't know much...please save my time and nervs, tell me how to make it working....

I tried this too, and not working:

SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"text");

hwnd is correct, but text is not updated... it send to correct handle, but not updated.... I think I need somehow to focus or update, once it updated successful, but I didnt realized what happened...so code worked once, but no more working... why one time it worked?

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Jigberto
  • 1,513
  • 7
  • 27
  • 50
  • 2
    Why don't you just use `WM_SETTEXT` rather than attempting to fake typing? – David Heffernan Apr 02 '12 at 22:36
  • @David Heffernan I tried this, but not working: SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"MyText"); I think I need to set focus or other thing to do before I set text...but how? – Jigberto Apr 02 '12 at 22:40
  • 2
    There is no error checking on the FindWindow calls. Are they working? You must have done some debugging, yes? – Martin James Apr 02 '12 at 22:40
  • 2
    If you can't get `WM_SETTEXT` to work, nothing will work. Absolutely no need to set focus before `WM_SETTEXT`. You are thinking of `SendInput`, but you aren't doing that. Martin is quite probably right. If you don't check errors then anything could be wrong. – David Heffernan Apr 02 '12 at 22:42
  • @David Heffernan hwnd is correct, but text is not updated... it send to correct handle, but not updated.... I think I need somehow to focus or update, once it updated successful, but I didnt realized what happened...so code worked once, but no more working... – Jigberto Apr 02 '12 at 22:44
  • Still no need to set focus before sending `WM_SETTEXT`. Are you sure it's really an EDIT control? – David Heffernan Apr 02 '12 at 22:46
  • SendMessage() also returns an LRESULT - you should check that as well. – Martin James Apr 02 '12 at 22:47
  • @user1267305 interesting project on freelancer :) – karlphillip Apr 03 '12 at 18:45
  • @DavidHeffernan The game has a built-in mechanism that prevents the WM_SETTEXT method from working. =( Check my answer for more info on the problem. – karlphillip Apr 04 '12 at 13:55

2 Answers2

4

Your question is money! Seriously. Let's say a little bird told me what's the game you are interested at (starts with an S). I've spent a few hours myself on this problem and I've had some success, so I'll share it with you.

There's a tool named Spy++ (from Microsoft) that let's you watch messages that are sent to a window/class. This is great for debugging because it allows you to monitor the messages that are sent to the EDIT box when a key is pressed on your keyboard, so you can find out the exact calls and parameters that are send to the game to simulate this operation.

Use spy++ to open the game process, and once you are in Game's login window you will see that spy++ reports several threads opened in this process, but only one thread is going to have 3 EDIT boxes. That is the thread you are interested at!

Also notice that neither of the EDIT boxes have caption, so the following code will never work:

HWND edit = FindWindowEx(hWnd, NULL, "Edit", NULL);

and by the way, always make sure that FindWindowEx() returns something valid, else how would you know that it succeeded finding the edit box?

What you should do instead is:

HWND edit = FindWindowEx(hWnd, NULL, "", NULL);
if (!edit)
{
    // report error
}

And this will find the first EDIT box. This box corresponds to the username box. The game uses 3 PostMessage() calls to simulate a key press, and not SendMessage() as you were trying:

// "..." means you need to find out the other parameters
PostMessage(edit, WM_KEYDOWN, ...); 
PostMessage(edit, WM_CHAR, ...); 
PostMessage(edit, WM_KEYUP, ...); 

Spy++ will reveal what the other parameters are, don't worry. You will probably spend some time figuring out how the last parameter of the call is built (because it's a mask).

I haven't been able to send keys to the game if it was minimized or without focus. You will have to figure this one out. For testing purposes, use can use SetForegroundWindow(window_hwnd); and some more stuff to focus the window.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
2

Look for the source code to Autoit. Autoit is able to send keys/mouse to just about anything. When newer versions of Kaspersky Anti Virus are installed, it messes with SendMessage|SendInput type things between processes.

Edit: For the folks who point out that Autoit is a huge lump of code to dig through to accomplish this task:

Autoit is able to send input to background apps that do not want to see injected input. It is not a trivial task easily done. There are games out there that do not want to see any scripted input of any form and they go out of their way to prevent it. Also, there are AV solutions in the wild that block inter-process input injection. Autoit somehow works around the blocks in a lot of cases.

JimR
  • 15,513
  • 2
  • 20
  • 26
  • Nice point about the AV software - I've had problems with Kaspersky too, (but not this one, yet..). – Martin James Apr 02 '12 at 22:50
  • 2
    Is your answer really to download the no doubt huge body of source code for Autoit and hunt around trying to understand it? Doesn't sound the most productive approach to me. – David Heffernan Apr 02 '12 at 22:50
  • This program to which I want to send text is a game, and it hide edit box if mouse is moved cursor out and it show when mouse cursor is move up, ... so maybe it must be focused or enabled before I send text to it, but I dont know how to do that.... I try to see in Spy++ and it show messages..... – Jigberto Apr 02 '12 at 23:01
  • @DavidHeffernan is surely right - it is not necessary to focus an edit before setting its text. If it was, most of my apps would not work! – Martin James Apr 02 '12 at 23:04
  • @user1267305 It seems that you have already decided that you know what the problem is. In which case why are you asking a question? Or, put another way, why does you question talk about sending `WM_CHAR` messages? You have decided that your problem is setting the focus to a particular edit control. You won't take any suggestions from us. If you want to know how to set the focus then ask that very question. – David Heffernan Apr 02 '12 at 23:08
  • @David Heffernan how to set focus ? – Jigberto Apr 02 '12 at 23:14
  • @user Doesn't sound like focus is the issue. Perhaps you are using the wrong term. Focus has a very specific meaning. Sounds like mouse presence over the window is what counts. Did you try putting mouse in the window. – David Heffernan Apr 02 '12 at 23:21
  • If you want it to work consistently, find the code in Autoit and use it. It works 95% of the time. `SendInput` and `SendMessage` are not reliable. You can send input to a background process consistently with Autoit as well. – JimR Apr 02 '12 at 23:47
  • @MartinJames: Try it with a good AV running or an app that doesn't want you injecting input. Or in certain apps that do not have focus. – JimR Apr 03 '12 at 00:41
  • I wouldn't label AV that interferes with input injection as "good." I would label it almost as bad as malware. In any case, I second @DavidHeffernan in asking, seriously? Your answer is to download a huge code base and search for the few lines of code that accomplish what he wants? This is not an answer. – Carey Gregory Apr 03 '12 at 13:11
  • @CareyGregory and DavidHeffernan: I know it works but I'm not willing to dig back into and post exactly what to do. And it is not a few lines of code. Have you done it? I wrote an input injector for a few online games back in the day. Most if not all of the games did not want input from `SendInput` or `SendMessage` from outside their process. Everything I tried with the exception of the code from Autoit or, maybe AutoHotkey, failed. It gets really tough when the target app doesn't have focus as it's easier to detect scripted input. As for AV interfering... Some people want that. – JimR Apr 03 '12 at 16:16
  • @user1267305: I would rather not post my details here. Based on what karlphillip told you, you should at least try autoit to see if it solves your problem. If you tell me the name of the software you're trying to automate, maybe I can make time to check it. However, this will not happen before Tuesday. If autoit doesn't work, have a look here: http://www.gamedev.net/topic/550264-dinput-and-global-key-hooks-vistawin7/ – JimR Apr 05 '12 at 18:05