Managing g-labels with dynamic names Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Managing g-labels with dynamic names

18 May 2021, 07:30

Hi all, I did some online searching but didn't found a reply that would apply to g-labels.

I'm trying to use a loop to create two separate GUIs, each one with sliders. At some point in the loop there's this code :

Gui, %guiName%: Add, Slider, % "x" 27 + 75 * (A_Index - 1) " y25 h80 w25 TickInterval1 Line1 Vertical Invert Range-2-2 vThisSliVal" A_Index " gGo Buddy1ThisTopText" A_Index " Buddy2BottomText" A_Index, 0

The "Go" label is called. But since "Go" is not a variable, then it's the same label name for both GUIs, which means that it won't work.
I'd need a separate label for each GUI. So ideally I'd need something like g%Variable name%. Unforaunately that doesn't seem to work.
I can just replace the loop and do everything twice. That will work, but it's not very elegant. Is there another solution ?
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

18 May 2021, 07:49

Jose Hidalgo wrote: then it's the same label name for both GUIs, which means that it won't work.
...
I'd need a separate label for each GUI. So ideally I'd need something like g%Variable name%. Unforaunately that doesn't seem to work.
You can have the same label for two GUIs as shown below. I guess you're saying you don't want to. You can use a variable name with a G-label, also as shown below with both expression and legacy syntax. You must have some other issue with your script.

Code: Select all

BtnLabel := "Go"
Gui, Add, Button, % "w100 g" BtnLabel, GO
Gui, Show

Gui, 2:Add, Button, w100 g%BtnLabel%, GO
Gui, 2:Show, x100 y100
return

Go:
	MsgBox, GO pressed
return

GuiClose:
ExitApp
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

18 May 2021, 09:10

I'm sorry to be bothering you (again) with this. But its either that or giving up on the project, so...

I'm basically using the same working script that you already saw in another topic. I just modified it to work with two GUIs instead of one.
Each GUI or GUI-dependant parameter now has a Sx1 or Sx2 prefix ("Left" or "Right"). The rest is just the same, so I guess I'm close to making it work.

I'm guessing it can't work like that, because in the Go subroutine it can't differentiate A_GuiControl for any of the GUIs.
I just don't know how to do it otherwise.

Code: Select all

win = Multi-Slider Window

global Usc := "_"
global Sx1 := "Left"
global Sx2 := "Right"

global SliNum     := 5

global SliName1 := "Text 1"
global SliName2 := "Text 2"
global SliName3 := "Text 3"
global SliName4 := "Text 4"
global SliName5 := "Text 5"

SliCol1 := "CC3333"
SliCol2 := "FF9900"
SliCol3 := "66FFCC"
SliCol4 := "CCFF66"
SliCol5 := "99FFFF"

SliTextSize := 14
SliFont     := "Calibri"

%Sx1%ActiveSli := 1
%Sx2%ActiveSli := 1

DrawSliders(Sx1)
Gui, LeftGui: show, x440 y85 w374 h130
DrawSliders(Sx2)
Gui, RightGui: show, x1720 y85 w374 h130
return

; ------------------------------------

DrawSliders(Listener)
{
  global
  guiName    := Listener "Gui"
  goListener := Listener
  Gui, %guiName%: +HwndGuiID
  Gui, %guiName%: +OwnDialogs
  Gui, %guiName%: -Caption +ToolWindow AlwaysOnTop
  Gui, %guiName%: Color, %BackColor%
  Gui, %guiName%: Font, s%SliTextSize%, %SliFont%
  loop, %SliNum%
  {
    ThisTopText := Listener "TopText"
    ThisCol     := SliCol%A_Index%
    ThisSliDis  := Listener "SliDis"
    ThisSliVal  := Listener "SliVal"
    ThisSliDis%A_Index% := 0
    ThisSliVal%A_Index% := 0
    Gui, %guiName%: Add, Text, vThisTopText%A_Index% c%ThisCol% Center w50, % ThisSliDis%A_Index% . " dB"
    Gui, %guiName%: Add, Text, vBottomText%A_Index% c%ThisCol%, % SliName%A_Index%
    Gui, %guiName%: Add, Slider, % "x" 27 + 75 * (A_Index - 1) " y25 h80 w25 TickInterval1 Line1 Vertical Invert Range-2-2 vThisSliVal" A_Index "  gGo Buddy1ThisTopText" A_Index " Buddy2BottomText" A_Index, 0
  }
  Return
}

