Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

PostMessage /Controlsend and minimized (game) window


  • Please log in to reply
10 replies to this topic
karmadude
  • Members
  • 4 posts
  • Last active: Jul 21 2004 05:18 PM
  • Joined: 18 Jul 2004
I apologize if my questions are rather obtuse but I am rather new to the whole scripting thing in general, and only recently learned of AHK after researching AutoIT.

I know most of you employ AHK for far more respectable tasks, but I am interested in finding a way to utilize it to send keystrokes to a minimized window of a game I play called EverQuest.

I performed many searches and saw some previous posts about games such as ShadowBane, Starcraft, etc. etc. but have not found anyone seeking EQ related support, but the purpose of the script I want to write is very basic.

I have tested and found that the SEND command DOES work and will send keystrokes to the game window when it is active. However, I cannot seem to get Controlsend to function correctly. I am unsure if I am simply not identifying the window adequetely or if the game won't allow input in this manner.

I downloaded Winspector and checked the window messages while running my Controlsend script that sent a few characters to the EQ window and it does appear that the window was receiving some messages such as WM_KEYDOWN, WM_CHAR, and WM_KEYUP, etc. but the text didn't appear to make it to the game as it should have. Perhaps the control that allowed text simply wasn't "topmost", but I also tried using the ahk_parent parameter to no affect.

Then I figured maybe I needed to use PostMessage. Postmessage seems to be some pretty intensive stuff, and being a complete noob I am feeling alittle out of my league to figure it all out. I figured I needed to Postmessage WM_CHAR (0x102) and then find out what the damn code value was for the wparam and lparam for the key I wanted sent, but my attenpts at searching MSDN and Google for some sort of key code listing have been fruitless. The best I could find was simply checking character map, or using Winspector and hitting the key and seeing what the message indicated as the value. This however doesn't seem to match with other examples I have found for using PostMessage WM_CHAR, however.

So, my hope is someone might be able to help a poor hapless entertainment seeker such as myself out alittle bit and lend me a few pointers. Any information on why my game would allow the Send command, but would not allow Controlsend? or PostMessage?

Also, I tried the following script to get a feel for PostMessage, and it did not work on my system. It opened Workpad but did not type text in the text input control.

Run, wordpad
WinWait, Document -
WinActivate
start = 0
Loop
{
   PostMessage, 0x102, %start%, 1, RICHEDIT50W1
   ++start
   if start > 600  ; This test indicates that it's not receiving multi-byte chars.
      break
}

The only thing I can imagine is that either some Windows update patch prevents this from working, or something in my msconfig has been disabled that needs to be enabled.

Any help would be GREATLY appreciated, thanks!

beardboy
  • Members
  • 443 posts
  • Last active: May 27 2017 08:41 AM
  • Joined: 02 Mar 2004

Any information on why my game would allow the Send command, but would not allow Controlsend? or PostMessage?

I'm not sure, Chris could answer for sure.

Also, I tried the following script to get a feel for PostMessage, and it did not work on my system. It opened Workpad but did not type text in the text input control.

I ran your code example above, but had to change the Control from RICHEDIT50W1 to RICHEDIT20W1 to get it to work. When I first ran some tests with PostMessage I couldn't get them to work with WordPad either, then I figured out that my control was for some reason different. As far as getting stuff to work with EverQuest, I'm not sure. See if you can get PostMessage to work first.

thanks,
beardboy

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
So that you can see how the example works, here is a revised version that should work with more versions of WordPad. Indeed, this approach might work with many apps, including some games:
Run, wordpad
WinWait, Document -
WinActivate
ControlGetFocus, focused_control
start = 0
Loop 
{ 
   PostMessage, 0x102, %start%, 1, %focused_control% // 0x102 is WM_CHAR
   ++start 
   if start > 600
      break 
}
This approach relies on the fact that the control in the window that currently has input focus is usually the one most capable of receiving and acting upon keystrokes sent with either ControlSend or the even lower-level approach (WM_CHAR) above. But first try ControlSend on the focused control.

If ControlGetFocus doesn't help, you might try analyzing the window to find out which controls are actually present. Some games might not have any obvious controls, but I'm not experienced enough to say how you should look for them other than to use MouseGetPos or Window Spy (depending on whether the game is full-screen or not). Also, perhaps Winspector will let you know which control classes are receiving the messages (I don't know since I've never used it).

My hunch tells me there is a slight chance that the game cannot be automated except through the actual Send command, but more likely it can be automated if you discover the right messages to Post. You might also try using SendMessage because some messages and/or some windows might respond differently to Send vs. Post.

Good luck.

karmadude
  • Members
  • 4 posts
  • Last active: Jul 21 2004 05:18 PM
  • Joined: 18 Jul 2004
No joy for me :cry:

Send seems to have no problems but Controlsend, PostMessage and SendMessage won't send keystrokes to the game, whether minimized or not.

