Jump to content

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

How to send keystrokes to a multiple windows that have the same process names?



  • Please log in to reply
4 replies to this topic
parkianik
  • Members
  • 5 posts
  • Last active: May 31 2014 10:22 PM
  • Joined: 13 Apr 2014

Hi,

 

I made a script which sends keystrokes using ControlSend, and clicks using PostMessage.

 

Well, the script I made works fine as I wanted except the fact that it applies only to one of my game, not to every games.

 

For example, if there are five game processes with the same name called "Game", my script will only be applied only to one of the "Game" processes.

 

I guess this is because I left Control section in ControlSend command in blank..

 

How should I edit my code? (ControlSend maybe?)

 

Here's a part of my codes:

Home::
id := WinExist("Game")

Loop
{
ControlSend,, {Ctrl Down}, ahk_id %id%
ControlSend,, 1, ahk_group %id%
ControlSend,, {Ctrl Up}, ahk_id %id%
Sleep, 2000
PostMessage, 0x201,,,, ahk_id %id%
PostMessage, 0x202,,,, ahk_id %id%
Sleep, 800
PostMessage, 0x201,,,, ahk_id %id%
PostMessage, 0x202,,,, ahk_id %id%
Sleep, 800
Gosub, selectCream
Gosub, quantity
Gosub, selectCheese
Gosub, quantity
Gosub, selectBread
Gosub, quantity
Sleep, 1500
ControlSend,, {Enter}, ahk_id %id%
Sleep, 1000
PostMessage, 0x204,,,, ahk_id %id%
PostMessage, 0x205,,,, ahk_id %id%
Sleep, 500
Gosub, eatZeroThenGo
Gosub, eatNineThenGo
Gosub, eatEightThenGo
Sleep, 1000
}
return


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

You need to send those commands to each window. Currently you are only sending it to one. Winexist only returns the ID of the first matching window.

 

This should work. Obviously the commands will be sent at quite different times to the various windows due to the sleep and the 'loop, % IDList' running all of them in sequence. You may want to write a wrapper function for the controlSend which internally loops the IDList and sends the specified keys to each window, that way they will all stay in sequence.

Home::
winget, IDList, List, Game ; get a list of all windows which match this windowTitle
Loop
{
    loop, % IDList ; IDList set to number of matches found
    {
        id := IDList%A_Index% ; id is stored in a pseudo array e.g. ID 1= IDList1, ID2 = IDList2
        ControlSend,, {Ctrl Down}, ahk_id %id%
        ControlSend,, 1, ahk_id %id%
        ControlSend,, {Ctrl Up}, ahk_id %id%
        Sleep, 2000
        PostMessage, 0x201,,,, ahk_id %id%
        PostMessage, 0x202,,,, ahk_id %id%
        Sleep, 800
        PostMessage, 0x201,,,, ahk_id %id%
        PostMessage, 0x202,,,, ahk_id %id%
        Sleep, 800
        Gosub, selectCream
        Gosub, quantity
        Gosub, selectCheese
        Gosub, quantity
        Gosub, selectBread
        Gosub, quantity
        Sleep, 1500
        ControlSend,, {Enter}, ahk_id %id%
        Sleep, 1000
        PostMessage, 0x204,,,, ahk_id %id%
        PostMessage, 0x205,,,, ahk_id %id%
        Sleep, 500
        Gosub, eatZeroThenGo
        Gosub, eatNineThenGo
        Gosub, eatEightThenGo
        Sleep, 1000
    }
}
return


parkianik
  • Members
  • 5 posts
  • Last active: May 31 2014 10:22 PM
  • Joined: 13 Apr 2014

 

You need to send those commands to each window. Currently you are only sending it to one. Winexist only returns the ID of the first matching window.

 

This should work. Obviously the commands will be sent at quite different times to the various windows due to the sleep and the 'loop, % IDList' running all of them in sequence. You may want to wrap just have a wrapper function for the controlSend which internally loops the IDList and sends the specified keys to each window, that way they will all stay in sequence.

