Overlay GUI With Dynamically Selected Buttons Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Overlay GUI With Dynamically Selected Buttons

26 Sep 2017, 09:32

I'm looking to do something a bit complicated: I'm trying to create a GUI that acts as an "overlay" to another program, adding buttons that the user can click whenever that program is the active window. I'm pretty sure I can figure out using WinSet to make the window transparent except for the buttons, and I know I need to use a background loop to determine whether the GUI should display or not.

The tricky part is that which buttons should display varies based on a wide number of factors - options the user has set, hotkeys they have triggered, other buttons they have clicked, etc. I'm trying to figure out what the cleanest way to handle this is. I am picturing that the background loop constantly checks for which buttons are valid to display, updating the available buttons whenever that changes. I'm not entirely sure what the best way to do that is, especially since I need other parts of my script to be able to change the available buttons arbitrarily.

I feel like a truly ideal setup would be something like an array of button objects that the background loop checks, with each object containing the text the button should display, which row of buttons it should prefer to be in, and what function the button calls when pressed. Unfortunately I'm crap at both objects and arrays and I don't really know where to start with such a complicated GUI; is it even possible to populate buttons like that?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Overlay GUI With Dynamically Selected Buttons

26 Sep 2017, 23:45

example:

Code: Select all

ComObjCreate("Shell.Application").FileRun()
WinWait, ahk_class #32770 ahk_exe explorer.exe
hParent := WinExist()

Gui, +HwndhChild -Caption
Gui, Add, Button, , AHK_Button
DllCall("SetParent", "ptr", hChild, "ptr", hParent)
Gui, Show, x20 y0 NA

WinSet, Style, -0x80000000, ahk_id %hChild% ; Remove WS_POPUP style
WinSet, Style, +0x40000000, ahk_id %hChild% ; Add WS_CHILD style
return
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Overlay GUI With Dynamically Selected Buttons

28 Sep 2017, 14:36

Okay, knowing that I can add "child" buttons onto a GUI like that is awesome, thank you very much for that.

My main concern with this project, though, is less how to display the buttons and more how to dynamically display only the buttons appropriate for the current moment, along with repositioning the buttons so that they are in a neat row no matter how many buttons there are.

For example, suppose the user is currently in "mode 1". There are four buttons that should display: "Do Foo", "Undo Foo", "Report Foo", and "Random Foo". However, the "Undo Foo" button should only display if {control on the parent application} has text in it. And if the user switches to "mode 2", then an entirely different set of five buttons should display.

On top of that, I have a function, Bar, that when called adds a new button - "Do Bar". This button displays in all modes, but only after that function is called.

Is that sort of dynamic GUI possible?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Overlay GUI With Dynamically Selected Buttons  Topic is solved

28 Sep 2017, 21:32

Yes, it is possible. Take a look at Tab and Toolbar controls. To show/hide control use GuiControl.

Just a quick example of Tab control:

Code: Select all

Gui, 99:+HwndhParent
Gui, 99:Add, Button,, This is the parent button
Gui, 99:Show, w600 h300
;------------------------------------------------------------------------
Gui, +HwndhChild -Caption +Border
Gui, Add, Tab2, Buttons w420 h30 vContainer AltSubmit, Mode1|Mode2

; You can also hide the Tab buttons, by specifing "w0 h0" options
; Gui, Add, Tab2, w0 h0 vContainer AltSubmit, Mode1|Mode2

Gui, Tab, 1
	Gui, Add, Button, xm Section gOnClick vBtn1, Do Foo
	Gui, Add, Button, gOnClick x+30, Undo Foo
	Gui, Add, Button, gOnClick x+30, Report Foo
	Gui, Add, Button, gOnClick x+30, Random Foo
Gui, Tab, 2
	GuiControlGet, Btn1, Pos
	Gui, Add, Button, x%Btn1X% y%Btn1Y% gOnClick, Do Foo 2
	Gui, Add, Button, gOnClick x+30, Undo Foo 2
	Gui, Add, Button, gOnClick x+30, Report Foo 2
	Gui, Add, Button, gOnClick x+30, Random Foo 2
	Gui, Add, Button, gOnClick x+30, Five Foo 2
Gui, Tab ; The following controls will not belong to any "Tab"
	Gui, Add, Button, xm y+80 gAddNewButton, Add New Button
;------------------------------------------------------------------------
DllCall("SetParent", "ptr", hChild, "ptr", hParent)
Gui, Show, x20 y100 NA

WinSet, Style, -0x80000000, ahk_id %hChild% ; Remove WS_POPUP style
WinSet, Style, +0x40000000, ahk_id %hChild% ; Add WS_CHILD style
Return

GuiClose:
ExitApp

OnClick:
	GuiControlGet, BtnText,, % A_GuiControl
	ToolTip(BtnText " clicked")
	GuiControl, -Default, % A_GuiControl
return

AddNewButton:
	GuiControlGet, TabIndex,, Container
	Gui, Tab, %TabIndex%

	if !NewBtn_%TabIndex% {
		y := Btn1Y + 50
		Gui, Add, Button, x%Btn1X% y%y%, New button in Mode%TabIndex%
		NewBtn_%TabIndex% := true
	} else {
		MsgBox, Sorry`, but I'm too lazy to add new buttons
	}
return

ToolTip(Text, sec := 2) {
	ToolTip, % Text
	if sec
		SetTimer, ToolTip_Remove, % -1 * sec * 1000
	return

	ToolTip_Remove:
		ToolTip
	return
}
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Overlay GUI With Dynamically Selected Buttons

29 Sep 2017, 10:02

Thanks! That's super helpful, I never would have thought of using a tab control for that.

That should be everything I need to make this project work, I really appreciate that.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Anput, Google [Bot] and 325 guests