Go:
  Gui, %Sx1%Gui: Submit, NoHide
  SetLevel(Sx1, A_GuiControl)
  Gui, %Sx2%Gui: Submit, NoHide
  SetLeve2(Sx1, A_GuiControl)
Return

; ------------------------------------

SetLevel(Listener, Control)
{
  global
  guiName := Listener "Gui"
  %Listener%ActiveSli := SubStr(Control, 0)

  ThisTopText := Listener "TopText"
  ThisSliDis  := Listener "SliDis"
  ThisSliVal  := Listener "SliVal"

  Gui, %guiName%: Submit, NoHide
  loop, %SliNum%
  {
    ThisSliDis%A_Index% := ThisSliVal%A_Index% * 3
    GuiControl,, ThisTopText%A_Index%, % ThisSliDis%A_Index% . " dB"
  }

  Enhancers(Listener)
  return
}

; ------------------------------------

ChangeVal(Listener, Num, Val)
{
  global
  guiName := Listener "Gui"
  If (Num = 0)
    Num := %Listener%ActiveSli

  ThisTopText := Listener "TopText"
  ThisSliDis  := Listener "SliDis"
  ThisSliVal  := Listener "SliVal"

  GuiControl,, ThisSliVal%Num%, % "+" Val

  Gui, %guiName%: Submit, NoHide
  ThisSliDis%Num% := ThisSliVal%Num% * 3
  loop, %SliNum%
    GuiControl,, ThisTopText%A_Index%, % ThisSliDis%A_Index% . " dB"
  Enhancers(Listener)
  return
}

; ------------------------------------

ChangeSli(Listener, Num)
{
  global
  guiName := Listener "Gui"
  ThisSliVal := Listener "SliVal"
  %Listener%ActiveSli := %Listener%ActiveSli + Num
  If (%Listener%ActiveSli < 1)
    %Listener%ActiveSli := 1
  If (%Listener%ActiveSli > SliNum)
    %Listener%ActiveSli := SliNum
  Gui, %guiName%: Submit, NoHide
  GuiControl, Focus, ThisSliVal%ActiveSli%
  return
}

; ------------------------------------

Enhancers(Listener)
{
  return
}

; ------------------------------------

QuitApp()
{
  FileDelete, %EnhFileLoc%
  ExitApp
}

; ------------------------------------

GuiClose:
ExitApp

; #If WinActive("ahk_id " GuiID)

#Right::ChangeSli(Sx1, 1)
#Left::ChangeSli(Sx1, -1)
#Up::ChangeVal(Sx1, 0, 1)
#Down::ChangeVal(Sx1, 0, -1)

#q::ChangeVal(Sx1, 1, -1)
#s::ChangeVal(Sx1, 1, 1)
#d::ChangeVal(Sx1, 2, -1)
#f::ChangeVal(Sx1, 2, 1)
#g::ChangeVal(Sx1, 3, -1)
#h::ChangeVal(Sx1, 3, 1)
#j::ChangeVal(Sx1, 4, -1)
#k::ChangeVal(Sx1, 4, 1)
#l::ChangeVal(Sx1, 5, -1)
#m::ChangeVal(Sx1, 5, 1)

<^>!Right::ChangeSli(Sx2, 1)
<^>!Left::ChangeSli(Sx2, -1)
<^>!Up::ChangeVal(Sx2, 0, 1)
<^>!Down::ChangeVal(Sx2, 0, -1)

<^>!q::ChangeVal(Sx2, 1, -1)
<^>!s::ChangeVal(Sx2, 1, 1)
<^>!d::ChangeVal(Sx2, 2, -1)
<^>!f::ChangeVal(Sx2, 2, 1)
<^>!g::ChangeVal(Sx2, 3, -1)
<^>!h::ChangeVal(Sx2, 3, 1)
<^>!j::ChangeVal(Sx2, 4, -1)
<^>!k::ChangeVal(Sx2, 4, 1)
<^>!l::ChangeVal(Sx2, 5, -1)
<^>!m::ChangeVal(Sx2, 5, 1)

