我有一个像这样的小测试脚本:
#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
其运行如下:
现在我想将其封装GuiControl
成一个函数,如下面的方法A:
BtnClicked()
{
gNum +=1
SetStaticText(gText, gNum) ;(A) elegant argument
}
SetStaticText(widget, num)
{
GuiControl, , widget, % num ; but it does NOT work
}
它不起作用。我肯定能找出问题所在,即widget
GuiControl 无法识别“变量名”。
所以我尝试了方法B,
BtnClicked()
{
gNum +=1
SetStaticText("gText", gNum) ;(B) ugly argument
}
SetStaticText(widget, num)
{
GuiControl, , %widget%, % num ; workable
}
方法 B 可行,但不太美观。调用者被迫传递字符串而不是变量。
所以我的问题是:我可以将函数封装为一种方法吗?
附注:Autohotkey 1.1.24
答案1
方法 A 您将变量 gText 的值传递给 SetStatic() 函数,但 GuiControl 需要一个控件名称,因此它得到的控件名称是“0”、“1”等,当然这不是“gtext”并且会失败。
方法 B 可以正确传递控件名称,并且正常工作。如果您想在函数之间正确传递控件名称,则需要将其保存在一个字符串变量中,正如您已经发现的那样。
如果你不喜欢将名字放在引号中,你可以这样做:
global gCtl := "gText"
BtnClicked()
{
gNum +=1
SetStaticText(gCtl, gNum) ;(A) elegant argument
}
执行此操作的一种方法是仅对控件和控制变量命名一次(因此,如果更改控件名称,则不必在多个地方修复它),如下所示。
#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
除了使用(并解决)现有的 AutoHotkey 语法之外,您还可以研究Function Objects
,这可能会(也可能不会)为您提供一种使用略有不同的语法来操纵函数执行的方法。然而,函数对象比上面的要复杂得多,所以在这种情况下,我甚至不会费心——只是让您知道它们的存在。