GUI Position Does not Reset After SetTimer Loop
Posted: 03 Feb 2023, 10:18
Three questions:
As you can see, I typically keep a small rectangle in the top right of my screen to see if the script is suspended or not.
Then, I've chosen to move the Gui around to show me that it's currently hotkey-spamming.
Timer toggles off fine without problems as far as I can tell. Color reset/change works but position doesn't. I suspect it has to do with the timing of my deactivating the timer/label and whether or not the script is currently asleep? How do I circumvent this?
But then, I've also tried removing all the sleep commands from my script and setting at the top of my script. I expect this snippet to cause all my hotkeys to be at least 20 ms apart and every button press to last 30 ms, would that be right? With this rewrite, the Gui still gets stuck in its last position (985, 530), before/after sending the {d} hotkey.
Secondly, further down in my script I have a L/RButton self-sender. For now, I've usedsuccessfully to toggle the mouse button rapidfire. This is no longer an option if I want to activate the above macro via a hotkey (as the AHK script would be suspended).
More specifically: Mouse button self-sender is off, but I still want the option to trigger WASD_Spam with its designated key.
I attempted the following without success. Why does it not work and what would be a workaround?
Lastly, my status GUI is visible even if my target program is out of focus. How do I constantly check its status without an infinite loop?
I've already got at the top of my script to ensure that all the hotkeys only fire when I'm actually using that program.
So, adding
at the bottom of my script obviously achieves nothing. As I understand it, the script executes once, top till bottom and it's over. Then it only listens to the hotkeys declared throughout the script. My first intuition is to just set an infinite loop at 0ms delay to constantly check but there has got to be a more elegant way. Also, I've made some worrying experiences with infinite timers running in the background causing insane CPU usage (C#) I'm pretty certain that's not the way to go.
Full script
Thanks for reading, appreciate every possible input
- Why does my Gui fail to set its new position after a few loops? See code sample
- How can I set a condition to hotkeys being active?
- How can I permanently check the status of a window to display my Gui accordingly?
Code: Select all
ShowStatus(){
Gui Color, Lime
Gui +E0x20 +AlwaysOnTop +ToolWindow -Caption
Gui, Show, x1910 y0 w10 h10 NoActivate, StatusWindow ;Give my GUI a title
WinSet, Transparent, 190, StatusWindow ;Use that title to change only ITS transparency
WinActivate, ahk_exe TARGET_PROG.exe
}
Then, I've chosen to move the Gui around to show me that it's currently hotkey-spamming.
Code: Select all
Active=1
SpamToggle=0
^::
SpamToggle:=!SpamToggle
If SpamToggle
{
Gui, Color, Red
SetTimer, WASD_Spam, 20
}
else
{
SetTimer, WASD_Spam, Off
;Return its default color + position
Gui, Color, Lime ;works
Gui, Show, x1910 y0 NoActivate ;fails most of the time
If !Active
Gui, Hide
}
return
WASD_Spam:
Gui, Show, x955 y510 NoActivate
Send w
Sleep 20
Gui, Show, x925 y530 NoActivate
Send a
Sleep 20
Gui, Show, x955 y530 NoActivate
Send s
Sleep 20
Gui, Show, x985 y530 NoActivate
Send d
return
But then, I've also tried removing all the sleep commands from my script and setting
Code: Select all
SetKeyDelay , 30, 20
Secondly, further down in my script I have a L/RButton self-sender. For now, I've used
Code: Select all
~MButton::
Suspend, Toggle
Active:=!Active
If !Active
Gui, Hide
else
ShowStatus()
return
More specifically: Mouse button self-sender is off, but I still want the option to trigger WASD_Spam with its designated key.
I attempted the following without success. Why does it not work and what would be a workaround?
Code: Select all
if(Active)
{
LButton::
; .. do stuff
return
RButton::
; .. do more stuff
return
}
Lastly, my status GUI is visible even if my target program is out of focus. How do I constantly check its status without an infinite loop?
I've already got
Code: Select all
#SingleInstance, Force
#IfWinActive, ahk_exe TARGET_PROG.exe
#UseHook
So, adding
Code: Select all
#IfWinNotActive, ahk_exe TARGET_PROG.exe
Gui, Hide
#IfWinActive, ahk_exe TARGET_PROG.exe
if(Active)
Gui, Show
Full script
Code: Select all
#SingleInstance, Force
#IfWinActive, ahk_exe PROG.exe
#UseHook
ShowStatus(){
Gui Color, Lime
Gui +E0x20 +AlwaysOnTop +ToolWindow -Caption
Gui, Show, x1910 y0 w10 h10 NoActivate, StatusWindow ;Give my GUI a title
WinSet, Transparent, 190, StatusWindow ;Use that title to change only ITS transparency
WinActivate, ahk_exe PROG.exe
}
Active=1
WASD_Toggle=0
ShowStatus()
^::
WASD_Toggle:=!WASD_Toggle
if(WASD_Toggle)
{
Gui, Color, Red
SetTimer, WASD_Spam, 20
}
else
{
SetTimer, WASD_Spam, Off
Gui, Color, Lime ;Works
Gui, Show, x1910 y0 NoActivate ;⚠⚠⚠⚠ doesn't set this position most of the time when interrupting the timer loop
If !Active
Gui, Hide
}
return
WASD_Spam:
Gui, Show, x955 y510 NoActivate
Send w
Sleep 20
Gui, Show, x925 y530 NoActivate
Send a
Sleep 20
Gui, Show, x955 y530 NoActivate
Send s
Sleep 20
Gui, Show, x985 y530 NoActivate
Send d
return
~MButton::
Suspend, Toggle
Active:=!Active
if(!Active)
Gui, Hide
else
ShowStatus()
return
LButton::
Loop
{
Keywait, Lbutton, D T0.15
if errorlevel = 1
break
SendInput {Lbutton down}
Sleep 20
SendInput {lbutton up}
Sleep 50
}
return