#v:: QuitApp()
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

18 May 2021, 09:25

You can have your subroutine determine what the active window is, which would tell you which GUI the button press came from, like this:

Code: Select all

Gui, +HwndGuiID
Gui, Add, Button, w100 gGo, GO
Gui, Show

Gui, 2:Add, Button, w100 gGo, GO
Gui, 2:Show, x100 y100
return

Go:
	MsgBox, % "GO pressed from GUI #" . (WinActive("A") = GuiID ? 1 : 2)
return

GuiClose:
ExitApp
just me
Posts: 9450
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Managing g-labels with dynamic names  Topic is solved

18 May 2021, 11:11

In this case A_Gui is your friend:

Code: Select all

#NoEnv
Gui, Margin, 100, 50
Gui, Add, Button, w100 gGo, GO
Gui, Show, x300 yCenter, #1
Gui, 2:Margin, 100, 50
Gui, 2:Add, Button, w100 gGo, GO
Gui, 2:Show, x700 yCenter, #2
Return
Go:
	MsgBox, GO pressed from GUI %A_Gui%
Return
GuiClose:
ExitApp
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

18 May 2021, 11:32

Wow, this code works...

Code: Select all

Go:
  If (WinActive("A") = GuiID)
    Current := Sx2
  Else
    Current := Sx1
  Gui, %Current%Gui: Submit, NoHide
  SetLevel(Current, A_GuiControl)
Return
... I just don't understand why ! :lol:
My script creates left Gui then right Gui.
Then I try clicking on either one of them. It works.
I may have misunderstood how WinActive("A") works. Could you elacorate that point ? Why would that condition be verified when the RIGHT window is active, and not verified when it's the LEFT one ?

EDIT - This code works too of course :

Code: Select all

  If (A_Gui = Sx1 "Gui")
    Current := Sx1
  Else
      Current := Sx2
At least I can understand this one. :lol:
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

18 May 2021, 11:46

WinActive returns the HWND of the specified window if it is active (0 if it is not), and since the window title is A (meaning the active window) in this case, it will surely return the HWND of that window. (We could have produced the same result with WinExist("A").) So then we simply compare the HWND of the active window to that of the main GUI, which is stored in the variable GuiID. If it is, we know the button on that GUI was clicked. If not, it had to be from clicking the button on the other GUI.
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

18 May 2021, 12:42

That I understand, it's exactly what I thought. :)
What I didn't understand is why (WinActive("A") = GuiID) is true only for the Right Gui, and false for the Left Gui. I'm now guessing it's because Right Gui was created last, so GuiID has its ID. If I had created the Left Gui last it would be the opposite, right ?

Maybe I should just change the code to this, at least it's not creation order-dependant :angel: :

Code: Select all

Go:
  If (WinActive("A") = WinExist(%Sx1%Gui))
    Current := Sx1
  Else
    Current := Sx2
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

18 May 2021, 13:59

Jose Hidalgo wrote: That I understand, it's exactly what I thought. :)
Apparently, you didn’t fully understand what I said because it answers your question below. GuiID in my example contains the HWND of the first GUI only because I assigned it to the specific variable name GuiID with the following line:

Code: Select all

Gui, +HwndGuiID

Jose Hidalgo wrote: What I didn't understand is why (WinActive("A") = GuiID) is true only for the Right Gui, and false for the Left Gui. I'm now guessing it's because Right Gui was created last, so GuiID has its ID. If I had created the Left Gui last it would be the opposite, right ?
If you assigned the HWND for both GUIs to the same variable, then it could only contain whichever one was last assigned. GuiID is just a variable name name I chose to assign the HWND for one of the GUIs. It’s not some inherent property of a GUI. If you want to capture both, use two separate variable names, like this:

Code: Select all

Gui, +HwndGui1ID
Gui, Add, Button, w100 gGo, GO
Gui, Show

Gui, 2:+HwndGui2ID
Gui, 2:Add, Button, w100 gGo, GO
Gui, 2:Show, x100 y100
return
In my example, I didn’t need to capture the second one because by process of elimination, if the HWND of the active window didn’t equal the HWND of the first GUI, then it had to be the second. But I wouldn’t have used the same variable name for both GUIs.
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

