GUI Position Does not Reset After SetTimer Loop

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
sh00ter666
Posts: 18
Joined: 07 Oct 2016, 10:55

GUI Position Does not Reset After SetTimer Loop

Post by sh00ter666 » 03 Feb 2023, 10:18

Three questions:
  • 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?
Been fiddling with my macro for a while. In order to display varying states I've opted to "draw" on screen using a transparent, click-through, borderless GUI.

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
}
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.

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
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

Code: Select all

SetKeyDelay , 30, 20
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 used

Code: Select all

~MButton::
Suspend, Toggle
Active:=!Active

If !Active
	Gui, Hide
else
	ShowStatus()
return
successfully 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?

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
at the top of my script to ensure that all the hotkeys only fire when I'm actually using that program.
So, adding

Code: Select all

#IfWinNotActive, ahk_exe TARGET_PROG.exe
Gui, Hide
#IfWinActive, ahk_exe TARGET_PROG.exe
if(Active)
	Gui, Show
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#) :shh: I'm pretty certain that's not the way to go.

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
Thanks for reading, appreciate every possible input :beard:

User avatar
mikeyww
Posts: 26437
Joined: 09 Sep 2014, 18:38

Re: GUI Position Does not Reset After SetTimer Loop

Post by mikeyww » 04 Feb 2023, 06:54

Hello,

I saw that no one responded, so I will offer some suggestions about how to adjust your post.

1. Try to keep the post short, and focus strictly on its subject line. If you have multiple questions that are very different from each other, using separate threads may help to organize the issues, as well as attract and focus readers who are interested in specific kinds of problems.

2. Script fragments are OK for simple questions about syntax, but they sometimes do not enable a reader to understand the problem completely, or to replicate it. Instead of providing many script fragments, provide a single script that a reader can run to demonstrate your problem. The reader (responder) can then work on adjusting that script or giving you feedback about it.

3. Instead of trying to debug a script with 72 lines, start with a script that has only a small section of code. Get it working. After it works, expand the script little by little, retesting along the way. That eases the debugging process.

Hotkeys are not defined "inline" (without the Hotkey command), but you can use one of the #If directives to define a context for a hotkey. #If applies only to hotkeys and hotstrings, not other code. See the documentation for details & examples.

If you have no idea which lines are executing, and what the values of your variables, functions, & conditional statements are, then find out. You can do this with MsgBox, ListVars, ListLines, or other techniques.

Post Reply

Return to “Ask for Help (v1)”