0

I have a small test script like this:

#SingleInstance, off

global gText
global gNum := 0

Gui, Font, s9 cBlack, Tahoma
Gui, Add, Text, w50 center vgText, % "0"
Gui, Add, Button, x+10 gBtnClicked, % "Add one"
Gui Show
return

BtnClicked()
{
    gNum +=1
    GuiControl, , gText, % gNum
}

GuiEscape:
GuiClose:
ExitApp

It runs as follows:

enter image description here

Now I want to encapsulate the GuiControl into a function, like method A below:

BtnClicked()
{
    gNum +=1
    SetStaticText(gText, gNum) ;(A) elegant argument
}

SetStaticText(widget, num)
{
    GuiControl, , widget, % num ; but it does NOT work
}

It does not work. I can surely identify the problem, which is, widget is not recognized "variable name" to GuiControl.

So I tried method B,

BtnClicked()
{
    gNum +=1
    SetStaticText("gText", gNum) ;(B) ugly argument
}

SetStaticText(widget, num)
{
    GuiControl, , %widget%, % num ; workable
}

Method B works, but it is ugly. Caller is forced to pass a string instead of a variable.

So my question is: Can I encapsulate the function as A method?

PS: Autohotkey 1.1.24

0

Method A you are passing the value of the variable gText to the SetStatic() function, but GuiControl expects a control name, so it gets a control name of '0', '1', etc. and of course that's not 'gtext' and fails.

Method B you pass the control name properly and it works properly. If you want to pass the control name around properly between functions you need to save it in a variable that's a string, as you have already discovered.

You could so something like this if you don't like putting the name in quotes:

global gCtl := "gText"

BtnClicked()
{
    gNum +=1
    SetStaticText(gCtl, gNum) ;(A) elegant argument
}

One way to do this where the control and control variable is named only once (so you don't have to fix it in multiple places if you change the control name), would be as follows.

#SingleInstance, off

;global gText       <-- you don't need this line
global gCtl := "gText"   ; store GUI control name as text
global gNum := 0


Gui, Font, s9 cBlack, Tahoma
Gui, Add, Text, % "w50 center v" gCtl, % "0"  ; this translates to "w50 center vgText", but will update automatically if you change the variable name in the global declaration section
Gui, Add, Button, x+10 gBtnClicked, % "Add one"
Gui Show
return

BtnClicked()
{
    gNum +=1
    SetStaticText(gCtl, gNum) ; elegant argument
}

SetStaticText(widget, num)
{

    GuiControl, , % widget, % num
}

GuiEscape:
GuiClose:
ExitApp

Besides just living with (and working around) the existing AutoHotkey syntax, you could also look into Function Objects, which may (or may not) give you a way to manipulate function execution using slightly different syntax. Function Objects are a lot more complex than the above however, so in this case I wouldn't even bother--just letting you know they exist.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.