Home::
winget, IDList, List, Game ; get a list of all windows which match this windowTitle
Loop
{
    loop, % IDList ; IDList set to number of matches found
    {
        id := IDList%A_Index% ; id is stored in a pseudo array e.g. ID 1= IDList1, ID2 = IDList2
        ControlSend,, {Ctrl Down}, ahk_id %id%
        ControlSend,, 1, ahk_id %id%
        ControlSend,, {Ctrl Up}, ahk_id %id%
        Sleep, 2000
        PostMessage, 0x201,,,, ahk_id %id%
        PostMessage, 0x202,,,, ahk_id %id%
        Sleep, 800
        PostMessage, 0x201,,,, ahk_id %id%
        PostMessage, 0x202,,,, ahk_id %id%
        Sleep, 800
        Gosub, selectCream
        Gosub, quantity
        Gosub, selectCheese
        Gosub, quantity
        Gosub, selectBread
        Gosub, quantity
        Sleep, 1500
        ControlSend,, {Enter}, ahk_id %id%
        Sleep, 1000
        PostMessage, 0x204,,,, ahk_id %id%
        PostMessage, 0x205,,,, ahk_id %id%
        Sleep, 500
        Gosub, eatZeroThenGo
        Gosub, eatNineThenGo
        Gosub, eatEightThenGo
        Sleep, 1000
    }
}
return

Hmm.. not quite the way I wanted. Yours send commands to Game 1, Game 2, ..., Game 5 in order. For example, when the first loop of commands are sent to Game 1, the next loop is then sent to Game 2, and so on. I wanted the script to work simultaneously. So at a run, the script is applied to the five "Game" processes at the same time or about at the same time..



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006
✓  Best Answer

The post was meant to show you how to get the IDs of all the programs, as I said you should write a wrapper function. But here it is anyway.

multiSend(sequence, title := "A")
{
    winget, IDList, List, %title%
    loop, % IDList 
        ControlSend, , %sequence%, % "AHK_ID " IDList%A_Index%
    return IDList
}

multiPost(msg := 0, wParam := 0, lParam := 0, Control := "", title := "A")
{
    winget, IDList, List, %title%
    loop, % IDList 
        PostMessage, msg, wParam, lParam, %Control%, % "AHK_ID " IDList%A_Index%
    return IDList
}

Home::
Loop
{
    multiSend("{Ctrl Down}", "Game") ; Usually you can send these three lines as one i.e. multiSend("{Ctrl Down}1{Ctrl Up}", "Game")
    multiSend("1", "Game")
    multiSend("Ctrl Up", "Game")
    Sleep, 2000
    multiPost(0x201,,,, "Game")
    multiPost(0x202,,,, "Game")
    Sleep, 800
    ; The rest of your loop
}
return


parkianik
  • Members
  • 5 posts
  • Last active: May 31 2014 10:22 PM
  • Joined: 13 Apr 2014

 

The post was meant to show you how to get the IDs of all the programs, as I said you should write a wrapper function. But here it is anyway.

multiSend(sequence, title := "A")
{
    winget, IDList, List, %title%
    loop, % IDList 
        ControlSend, , %sequence%, % "AHK_ID " IDList%A_Index%
    return IDList
}

multiPost(msg := 0, wParam := 0, lParam := 0, Control := "", title := "A")
{
    winget, IDList, List, %title%
    loop, % IDList 
        PostMessage, msg, wParam, lParam, %Control%, % "AHK_ID " IDList%A_Index%
    return IDList
}

Home::
Loop
{
    multiSend("{Ctrl Down}", "Game") ; Usually you can send these three lines as one i.e. multiSend("{Ctrl Down}1{Ctrl Up}", "Game")
    multiSend("1", "Game")
    multiSend("Ctrl Up", "Game")
    Sleep, 2000
    multiPost(0x201,,,, "Game")
    multiPost(0x202,,,, "Game")
    Sleep, 800
    ; The rest of your loop
}
return

Thank you so much..! I learnt a lot from yours regarding how to get all the IDs and how to work with it. :D

I was stuck creating function but the script is now working great. Thanks again.