Autohotkey If WinActive - autohotkey

Here is the script I am using to use the key 1 to send 1 if active window is 3ds max or else go back in explorer and browser. My code only works if the window is a newly opened unsaved 3ds max file. How do I get it to work with any 3ds max file? I know the ahk_class of max is 3DSMAX.
1::
if WinActive("Untitled - Autodesk 3ds Max 2018")
{
Send, 1
}
Else
{
Send, {Alt Down}{Right Down}{Right Up}{Alt Up}
}
Return
The official documentation says this
if WinActive("ahk_class Notepad") or WinActive("ahk_class" . ClassName)
but neither this works
if WinActive("ahk_class 3DSMAX") or WinActive("ahk_class" . ClassName)
Nor this works
if WinActive("ahk_class 3DSMAX")
Nor this works
WinActive("ahk_class" . 3DSMAX)
I cannot use
#IfwinActive ahk_class 3DSMAX
even though it works because my script is using intercept to use the macro keys on Razer Naga Hex, to send separately from my keyboard keys and it will get very complicated once I start adding all of the software I use.
Here is the full script
#HotkeyInterval 20000 ; This is the default value (milliseconds).
#MaxHotkeysPerInterval 2000
#SingleInstance force
#Persistent
#if (getKeyState("F22", "P"))
F22::return
;=========================================
1::
if WinActive("Untitled - Autodesk 3ds Max 2018")
{
Send, 1
}
Else
{
send, {Alt Down}{Right Down}{Right Up}{Alt Up}
}
return
;=========================================
2::
send, {Ctrl Down}z{Ctrl Up}
return
;========================================
3::
send, {Ctrl Down}y{Ctrl Up}
return
;=========================================
4::
send, {Alt Down}{Left Down}{Left Up}{Alt Up}
return
;=========================================
5::
return
;=========================================
6::
return
;==========================================
7::
return
;==========================================
#if
return

Related

I'm having trouble with GetKeyState in AHK

Below is an alt+tab program I wrote that, for some reason, won't work.
while x = 1
{
mb1 := GetKeyState(j)
mb2 := GetKeyState(k)
if (mb1 = 1) and (mb2 = 1)
{
Send, {Alt Down}
Send, {Tab Down}
sleep, 50
Send, {Alt Up}
Send, {Tab Up}
}
}
I've tried multiple methods of the loop and key detection to no avail.
You do not need to store the value of the keystate in a variable prior to the if-statement; you can check them during the if-statement itself.
So, you could implement this change with something like this:
Loop
{
if (GetKeyState("j") && GetKeyState("k"))
{
Send, {Alt Down}
Send, {Tab Down}
sleep, 50
Send, {Alt Up}
Send, {Tab Up}
}
}
However, if you need to save the value of the KeyStates for some reason, there are a couple of ways to do this:
Just save the values from the GetKeyStates while you are checking them in the if-statement.
Note: For both variables to always update every iteration, you need to replace the efficient && with the less efficient &, since the && will stop checking variables as soon as it determines the expression will be false.
This would look something like:
Loop
{
if (mb1:=GetKeyState("j") & mb2:=GetKeyState("k"))
{
Send, {Alt Down}
Send, {Tab Down}
sleep, 50
Send, {Alt Up}
Send, {Tab Up}
}
MsgBox During the last check, j was %mb1%, and k was %mb2%!
}
Use the alternative GetKeyState command syntax
Note: Although this version of the command makes it more straightforward to save the output of the command to a variable, it is depreciated and not recommended for use in new scripts.

Autohotkey, problems redefining keypress down state of mousekey

I am using the LButton (mouse left) in a keybind as a prefix key. I got it to work, problem is I now need to redefine the LButton as whatever it was in it's natural state...in Autohotkey's terms.
I read this: https://www.autohotkey.com/docs/commands/GetKeyState.htm.
And cameup with the following code, but it's not working at all the way I thought it would. Simply put, you can use $LButton::Send {Click Left} to emulate the basic mouse click. The problem is when you hold the button/key down, nothing happens. I thought the code to emulate, or define the 'pressed down' behaviour would be readily available, but what I've found isn't working.
$LButton::
if (GetKeyState("LButton", "P"))
Send, {Click Left Down} ;tried variants with {Click Left} etc alrdy
else
Send, {Click Left Up}
return
For person in comments:
LButton & ~RButton::
Send, 1{Click Right}{Click Left}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
return
$LButton:: ;no idea what this shud be
SendInput {Click Left}
;Send, {Click Left Down}
;KeyWait, LButton
;Send, {Click Left Up}
return
RButton::
Send, 1{Click Right}{Click Left}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
return
Not sure if I understood this correctly, but you want holding LButton, then clicking the RButton to run this code:
Send, 1{Click Right}{Click Left}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
And just clicking RButton should run that code as well?
And if LButton is just pressed normally (not in combination with RButton) it should function as normal?
Well this would be it:
~LButton & RButton::
RButton::
Send, 1{Click Right}{Click Left}{Click Right}{MButton}
Sleep, 130
Send, 1
return
Basically just making use of the ~ modifier.
Although I can't speak for Send, 1{Click Right}{Click Left}{Click Right}{MButton}.
I don't know what it's supposed to do, but maybe/hopefully it's doing the right thing.
Pressing w or something that you define should do the job
w::
Send, {Click down}
Send, {Blind}1{Click Right}{Click}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
return
Anyone looking for something similar could try in this direction
#SingleInstance force
#warn
r::Reload
x::ExitApp
w::
Send, {Click down}
Send, {Blind}1{Click Right}{Click}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
return
just Pressing w should do the job
Alternately
, the below one will do the same
LButton::Send, {Click down}
RButton::
if GetKeyState("LButton", "P")
{
Send, {Blind}1{Click Right}{Click}{Click Right}{MButton}
Sleep 130 ;125
Send, 1
}
else
Send, {Click Right}
return