19 May 2021, 05:11

Thanks for clearing that out. I think I finally got it. :thumbup:
boiler wrote:
18 May 2021, 13:59
Apparently, you didn’t fully understand what I said
That is of course true. And I guess it will be a long time before I finally understand how AHK works. I have done some programming in the past, in various languages, but it wasn't nearly as difficult as this.
Saying that AHK has a steep learning curve would be an understatement IMHO. And most of it is due to its complicated / non-intuitive syntax that creates confusion between many things.

I spend 80% of my AHK debugging time only with variables :
  • Variable names (do they need one % on the left with a space or one % on each side, or no % at all),
  • Variable types (are they dynamic or static, are they global or local),
  • Variables with a dynamic part of the name (e.g. staticpart%dynamicpart% or %dynamicpart%staticpart) : sometimes it's allowed and sometimes it's not,
  • Variables with two dynamic parts of the name (e.g. LeftVariable1, Rightvariable1, LeftVariable2 and RightVariable2) : these seem to be particularly hard to assemble and to evaluate.
  • Confusion between things that are user-variables and things that are not (like I just did with GuiID)
  • And most importantly, do variables return the expected value at any given moment, within the same function or between different functions).
All the other AHK things are great and allow for amazing possibilities, but variables... OMG. :crazy:

I'm not complaining though : AHK is free and as such nobody can complain. I'm just stating the difficulties that a beginner like me (not even in programming, I started in 1980 when I was 10 years old) has to go through in order to understand it. I have watched tutorials and I read documentation pages (such as the GUI page) every day... so many times, but it's still not enough. And spending so much time on syntax debugging and variable value testing doesn't allow us to be as productive as we should.

EDIT : here's another example. Yesterday I literally spent several HOURS before realizing that the GuiControl command could (and should in my case) be used with a GUI name ! :shock: Why ? Because the GuiControl page ( https://www.autohotkey.com/docs/commands/GuiControl.htm ) doesn't state it clearly from the start ( GuiControl, SubCommand, ControlID , Value ) and you need to go through all the page to finally find out in the Remarks section that "To operate upon a window other than the default, include its name or number (or [in v1.1.03+] its HWND) followed by a colon in front of the sub-command" ! So you can do something like GuiControl %guiName%:, {rest of the line} . But don't you dare forget both %, plus the :, plus the , ! :lol:
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

19 May 2021, 06:31

Jose Hidalgo wrote: Variable names (do they need one % on the left with a space or one % on each side, or no % at all),
This is by far the most common source of confusion for beginners, and was for myself as well. I wish I had first read an overview about the two syntaxes. In AHK v2 (currently in alpha release), they do away with legacy syntax so everything uses expression syntax. You may have already read these parts of the documentation, but they are good to review: When to use percents (from tutorial), When are variable names enclosed in percent signs, Legacy Syntax, Expressions, and more details on expressions. Remember that function parameters are always in expression syntax, while command parameters are usually in legacy syntax, although they often allow expressions when stated in the documentation of the command. You can always force an expression to use expression syntax where legacy syntax is expected.

Jose Hidalgo wrote: Variable types (are they dynamic or static, are they global or local)
The above should help with dynamic variables. The main thing to remember about local variables is that is the default in functions, and that it's typically best to limit your use of global variables to when there are no better options. More here.

Jose Hidalgo wrote: Variables with a dynamic part of the name (e.g. staticpart%dynamicpart% or %dynamicpart%staticpart) : sometimes it's allowed and sometimes it's not
It's almost always allowed. you just have to be careful about expressing it correctly regarding the syntax you're using.

Jose Hidalgo wrote: Variables with two dynamic parts of the name (e.g. LeftVariable1, Rightvariable1, LeftVariable2 and RightVariable2) : these seem to be particularly hard to assemble and to evaluate.
You can pretty much avoid these kinds of approaches to dynamic variables if you want. The best way is to use arrays (true array objects, not pseudo-arrays).

Jose Hidalgo wrote: Confusion between things that are user-variables and things that are not (like I just did with GuiID)
That probably happens most when dealing with GUIs, and it gets easier the more you use them. It might help to familiarize yourself with the various built-in variables.

