为什么表达式:If (A:=!A) 每次按下热键时的计算结果都不一样?
Why does the expression: If (A:=!A) evaluate differently each time a hotkey is pressed?
在 Autohotkey 脚本中,一旦用户按下 CapsLock 键,SplashText 应该弹出,表明它已打开,或者当它关闭时退出,这里的问题不在于让它工作的代码,而是它可以变得多么简单。
有不同的方法,有些需要大约 25 行,有些使用 SetTimer 和 GetKeyState 内部函数和几个循环来达到 运行,有些只有五个,没有循环。
最简单的:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (Tog:=!Tog)
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
else
SplashTextOff
return
If (Tog:=!Tog) 怎么这么容易得到这个代码运行ning? Tog 只是一个未初始化的变量,每次按下 CapsLock 它都会不断地从 1 到 0
改变它的值
好像是在代码中充当Flag?我在这一行中缺少什么:
If (Tog:=!Tog)
是什么让它每次评估都不同?
下面是另一种方法 A = 0 作为开关工作,我做了这个,但它并没有我想要的那么简单是,但它完成了工作。
更长的代码:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (A = 0)
{
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
A=1
}else
{
SplashTextOff
A=0
}
return
最长的代码:
最后一个得到相同的结果,但检查密钥的实际物理状态它不会依赖脚本顶部的 SetCapsLockState, Off 来确保switch 将在一行中完成其余的工作,因为它更简单。
#SingleInstance Force
#Persistent
SetTimer, StateCapsLockON_Timer, 100
Return
~CapsLock::
StateCapsLockON_Timer
If GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, 100
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
SetTimer, StateCapsLockON_Timer, Off
}
Return
StateCapsLockOFF_Timer:
If !GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, Off
SplashTextOff
SetTimer, StateCapsLockON_Timer, On
}
Return
关于 If (Tog:=!Tog) 在这三个例子中最简单的例子中的工作方式有什么好的想法吗?
我现在知道了,检查 logical-not 这个 link:
https://lexikos.github.io/v2/docs/Variables.htm
如果操作数(在本例中为 Tog)为空或 0,则应用 logical-not(或 !Tog) 为 1,表示 "true"。否则,结果为 0(假)
if (Tog = 0)
Tog = 1
会带来与以下相同的结果:
If Tog:=!Tog
因为在 If 甚至检查更改的值之前就已经发生了操作,所以 if 不仅仅是比较数据,操作发生在 if 之前,因为括号内的值不仅被读取而且还被更改并且变量被重新分配。
(表达式) 括号中的任何 sub-expression。例如,(3 + 2) * 2 强制首先计算 3 + 2。
主要区别在于赋值运算符 :=
与比较运算符 =
的用法不同。因为,如您所见,您可以计算 if-statement 中的表达式,您实际上可以在同一个 if-statement 中包含两个运算符。这是一个例子:
f1::
If (( test := 3+2 ) = 5 )
MsgBox
Return
这里"test"是先赋值3+2之和,然后和5进行比较。所以,关键是if-statements允许赋值,先赋值,也就是说,在比较任何内容并将其评估为真或假之前。
如果没有比较运算符(=、<、>、<=、>=),就像您的切换中的情况一样,它只会评估变量本身是真还是假。如果变量为空白、0 或 false,则计算结果为 false;其他一切都是真的,即使是字符串 "false".
现在有趣的是。如果我们使用 Progress
和 "zh0" 选项,我们实际上可以将您的代码减少到一行。
~CapsLock::Progress , % ( Tog := !Tog ) ? "zh0 w350 h35" : "Off" ,, [CapsLock] Activated. , Wanted !
不幸的是,SplashText
无法做到这一点,因为它们实际上是两个独立的命令。但好处是 Progress
实际上有更多可用选项,因此您可以更改字体大小和颜色等。
在 Autohotkey 脚本中,一旦用户按下 CapsLock 键,SplashText 应该弹出,表明它已打开,或者当它关闭时退出,这里的问题不在于让它工作的代码,而是它可以变得多么简单。
有不同的方法,有些需要大约 25 行,有些使用 SetTimer 和 GetKeyState 内部函数和几个循环来达到 运行,有些只有五个,没有循环。
最简单的:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (Tog:=!Tog)
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
else
SplashTextOff
return
If (Tog:=!Tog) 怎么这么容易得到这个代码运行ning? Tog 只是一个未初始化的变量,每次按下 CapsLock 它都会不断地从 1 到 0
改变它的值好像是在代码中充当Flag?我在这一行中缺少什么:
If (Tog:=!Tog)
是什么让它每次评估都不同?
下面是另一种方法 A = 0 作为开关工作,我做了这个,但它并没有我想要的那么简单是,但它完成了工作。
更长的代码:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (A = 0)
{
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
A=1
}else
{
SplashTextOff
A=0
}
return
最长的代码:
最后一个得到相同的结果,但检查密钥的实际物理状态它不会依赖脚本顶部的 SetCapsLockState, Off 来确保switch 将在一行中完成其余的工作,因为它更简单。
#SingleInstance Force
#Persistent
SetTimer, StateCapsLockON_Timer, 100
Return
~CapsLock::
StateCapsLockON_Timer
If GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, 100
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
SetTimer, StateCapsLockON_Timer, Off
}
Return
StateCapsLockOFF_Timer:
If !GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, Off
SplashTextOff
SetTimer, StateCapsLockON_Timer, On
}
Return
关于 If (Tog:=!Tog) 在这三个例子中最简单的例子中的工作方式有什么好的想法吗?
我现在知道了,检查 logical-not 这个 link:
https://lexikos.github.io/v2/docs/Variables.htm
如果操作数(在本例中为 Tog)为空或 0,则应用 logical-not(或 !Tog) 为 1,表示 "true"。否则,结果为 0(假)
if (Tog = 0)
Tog = 1
会带来与以下相同的结果:
If Tog:=!Tog
因为在 If 甚至检查更改的值之前就已经发生了操作,所以 if 不仅仅是比较数据,操作发生在 if 之前,因为括号内的值不仅被读取而且还被更改并且变量被重新分配。
(表达式) 括号中的任何 sub-expression。例如,(3 + 2) * 2 强制首先计算 3 + 2。
主要区别在于赋值运算符 :=
与比较运算符 =
的用法不同。因为,如您所见,您可以计算 if-statement 中的表达式,您实际上可以在同一个 if-statement 中包含两个运算符。这是一个例子:
f1::
If (( test := 3+2 ) = 5 )
MsgBox
Return
这里"test"是先赋值3+2之和,然后和5进行比较。所以,关键是if-statements允许赋值,先赋值,也就是说,在比较任何内容并将其评估为真或假之前。
如果没有比较运算符(=、<、>、<=、>=),就像您的切换中的情况一样,它只会评估变量本身是真还是假。如果变量为空白、0 或 false,则计算结果为 false;其他一切都是真的,即使是字符串 "false".
现在有趣的是。如果我们使用
Progress
和 "zh0" 选项,我们实际上可以将您的代码减少到一行。
~CapsLock::Progress , % ( Tog := !Tog ) ? "zh0 w350 h35" : "Off" ,, [CapsLock] Activated. , Wanted !
不幸的是,SplashText
无法做到这一点,因为它们实际上是两个独立的命令。但好处是 Progress
实际上有更多可用选项,因此您可以更改字体大小和颜色等。