How to make "BlockInput On/Off" only block keyboard inputs not mouse

As the title says, I've had trouble finding a way for my script to only block keyboard inputs during my script. Is there a method that I've overlooked to do this? Here's my code for reference:
toggle = 0
*xbutton1::
{
if GetKeyState("d", "P")
{
if GetKeyState("w", "P")
{
BlockInput On ;enabled
Send, {d up}
Send, {w up}
Send, {a down}
Send, {s down}
Send, {K}
BlockInput Off ;disabled when completed with the above actions ^ so no key inputs interfere
Sleep, -1
Send, {a up}
Send, {s up}
Send, {d down}
Send, {w down}
return
}
Thanks! I'd appreciate any info or tips.
You can create a function to only block keyboard input:
; Press F1 to block keyboard input for 10 seconds:
$F1::
BlockKeyboard("On")
Sleep, 10000
BlockKeyboard("Off")
return
BlockKeyboard(state){
Loop, 512
{
Key := Format("SC{:X}",A_Index)
If (state = "On")
Hotkey, *%Key%, KeyboardKey, On UseErrorLevel
else
Hotkey, *%Key%, KeyboardKey, Off UseErrorLevel
}
KeyboardKey:
return
}

Autohotkey Mapping Modifiers

I can't use arrow keys from my keyboard so I mapped 1234 to be the arrow keys like that:
*!^1::
Send, {Left down}{Left up}
Return
*!^2::
Send, {Down down}{Down up}
Return
*!^3::
Send, {Up down}{Up up}
Return
*!^4::
Send, {Right down}{Right up}
Return
Now my problem is that in some programs the arrow keys pressed with the shift modifier is associated to a function and with the current settings, when I press Ctrl+Alt+Shift+1 it still outputs me the associated arrow key without considering the 'Shift' modifier.
Do you know how could I solve the problem?
Thanks.
You can just add a list of commands that already includes the shift key, like this:
*+!^1::
Send, {Shift down}{Left down}{Left up}{Shift up}
Return
*+!^2::
Send, {Shift down}{Down down}{Down up}{Shift up}
Return
*+!^3::
Send, {Shift down}{Up down}{Up up}{Shift up}
Return
*+!^4::
Send, {Shift down}{Right down}{Right up}{Shift up}
Return

Wait for previous process to finish before starting new one

I need to find a way in AHK to wait for a program to finish, before starting a new one.
Basically, I have a script that opens an application and inputs some parameters. The application then spends an unknown amount of time processing the input data.
Unfortunately, at the moment the ahk script ends before the application has finished processing, at which point the same ahk script is run again and does not work / interrupts the previous processing.
edit: (the ahk .exe is called using subprocess calls in Python)
is there a way or any methods to help with this?
For reference, the script:
#NoEnv
CoordMode, Mouse, Window
SendInput Mode Input
#SingleInstance Force
SetTitleMatchMode 2
#WinActivateForce
SetControlDelay 1
SetWinDelay 0
SetKeyDelay -1
SetMouseDelay -1
SetBatchLines -1
if 0 < 2 ; The left side of a non-expression if-statement is always the name of a variable.
{
MsgBox, This script requires 2 incoming parameters but it only received %0%.
ExitApp
}
IfWinNotExist, ahk_exe photoscan.exe
{
Run, "C:\Program Files\Agisoft\PhotoScan Pro\photoscan.exe"
}
sleep, 200
WinActivate, ahk_exe photoscan.exe
sleep,5
WinMaximize, ahk_exe photoscan.exe
;Macro5:
Click, 476, 438, 0
SendInput {LControl Down}
SendInput {r}
Click, -56, 157, 0
WinActivate, Run Python Script ahk_class QWidget
sleep, 400
SendInput {LControl Up}
SendInput {LControl Down}
SendInput {a}
SendInput {LControl Up}
sleep, 400
SendInput {Backspace}
SendInput %1% ; 1st argument is the photoScan API scriptimages folder directory
SendInput {Tab}
SendInput {Tab}
sleep, 400
SendInput {LControl Down}
SendInput {a} ; 2nd argument is additional args (in our case, the projectName)
SendInput {LControl Up}
SendInput {Backspace}
SendInput %2% ; 2nd argument is the images folder directory & name of output log, model and texture
Sleep, 703
SendInput {Enter}
Click, 476, 438, 0
Return
You have:
IfWinNotExist, ahk_exe photoscan.exe
{
Run, "C:\Program Files\Agisoft\PhotoScan Pro\photoscan.exe"
}
sleep, 200
Which is set to start/launch the application if it is not running. Then a sleep to allow two tenths of a second for it to load (which is probably too small).
Instead of just a ‘sleep’ you have to ‘WinWait’ or ‘WinWaitActive’, found at this link:
https://autohotkey.com/docs/commands/WinWaitActive.htm
Like this sample:
Run, "C:\Program Files\Agisoft\PhotoScan Pro\photoscan.exe"
WinWaitActive, ahk_exe photoscan.exe, , 2
if ErrorLevel
{
MsgBox, WinWait timed out.
return
}
else
WinMinimize ; minimize the window found by WinWaitActive.
You may also have to use the window inspector to get the true name of the window/application/process name.