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 ?
Managing g-labels with dynamic names Topic is solved
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
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.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.
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
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
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.
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()
Re: Managing g-labels with dynamic names
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
Re: Managing g-labels with dynamic names Topic is solved
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
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
Wow, this code works...
... I just don't understand why !
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 :
At least I can understand this one.
Code: Select all
Go:
If (WinActive("A") = GuiID)
Current := Sx2
Else
Current := Sx1
Gui, %Current%Gui: Submit, NoHide
SetLevel(Current, A_GuiControl)
Return
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
Re: Managing g-labels with dynamic names
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.
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
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 :
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 :
Code: Select all
Go:
If (WinActive("A") = WinExist(%Sx1%Gui))
Current := Sx1
Else
Current := Sx2
Re: Managing g-labels with dynamic names
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:Jose Hidalgo wrote: ↑ That I understand, it's exactly what I thought.
Code: Select all
Gui, +HwndGuiID
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: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 ?
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
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
Thanks for clearing that out. I think I finally got it.
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 :
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 ! 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 , !
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).
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 ! 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 , !
Re: Managing g-labels with dynamic names
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 names (do they need one % on the left with a space or one % on each side, or no % at all),
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: ↑ Variable types (are they dynamic or static, are they global or local)
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 a dynamic part of the name (e.g. staticpart%dynamicpart% or %dynamicpart%staticpart) : sometimes it's allowed and sometimes it's not
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: ↑ 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.
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: ↑ Confusion between things that are user-variables and things that are not (like I just did with GuiID)
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: ↑ 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.
Believe it or not, I started the exact same year with my Atari 800.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.
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 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 ! 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 , !
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
Thank you so much for all this ! 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 ).
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 !
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 !
Re: Managing g-labels with dynamic names
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 wrote: ↑19 May 2021, 08:25Me, 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 !
-
- Posts: 222
- Joined: 07 Mar 2021, 07:44
Re: Managing g-labels with dynamic names
... and you became so good at AHK, that either you're incredibly brilliant, or you had a lot of free time to learn !
Anyway, I'm doing my best here, I promise. But one thing is sure : things were easier with a TRS-80 !
Anyway, I'm doing my best here, I promise. But one thing is sure : things were easier with a TRS-80 !
Re: Managing g-labels with dynamic names
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.
Keep at it. More things click into place the more you use it and see examples of code written by more experienced AHK users.
Who is online
Users browsing this forum: RussF and 368 guests