I did some further investigation and checked the messages that were received when I had the window maximized and typed the letter "s" in a text field. I then took the three messages (which consisted of a WM_KEYDOWN, WM_CHAR, and WM_KEYUP command) and made a hotkey that would SendMessage the same messages with the same params to the window.

The messages were sent, but Winspector also showed me a return value of 0 on those messages, which indicates a failure I believe.

I guess I need to somehow find out what control classes or whatever are accepting keypresses. It just confuses me why Send works but none of the other commands do.

P.S. I tried to run
Run, wordpad
WinWait, Document -
WinActivate
ControlGetFocus, focused_control
start = 0
Loop
{
   PostMessage, 0x102, %start%, 1, %focused_control% // 0x102 is WM_CHAR
   ++start
   if start > 600
      break
}

and all it did was launch Wordpad. :?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

I guess I need to somehow find out what control classes or whatever are accepting keypresses.

I suspect that is the key, to find out which control to send to (assuming the window has controls at all). But it's possible the game only accepts these messages when they were generated by its own thread (in response to simulated keystrokes from the Send command), and not from external threads.

It just confuses me why Send works but none of the other commands do.

Send produces actual simulated keystrokes, which are higher level events than PostMessage/SendMessage. Most apps cannot tell the difference between simulated keystrokes and real ones. This might not be as true for Post/SendMessage.

all it did was launch Wordpad

Strange, I think I tested that script in WinXP and Win98se and it worked in both. Maybe there are many different versions of Wordpad.

silentblood
  • Members
  • 36 posts
  • Last active: Oct 25 2006 12:24 AM
  • Joined: 19 Jun 2004
WinGet,SBID, ID,A : this will get the windows ID of the active window and set it to SBID variable.(hece everquest window)


ControlSend,,TEST , ahk_id %SBID% : This will send a keystroke only to everquest or whatever windows ID got stored as SBID. This will send TEST to the the SBID windowed. Make sure you put the WinGet Command outside of your main loop so it only checks this once when you first start. I have this to macro multiple clients on Shadowbane.

karmadude
  • Members
  • 4 posts
  • Last active: Jul 21 2004 05:18 PM
  • Joined: 18 Jul 2004
Ok, so I tried this
SetTitleMatchMode, 2
IfWinNotExist, Untitled
{
Run, notepad
WinWait, Untitled -
}
WinActivate, Untitled
ControlGetFocus, focused_control
WinMinimize
MsgBox, %focused_control%
WinActivate, test
start = 0
Loop
{
   PostMessage, 0x102, 0x41, 1, %focused_control%
   ++start
   if start > 0
      break
}
sleep 1000
WinRestore

Just so I could see whether I could get everything working just with Notepad.

When messing around creating this script I learned that I suck at being able to obtain the %focused_control% without having the window activated. Whenever I simply added the parameter indicating the title of the window I wanted to perform the ControlGetFocus on, it wouldn't work. I would have to activate it and then do the ControlgetFocus.

For example,
SetTitleMatchMode, 2
ControlGetFocus, focused_control, Untitled
MsgBox, %focused_control%

Would display an empty message box, i.e. no dice obtaining the control.

I am at work currently, but when i get home i will try to see if I can perform a ControlGetFocus on EQ when it is active. If so, i'll just have it activate and get the control, then minimize the window and have my hotkeys ready to go. :D

Oh, and thanks silentblood, I tried to do Controlsend directly to the window previously and had no luck :(

Chris is probablly right and the game simply won't allow input from separate threads, but I am hoping I'll be able to figure something out.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks for mentioning that, it's an oversight in the docs which I've corrected as follows:

The control retrieved by this command is the one that has keyboard focus, that is, the one that would receive keystrokes if the user were to type them.

The target window must be active to have a focused control. If the window is not active, OutputVar will be made blank.



silentblood
  • Members
  • 36 posts
  • Last active: Oct 25 2006 12:24 AM
  • Joined: 19 Jun 2004
The thing I posted above allows me to macro mutliple clients on on machine in Shadowbane and also alt tab and serf and stuff. All that stuff yall are typing is not required for SB not sure if you need it for EQ either.

karmadude
  • Members
  • 4 posts
  • Last active: Jul 21 2004 05:18 PM
  • Joined: 18 Jul 2004
Thanks Silent, but the following
q::
WinGet,SBID, ID,A
ControlSend,,TEST , ahk_id %SBID%

Will work when I open notepad and click "q", but when I tab to EQ and do the same it does not enter any text.

I tried
q::
ControlGetFocus, focused_control,A
MsgBox, %focused_control%

to get the active control in EQ and it didn't work...empty messagebox.

So, I can only assume the game says kiss off to any input from a separate thread, and I will need to utilize some other means. Oh well, was fun trying :)

bgueas
  • Guests
  • Last active:
  • Joined: --
I think somethink is wrong ; /...