0

I have an AHK script that allows me to bind joystick presses to keystrokes. These keystrokes are used to trigger functions in a trainer that runs in the background while I play a game. The script works fine, but the problem is that the joystick bindings send unwanted input to other programs when the game is minimized.

What I want is either:

  1. disabling the script while the game is minimized.
  2. send keystrokes only to the trainer.

Im not even sure that option 2 is viable as sending keystrokes via joystick with a simple script like Joy13:: Send {T} doesn't seem to work for the intended purpose. The problem is that I don't know how my original script works as someone else made it for me and is no longer available to modify it for this purpose.

Here is the original code:

pad2KB := New Pad2KB ;Create an instance of Pad2KB class                        

;----------Change only this section----------                       
;pad2KB.bindKey2Keys  - bind one pad key to two KB keys
;pad2KB.bindKeys2Keys - bind two pad keys to two KB keys
;pad2KB.bindKeys2Key  - bind two pad keys to one KB key
;pad2KB.bindKey2Key   - bind one pad key to one KB key

pad2KB.bindKey2Keys("Joy11", "CTRL", "U", true) ;"true" in this case means "Use this key as a toggle - press-release to enable and do the same to disable
pad2KB.bindKey2Keys("Joy8", "CTRL", "I")        ;when there's no "true" you can press and hold the key
pad2KB.bindKey2Keys("Joy7", "CTRL", "K")
pad2KB.bindKey2Key("Joy13", "T", true)                                  

;pad2KB.bindKey2Key("4","B")
;pad2KB.bindKeys2Keys("5", "6", "CTRL", "U", true)                          
;----------Change only this section----------

pad2KB.run() ;Start a while loop and check for the keys                                                                 
;----------Class----------
class Pad2KB
{
    mask := 0xFFFFFFFF
    hotKeyStruct      := {PadKey0: this.mask, PadKey1: this.mask, KBKey0: this.mask, KBKey1: this.mask, Toggle: false, State: false}
    hotKeyArray       := {}

    abort        := false
    sleep        := 50

    bindKey2Keys(nPadKey0, nKBKey0, nKBKey1, nToggle:=0)
    {
        this.addHotKeys(nPadKey0, this.mask, nKBKey0, nKBKey1, nToggle)
    }

    bindKeys2Keys(nPadKey0, nPadKey1, nKBKey0, nKBKey1, nToggle:=0)
    {
        this.addHotKeys(nPadKey0, nPadKey1, nKBKey0, nKBKey1, nToggle)
    }

    bindKey2Key(nPadKey0, nKBKey0, nToggle:=0)
    {
        this.addHotKeys(nPadKey0, this.mask, nKBKey0, this.mask, nToggle)
    }

    bindKeys2Key(nPadKey0, nPadKey1 , nKBKey0, nToggle:=0)
    {
        this.addHotKeys(nPadKey0, nPadKey1, nKBKey0, this.mask, nToggle)
    }

    addHotKeys(nPadKey0, nPadKey1, nKBKey0, nKBKey1, nToggle)
    {
        newHotKeyStruct         := new this.hotKeyStruct
        newHotKeyStruct.PadKey0 := nPadKey0
        newHotKeyStruct.PadKey1 := nPadKey1
        newHotKeyStruct.KBKey0  := nKBKey0 
        newHotKeyStruct.KBKey1  := nKBKey1 
        newHotKeyStruct.Toggle  := nToggle 

        this.hotKeyArray.push(newHotKeyStruct)
    }

    checkToggle(state, status, iter)
    {
        if( (state && !status) || (!state) )
        {
            this.hotKeyArray[iter].State := true
            return true
        }
        return false
    }

    getState(key0, key1)
    {
        result0 := getKeyState(key0, "p") ;"p" - check physical state
        if(key1 != this.mask)
        {
            result1 := getKeyState(key1, "p")
            return result0 && result1
        }
        return result0
    }

    pressKeys(key0, key1)
    {
        keys := [key0, key1]
        if(!this.abort)
        {
            Loop % keys.Length()
            {
                var := keys[A_Index]
                if(%var% != this.mask)
                    Send, {%var% down}
            }

            Sleep, this.sleep

            Loop % keys.Length()
            {
                var := keys[A_Index]
                if(%var% != this.mask)
                    Send, {%var% up}
            }
        }
        else
        {
            Loop % keys.Length()
            {
                var := keys[A_Index]
                if(%var% != this.mask)
                    Send, {%var% up}
            }
        }
    }

    processKeys()
    {
        Loop % this.hotKeyArray.Length()
        {
            if(this.getState(this.hotKeyArray[A_Index].PadKey0, this.hotKeyArray[A_Index].PadKey1))
            {
                if(this.checkToggle(this.hotKeyArray[A_Index].Toggle, this.hotKeyArray[A_Index].State, A_Index))
                    this.pressKeys(this.hotKeyArray[A_Index].KBKey0, this.hotKeyArray[A_Index].KBKey1)
            }
            else
            {
                this.hotKeyArray[A_Index].State := false
            }
        }
    }