Jose Hidalgo wrote: And most importantly, do variables return the expected value at any given moment, within the same function or between different functions).
All the other AHK things are great and allow for amazing possibilities, but variables... OMG. :crazy:
The most important thing here is to remember variable scope. Variables are always local to a function (and only that function) unless you change that. Don't change it unless you have a good reason to do so. Making all your functions global can really make a mess of things.

Jose Hidalgo wrote: I'm not complaining though : AHK is free and as such nobody can complain. I'm just stating the difficulties that a beginner like me (not even in programming, I started in 1980 when I was 10 years old) has to go through in order to understand it.
Believe it or not, I started the exact same year with my Atari 800.

Jose Hidalgo wrote: EDIT : here's another example. Yesterday I literally spent several HOURS before realizing that the GuiControl command could (and should in my case) be used with a GUI name ! :shock: Why ? Because the GuiControl page ( https://www.autohotkey.com/docs/commands/GuiControl.htm ) doesn't state it clearly from the start ( GuiControl, SubCommand, ControlID , Value ) and you need to go through all the page to finally find out in the Remarks section that "To operate upon a window other than the default, include its name or number (or [in v1.1.03+] its HWND) followed by a colon in front of the sub-command" ! So you can do something like GuiControl %guiName%:, {rest of the line} . But don't you dare forget both %, plus the :, plus the , ! :lol:
Yes, a lot of the keys on how to use various commands and functions in certain situations are not clear unless you read the entire documentation page for it. The examples usually help as well. It's well worth reading through the whole page when first using a certain command or function.
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

19 May 2021, 08:25

Thank you so much for all this ! :bravo: Indeed some of the links I hadn't read yet. Sounds like I'm in for a lot of reading, and that's a good thing (I guess :? ).
boiler wrote:
19 May 2021, 06:31
Believe it or not, I started the exact same year with my Atari 800.
I'm glad that you can relate ! :) Me, I started with this beast : https://www.youtube.com/watch?v=4f_dyFk51o0 . It got me hooked into computer stuff. Great times !
So I did stuff with good old Basic Level II. Later on I moved to Turbo Pascal. Did some Cobol basics (mainly because my engineering school forced me to), then I stopped for more then 20 years, lol.
More recently I did a bit of Windows batch scripting (Cmd, PowerShell), some Python (not programming myself - mainly running other people's programs), and now... AHK ! :mrgreen:
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

19 May 2021, 10:53

Jose Hidalgo wrote:
19 May 2021, 08:25
Me, I started with this beast : https://www.youtube.com/watch?v=4f_dyFk51o0 . It got me hooked into computer stuff. Great times !
So I did stuff with good old Basic Level II. Later on I moved to Turbo Pascal. Did some Cobol basics (mainly because my engineering school forced me to), then I stopped for more then 20 years, lol.
More recently I did a bit of Windows batch scripting (Cmd, PowerShell), some Python (not programming myself - mainly running other people's programs), and now... AHK ! :mrgreen:
I never saw one of those, but I of course was familiar with the TRS-80 that it was based on. I also started with Basic and then a great language for the Atari named Action!, then Pascal in high school which became my favorite language. In engineering school, we used C and Fortran mainly, then I also stopped coding for about the same amount of time since I didn't need it for my job and because I didn't find programming in a Windows environment to be easy or fun, until I finally discovered AHK.
Jose Hidalgo
Posts: 222
Joined: 07 Mar 2021, 07:44

Re: Managing g-labels with dynamic names

19 May 2021, 12:06

... and you became so good at AHK, that either you're incredibly brilliant, or you had a lot of free time to learn ! :lol:
Anyway, I'm doing my best here, I promise. :oops: But one thing is sure : things were easier with a TRS-80 ! :lol:
User avatar
boiler
Posts: 16915
Joined: 21 Dec 2014, 02:44

Re: Managing g-labels with dynamic names

19 May 2021, 17:46

Thanks. Actually, I'm really only adequately skilled at AHK for my purposes. There are many experts on the forum that I continue to learn from. But yes, I was able to spend a lot of time using AHK on various ventures over the last several years.

Keep at it. More things click into place the more you use it and see examples of code written by more experienced AHK users.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: RussF and 368 guests