    run()
    {
        while(!this.abort)
        {
            this.processKeys()
            Sleep, 1
        }
    }

    exitFunc(exitReason:=0, exitCode:=0)
    {
        this.abort := true
        this.processKeys()
    }

    __Delete()
    {
         this.exitFunc()
    }
}
;----------Class----------

Below are examples of different variations of the script that I have tried with no success:

https://paste.ubuntu.com/p/RjVzXXHm6Y/

https://paste.ubuntu.com/p/fQN9mFPWns/

https://paste.ubuntu.com/p/Gxfng2MwbV/

https://paste.ubuntu.com/p/RJWpggt8HK/

Again, the goal is to simply get this script to pause while bio4.exe is minimized. Perhaps I can write a second script to toggle this script?

Perhaps this could work with another .bat file that with something like:

if bio4.exe window minimized, exit script.ahk
if bio4.exe window maximized, run script.ahk
1

For shortcuts, the usual solutions use #IfWinActive directive.

For finer control use the #If directive in combination with the WinActive/IfWin[Not]Active built-in function. You might also find useful WinExist() / IfWin[Not]Exist.

Example:

    IfWinActive, Untitled - Notepad
    {
        WinMaximize  ; Maximizes the Notepad window found by IfWinActive above.
        Send, Some text.{Enter}
        return
    }
  • The section of the documentation of Context-sensitive Joystick Buttons says that #IfWinActive/Exist is valid for joystick events. Your script is a bit long, but perhaps you can update it to show what you have tried and didn't work. What I don't understand in your other post is "#if comment at end of script". It should rather encompass the entire script. – harrymc Oct 3 at 19:18
  • THanks for the reply. In my other post I said that I want my script to only be activated when my game is maximized. Is this possible? – Kalamalka Kid Oct 3 at 19:20
  • Everything is possible. Use the WinGet command with the MinMax sub-command. – harrymc Oct 3 at 19:23
  • sorry I dont understand any of this. None of the code in your answer works with my script. Id be happy to upvote for the attempt to help. – Kalamalka Kid Oct 3 at 19:25
  • Then show the script that doesn't work, as I asked before. – harrymc Oct 3 at 19:27
0

I found another script here to minimize and maximize the game. Adding joy12::Pause at the end of the original script above solved the issue since my Joy12 is tasked with minimizing/maximizing the bio4.exe window in another running script:

Joy12::
WinGetPos, X, Y, Width, Height, Resident Evil 4
if (X == -32000)
WinMaximize, Resident Evil 4
else if (X == 0 and Y == 0 and Width == 1920 and Height == 1080)
WinMinimize, Resident Evil 4
return

so having these two scripts using the same toggle effectively pauses the script while also minimizing the game.

I would still love to know how to pause a script while the game window is minimized without the workaround.

0

Why the Usual Answers Don't Work

The reason #If or #IfWinActive statements don't work for this code is because this is checking for physical button states and manually implementing hotkey behaviours, vs. using the built-in AutoHotkey hotkey definitions.

I would imagine it's because the class allows more extended behavior mapping (one to two keys, etc)--the original code may be a bit overly-complicated but it mostly works right, so best to leave well enough alone if possible and not re-write it if that's not necessary.

Where To Try and Mod

To that end I would try to mod the run() loop.

I can't test this code easily myself, but if all you want is to "fix it", try placing a conditional in front of the this.processKeys() call. You could put any kind of conditional here:

run() {
    while(!this.abort) {
        If WinActive("ahk_exe bio4.exe")  ; <-- Try a conditional here
            this.processKeys()
        Sleep, 1
    }
}

Side Note #1: If the If WinActive() statement shown below doesn't do the trick, check the title name and/or class or whatnot using the Window Spy program (open from the Tray Icon context menu of any AutoHotkey script), to see what the title, class, exe is for an active window. Start Window Spy then start/activate your program of interest and see what Window Spy displays (and you can 'pause' the display with [Windows Key]+'a' if needed).

Side Note #2: If you do decide to use a plain window title vs. an ahk_exe designation, be aware of SetTitleMatchMode.

Side Note #3: You can also use logic combinations at this point to do any kind of multi-process checks you want, if that were ever needed.

;Allow process to run for any window *except* when Chrome or Explorer windows are active
If !WinActive("ahk_exe chrome.exe") && !WinActive("ahk_exe explorer.exe")

Side Note #4: You can also use WinExist() if you want to check for window presence, vs. window active. It doesn't sound like this is the case in your example, but wanted to make you aware of this function also.

; Mapping will pause if a chrome window is running, even if it's not active...
If WinActive("ahk_exe bio4.exe") && !WinExist("ahk_exe chrome.exe")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.