函数| AutoHotkey

文章推薦指數: 80 %
投票人數:10人

然而, 当函数传递给它自己全局变量, 静态变量或ByRef 参数时不会产生这样的问题. 如果一个参数在函数调用中被解析为一个变量(例如 Var 或 ++Var 或 Var*=2 ) ... 函数 目录 介绍和简单示例 参数 可选参数 返回值给调用者 可变参数函数 局部和全局变量 动态调用函数 优化布尔求值 在函数中使用子程序 Return,Exit及一般说明 使用#Include在多个脚本间共享函数 函数库:标准库和用户库 内置函数 介绍和简单示例 函数类似于子程序(Gosub),不过它还可以从调用者那里接受参数(输入).而且,函数还可以返回值给调用者.参考下面的例子,Add函数接受两个参数并返回它们之和: Add(x,y) { returnx+y;"Return"可直接返回表达式的结果. } 上面就是一个函数定义,因为它创建了一个名称为"Add"(不区分大小写)的函数,并且确立了调用它时必须准确的提供两个参数(x和y).要调用此函数,请把它的结果通过:=运算符赋值给变量.例如: Var:=Add(2,3);数字5将被保存到Var. 当然,调用函数时也可以不保存其返回值: Add(2,3) 不过这种情况下,函数的任何返回值都会被丢弃;所以除非函数还有除了返回值之外的功能(译者注:比如函数内修改了全局变量;通过ByRef修改了变量值...等等),否则这次调用毫无意义. 由于函数调用属于表达式语法,所以在其参数列表中的任何变量名称都不应该用百分号包围.同时,表示原义字符串的变量则应该用双引号包围.例如: ifInStr(MyVar,"fox") MsgBoxThevariableMyVarcontainsthewordfox. 最后,通常在命令的参数中也可以调用函数(除了像StringLen中的OutputVar和InputVar这种参数之外).另外,在不支持表达式的参数中调用函数时必须加上"%"前缀(百分号加一个空格),例如: MsgBox%"Theansweris:".Add(3,2) 在原生支持表达式的参数中也允许加上"%"前缀,但它只是会被忽略. 参数 定义函数时,其参数都在其名称后面的括号中列出(函数名和左括号之间不能有空格).如果函数不接受任何参数,请把括号留空,例如:GetCurrentTimestamp(). ByRef参数:从函数的角度看,参数本质上是局部变量,除非它们被定义为ByRef,例如: Swap(ByRefLeft,ByRefRight) { temp:=Left Left:=Right Right:=temp } 在上述例子中,ByRef的使用让相应的参数变成从调用者传递进来的变量的一个别名.换句话说,参数和调用者的变量都引用内存中相同的内容.这样使得Swap函数可以通过移动Left的内容到Right中来修改调用者的变量,反之亦然. 与之相比,在上述例子中如果没有使用ByRef,Left和Right将是调用者变量的副本,因此Swap函数不会对外部产生影响. 由于return只能返回一个值给函数的调用者,所以可以使用ByRef返回更多的结果.这是通过函数将调用者传递进来的变量(通常为空值的变量)赋值实现的. 传递大字符串给函数时,使用ByRef提高了性能,并且通过避免生成字符串的副本节约了内存.同样地,使用ByRef送回长字符串给调用者通常比类似ReturnHugeString的方式执行的更好. [AHK_L60+]:如果传递给ByRef参数的变量是不可修改的,那么函数会表现的就像没有"ByRef"关键字一样.例如,Swap(A_Index,i)保存A_Index的值到i中,但是当Swap函数返回时赋给Left的值会被丢弃.(译者注:因为A_Index是只读的内置变量.) [v1.1.01+]:IsByRef()函数可以用来判断调用者是否为指定的ByRef参数提供了变量. 已知限制: 对象的属性在ByRef的参数中不会被视为变量.例如,如果foo.bar传递给ByRef参数,那么它将表现的就像没有ByRef关键字一样. 不能传递Clipboard,内置变量或环境变量给函数的ByRef参数,无论脚本中有没有#NoEnv语句. 尽管函数可以递归调用它自己,但是如果它传递它自己的一个局部变量或非ByRef参数给自己的ByRef,那么新一层的ByRef参数将引用它自己那个名称的局部变量而不是之前层的.然而,当函数传递给它自己全局变量,静态变量或ByRef参数时不会产生这样的问题. 如果一个参数在函数调用中被解析为一个变量(例如Var或++Var或Var*=2),它左边或右边的其他参数可能在它被传递给函数前修改这个变量.例如,当Var初始为0时MyFunc(Var,Var++)会意外地传递1和0,即使函数的首个参数不是ByRef类型时.因为这种行为是违反常规的,所以可能在将来的版本中改变. ByRef不直接支持函数调用COM客户端,或调用COM方法.作为替代,脚本必须接受或传递一个wrapperobject(包装对象)包含特殊的VarType(变量类型)和变量内存地址. 可选参数 定义函数时,可以把它的一个或多个参数标记为可选的.这可以通过在参数后添加一个:=(在[v1.1.09]及以后的版本)或=,后面跟着参数的默认值来表示.参数的默认值必须是下列形式中的一种:true,false,原义的整数,原义的浮点数或引号包围的/原义的字符串例如"fox"或""(但在[1.0.46.13]之前的版本中字符串只支持""). 允许使用=(没有冒号)是为了向后兼容,但是已经不推荐使用,而且AutoHotkeyv2将不再允许这样做.不管使用哪种操作符,字符串格式的默认值总是被双引号包围的. 下面这个函数中的Z参数就是一个可选参数: Add(X,Y,Z:=0){ returnX+Y+Z } 当调用者传递三个参数给上面的函数时,Z的默认值被忽略.但当调用者仅传递两个参数时,Z自动接受默认值0. 可选参数不能孤立地放在参数列表的中间.换句话说,在首个可选参数右边的所有参数都必须定义为可选的.[AHK_L31+]:调用函数时可以省略参数列表中间的可选参数,如下所示:从[v1.1.12]开始,动态调用函数或方法时也支持这种特性. MyFunc(1,,3) MyFunc(X,Y:=2,Z:=0){;注意:这里的Z必须是可选参数. MsgBox%X%,%Y%,%Z% } 从[v1.0.46.13]开始,ByRef参数也支持默认值;例如:MyFunc(ByRefp1="").每当调用者省略这样的参数时,函数会创建一个包含默认值的局部变量;不过,这种情况下"ByRef"关键字没有任何意义. 返回值给调用者 如介绍中所说,函数可以返回一个值给调用者. Test:=returnTest() MsgBox%Test returnTest(){ return123 } 如果要从函数中返回额外的结果,可以使用ByRef: returnByRef(A,B,C) MsgBox%A","B","C returnByRef(ByRefval1,ByRefval2,ByRefval3) { val1:="A" val2:=100 val3:=1.1 return } [v1.0.97+]:可以使用对象和数组返回多值甚至是命名值: Test1:=returnArray1() MsgBox%Test1[1]","Test1[2] Test2:=returnArray2() MsgBox%Test2[1]","Test2[2] Test3:=returnObject() MsgBox%Test3.id","Test3.val returnArray1(){ Test:=[123,"ABC"] returnTest } returnArray2(){ x:=456 y:="EFG" return[x,y] } returnObject(){ Test:={id:789,val:"HIJ"} returnTest } 可变参数函数[AHK_L60+] 定义函数时,在最后一个参数后面写一个星号来标记此函数为可变参数的,这样让它可以接收可变数目的参数: Join(sep,params*){ forindex,paraminparams str.=param.sep returnSubStr(str,1,-StrLen(sep)) } MsgBox%Join("`n","one","two","three") 调用可变参数函数时,通过保存在函数的最后参数中的对象可以访问剩余的参数.函数的首个超出参数是params[1],第二个是params[2]以此类推.和所有的标准对象一样,使用params.MaxIndex()可以确定最大的索引值(这里为参数的数目).但是如果没有参数,MaxIndex会返回空字符串. 注意: "可变"参数只可以出现在显式参数(形参)列表的末尾. RegEx调出函数不是可变参数的,虽然允许使用"可变的"参数但是那只是留空而已. 回调函数通过地址而不是数组传递剩余参数. 可变参数函数调用 虽然可变参数函数可以接受可变数目的参数,不过在函数调用中使用相同的语法可以把数组作为参数传递给任何函数: substrings:=["one","two","three"] MsgBox%Join("`n",substrings*) 注意: 在源数组中参数的编号从1开始. 数组中的可选参数可以完全省略. 调用自定义函数时数组参数可以包含命名项,在其他情况下则不支持命名项. 目标函数也可以是可变的,此时命名项被复制,即使它们没有一致的形式参数. 这样的语法还可以用于调用对象的方法或获取对象的属性;例如,Object.Property[Params*].从[v1.1.12]开始,它还可以用于设置属性. 已知限制: 只有最右边的那个参数才可以这样展开.例如,支持MyFunc(x,y*)但不支持MyFunc(x*,y). 在星号(*)和参数列表中最后的形式参数间不能存在任何的非空白字符. 局部变量和全局变量 局部变量 局部变量是特定于单个函数的,只在该函数内可见.因此,局部变量可能具有与全局变量相同的名称,并且两个变量都有单独的内容.不同的函数也可以安全地使用相同的变量名. 当函数返回值时,所有非静态的局部变量都自动释放(变为空). 像Clipboard,ErrorLevel和A_TimeIdle这样的内置变量不会是局部的(它们可以从任何地方访问),并且不能被重新声明. 默认情况下,函数假定是局部的.在函数内访问或创建的变量默认为局部的,但以下情况除外: 超级全局变量,包括classes(类). 动态变量引用,如果不存在同名的局部变量,则可以解析为现有的全局变量. 创建伪数组的命令,即使只声明第一个元素,也可以将所有创建的元素作为全局变量. 如下所示,也可以重写默认值(通过声明变量或改变函数的模式). 强制局部模式[v1.1.27+]:如果函数的第一行是单词"local",则假定所有变量引用(甚至是动态的)都是局部的,除非它们在函数内声明为全局的.与默认模式不同,强制局部模式具有以下行为: 函数内部没有声明时,超级全局变量(包括类)不能被访问. 动态变量引用遵循与非动态变量引用相同的规则.只有在函数中声明的全局变量才能被访问. 创建伪数组的StringSplit和其他命令遵循与非动态变量引用相同的规则(避免共同的混淆源). LocalSameAsGlobal警告永远不会被强制局部函数中的变量引发. 全局变量 要在函数中引用现有的全局变量(或创建新的),需要在使用前声明此变量为全局的.例如: LogToFile(TextToLog) { globalLogFileName;此全局变量之前已经在函数外的某个地方赋值了. FileAppend,%TextToLog%`n,%LogFileName% } 假设全局模式:如果函数需要访问或创建大量的全局变量,通过在函数的首行使用单词"global"或声明局部变量可以把函数定义为假设其所有的变量都是全局的(除了它的参数).例如: SetDefaults() { global;如果此函数的首行是类似于"localMyVar"这样的,那么这个单词可以省略. MyGlobal:=33;把33赋值给全局变量,必要时首先创建这个变量. localx,y:=0,z;在这种模式中局部变量必须进行声明,否则会假设它们为全局的. } 函数还可以使用这种假设全局模式来创建全局数组,例如赋值给Array%A_Index%的循环. 超级全局变量[v1.1.05+]:如果全局声明出现在任何函数的外面,默认情况下它可以对所有函数有效(强制局部模式的函数除外).这样可以避免在每个函数中重复声明变量的需要.不过,如果声明了含有相同名称的函数参数或局部变量,那么它会优先于全局变量.由class关键字创建的变量也是超级全局的. 静态变量 静态变量总是隐式的局部变量,但和局部变量的区别是它们的值在多次调用期间是记住的.例如: LogToFile(TextToLog) { staticLoggedLines:=0 LoggedLines+=1;保持局部的计数(它的值在多次调用期间是记住的). globalLogFileName FileAppend,%LoggedLines%:%TextToLog%`n,%LogFileName% } 静态初始化:在[1.0.46]以前的版本中,所有的静态变量都是以空值开始;所以要检查静态变量首次被使用的唯一方法是检查它是否为空值.[v1.0.46+]:静态变量可以初始化为""外的其他值,通过在后面跟着:=或=及后面这些形式的其中一种:true,false,原义的整数,原义的浮点数或引号包围的/原义的字符串,如"fox".例如:staticX:=0,Y:="fox".每个静态变量只初始化一次(在脚本开始执行前). [AHK_L58+]:支持Staticvar:=expression.根据这些表达式在脚本中出现的顺序对它们进行计算,紧接着才进入脚本的自动执行段. 假设静态模式[v1.0.48+]:通过在函数的首行使用单词"static"可以把函数定义为假设其所有的变量都是静态的(除了它的参数).例如: GetFromStaticArray(WhichItemNumber) { static staticFirstCallToUs:=true;静态声明初始化仍然只运行一次(在脚本执行前). ifFirstCallToUs;在首次调用而不在后续的调用时创建静态数组. { FirstCallToUs:=false Loop10 StaticArray%A_Index%:="Value#".A_Index } returnStaticArray%WhichItemNumber% } 在假设静态模式中,任何非静态变量都必须声明为局部变量或全局变量(例外情况与假设局部模式相同,除非强制局部模式也有效). [v1.1.27+]:可以通过指定local然后static的方式将强制局部模式和假设静态模式组合在一起使用,如下面演示的那样.允许函数使用强制局部模式的规则,但默认情况下创建静态变量. globalMyVar:="Thisisglobal" DemonstrateForceStatic() DemonstrateForceStatic() { local static MyVar:="Thisisstatic" ListVars MsgBox } 关于局部和全局变量的更多信息 通过逗号分隔多个变量这样可以在同一行声明它们,例如: globalLogFileName,MaxRetries:=5 staticTotalAttempts:=0,PrevResult [v1.0.46+]:通过后面跟着:=或=及任意表达式,局部或全局变量可以在声明的同一行初始化(在声明时=运算符和:=作用相同).与静态初始化不同,在每次调用函数时都会对局部变量和全局变量进行初始化,但只在控制流实际达到它们所在的语句时.换句话说,像localx:=0这样的一行和写成单独的两行有同样的效果:localx后面跟着x:=0. 因为单词local,global和static都是在脚本运行时立即处理的,所以不能使用IF语句有条件的声明变量.换句话说,IF或ELSE的区块内的声明无条件对声明和函数的闭括号之间的所有行生效.同时还需注意当前还不支持声明动态变量,例如globalArray%i%. 对于创建伪数组的命令(例如StringSplit),如果假设全局模式没有生效或数组的首个元素已经声明为局部变量时创建的数组是局部的(如果函数的某个参数被传递时也是如此,即使此参数为ByRef类型,因为参数类似于局部变量).相反地,如果首个元素已经声明为全局的,那么创建全局的数组.不过,后面混乱的常见根源也适用于这些情况.StringSplit创建的数组首个元素为ArrayName0.对于其他创建数组的命令,例如WinGetList,首个元素为ArrayName(即没有数字).[v1.1.27+]:当强制局部模式生效时,这些命令遵循与普通变量引用一致的规则;也就是说,任何未声明为全局的伪数组元素都将是局部的,即使其他元素声明为全局的. 在函数(强制局部模式生效时除外)中,任何动态变量引用,例如Array%i%,总是解析为局部变量,仅当这样名称的局部变量不存在而全局变量存在时才解析为全局变量.如果两者都不存在并且需要创建此变量时,当假设全局模式没有生效时它被创建为局部变量.因此,仅当函数被定义为假设全局函数时,函数中才可以手动创建全局数组(通过使用类似Array%i%:=A_Index的方法). 混乱的常见根源:任何非动态引用都会在脚本运行时创建那个变量.例如,在函数外使用时,MsgBox%Array1%会在脚本运行的时候创建Array1为全局变量.相反地,在函数中使用MsgBox%Array1%会在脚本运行的时候创建Array1为函数的一个局部变量(除非假设全局模式生效),即使Array和Array0都声明为全局的. 动态调用函数 [v1.0.47.06+]:通过百分号可以动态调用函数(包括内置函数).例如,%Var%(x,"fox")将调用名称保存在Var中的函数.同样地,Func%A_Index%()将调用Func1()或Func2()等,这取决于A_Index的当前值. [v1.1.07.00+]:在%Var%()中的Var可包含函数名或函数对象.如果此函数不存在,则调用默认基对象的__Call元函数. 如果由于下面的某个原因无法调用函数,计算包含调用的表达式时可能会过早静默停止,这样可能会产生问题. 调用不存在的函数,这可以通过使用IfIsFunc(VarContainingFuncName)来避免.除了内置函数,被调用函数的定义必须真实存在于脚本中,通过类似#Include或对库函数的非动态调用的方法. 传递过少的参数,这可以通过检查IsFunc()的返回值来避免(这是强制参数的数目加上一的数字).[v1.0.48+]:注意允许传递过多的参数;每个额外的参数在被完全计算(包括任何函数调用)后丢弃. 最后,对函数的动态调用比正常调用稍慢,因为正常的调用在脚本开始运行前解析(查询). 优化布尔求值 当在表达式中使用AND,OR和三元运算符时,会对它们进行优化来提高性能(不管当前是否存在函数调用).通过不计算表达式中那些不影响最终结果的部分来进行优化运算.为了说明这个概念,请看这个例子: if(ColorName!=""ANDnotFindColor(ColorName)) MsgBox%ColorName%couldnotbefound. 在上面的例子中,如果ColorName变量为空则永远不会调用FindColor()函数.这是由于AND的左侧结果将为false,因此其右边不可能让最终的结果为true. 由于此特性,所以需要注意到,如果在AND或OR的右侧调用函数,那么函数可能永远不会产生副作用(例如改变全局变量的内容). 还需要注意在嵌套的AND和OR串联表达式的求值优化.例如,在后面的表达式中每当ColorName为空时只会进行最左边的比较.这是因为此时最左边的比较已经足以确定最终的结果: if(ColorName=""ORFindColor(ColorName,Region1)ORFindColor(ColorName,Region2)) break;搜索内容为空或找到了匹配. 从上面的例子可以看出,任何耗时的函数一般应该在AND或OR的右侧调用从而提高性能.这种方法还能避免调用接受了一个不合适的值例如空字符串的函数. [v1.0.46+]:三元条件运算符(?:)也通过不计算丢弃的分支进行求值优化. 在函数中使用子程序 尽管在一个函数中不能定义其他函数,但它可以含有子程序.与其他子程序一样使用Gosub运行它们且使用Return返回(此时Return属于Gosub而不是函数). 已知限制:当前每个子程序(标签)的名称在整个脚本中必须是唯一的.如果存在重复的标签,在运行前程序会通知您. 如果函数使用Gosub跳转到公共子程序(在函数外部的子程序),那么所有外面的变量都是全局的而且在子程序返回前无法引用函数自身的局部变量.不过,A_ThisFunc仍将包含正在执行的函数名称. 尽管不能使用Goto从函数中跳转到外面,但可以在函数中使用Gosub到外部/公共的子程序,然后在那里使用Goto. 尽管一般不鼓励使用Goto,但它能用来在同个函数中的一个位置跳转到其他位置.这样有助于简化包含许多个返回点而所有这些点在返回前需要进行一些清理的复杂函数. 函数可以包含能被外部调用的子程序,例如计时器,GUIg-标签和菜单项.通常把它们封装到一个单独的文件中供#Include使用,这样避免了它们和脚本的自动执行段的冲突.不过,还存在下面这些限制: 如果它们所在的函数曾经被正常调用,那么这样的子程序应该只使用静态和全局变量(不使用局部变量).这是由于中断函数调用线程的子程序线程(反之亦然)可以改变被中断线程看到的局部变量的值.此外,在任何时候函数返回到其调用者时,它包含的所有局部变量都被置空来释放占用的内存. 这样的子程序应该只使用全局变量(不使用静态变量)作为GUI控件的变量. 当一个子程序线程进入函数后,在此线程中任何对动态变量的引用都被视为是全局的(包括创建数组的那些命令). Return,Exit及一般说明 如果函数内的执行流在遇到Return前到达了函数的闭括号,那么函数结束并返回空值(空字符串)给其调用者.当函数明确省略Return的参数时也返回空值. 当函数使用Exit命令终止当前线程时,其调用者不会接收到返回值.例如,这个语句Var:=Add(2,3)中,如果Add()退出了那么Var会保持不变.如果函数出现了运行时错误,例如运行了一个不存在的文件(当UseErrorLevel选项不存在时),也会出现同样的情况. 如果要返回一个额外的容易记住的值,那么函数可以修改ErrorLevel的值来实现. 要使用一个或多个空值(空字符串)调用函数,可以使用空的引号对,例如:FindColor(ColorName,""). 因为调用函数不会开启新线程,所以函数对设置例如SendMode和SetTitleMatchMode做出的任何改变对其调用者同样有效. 函数的调用者可以传递不存在的变量或数组元素给它,当函数期望和ByRef一致的参数时这很有用.例如,调用GetNextLine(BlankArray%i%)会自动地创建局部或全局的变量BlankArray%i%(是局部还是全局取决于调用者是否在函数内并且它的假设全局模式是否有效). 在函数中使用ListVars时,它会显示函数的局部变量及其内容.这样可以帮助调试脚本. 风格和命名约定 您也许会发现,如果给复杂函数中的特定变量加上独特的前缀会让函数更容易阅读和维护.例如,使用"p"或"p_"开头来命名函数中的每个参数可以让它们的性质一目了然,尤其是当函数中有许多局部变量吸引您的注意力的时候.同样地,前缀"r"或"r_"可以用于ByRef参数,而"s"或"s_"可以用于静态变量. 在定义函数时可以使用OneTrueBrace(OTB)风格.例如: Add(x,y){ returnx+y } 使用#Include在多个脚本间共享函数 可以使用#Include指令(即使在脚本的顶部)从外部文件中加载函数. 说明:当脚本的执行流遇到函数定义时,它会跳过函数(使用一种瞬时的方法)并在函数闭括号后恢复执行.因此,开始执行时执行流不会陷入函数中,也不会因为在脚本的最顶部存在一个或多个函数而影响到自动执行段. 函数库:标准库和用户库[v1.0.47+] 脚本中可以不需要通过#Include而调用外部文件中的函数.要达到此目的,必须在下面某个库文件夹中存在与函数同名的文件: %A_ScriptDir%\Lib\;本地库,脚本所在目录中的Lib文件夹-需要[AHK_L42+]. %A_MyDocuments%\AutoHotkey\Lib\;用户库. directory-to-the-currently-running-AutoHotkey.exe\Lib\;标准库,当前运行的AutoHotkey.exe所在目录中的Lib文件夹. 例如,当脚本调用不存在的函数MyFunc()时,程序会在用户库中搜索名为"MyFunc.ahk"的文件.如果没有找到,会继续在标准库中搜索此文件.如果仍然没有找到匹配的文件且函数的名称含有下划线(例如MyPrefix_MyFunc),那么程序会在两个库中搜索名为MyPrefix.ahk的文件,如果找到则加载它.这样使得MyPrefix.ahk可以同时包含MyPrefix_MyFunc函数和其他名称以MyPrefix_开始的相关函数. [AHK_L42+]:支持本地库且本地库优先于用户库和标准库. 只有如MyFunc()这样直接的函数调用才能自动导入库.如果仅动态或间接调用该函数,就像计时器或GUI事件,那么库必须在脚本中明确的(显式)导入,例如:#Include 虽然库文件通常只包含和它的文件名称相同的单个函数,但它还可以包含仅被此函数调用的私有函数和子程序.然而,这样的函数应该使用相当明确清晰的名称,因为它们仍属于全局命名空间;也就是说,可以在脚本的任意位置调用它们. 如果库文件使用#Include,那么#Include的工作目录为库文件自身所在的目录.利用这个特性可以重定向到较大的库文件,其中包含此函数及相关内容. 脚本编译器(ahk2exe)同样支持库函数.不过,它要求在编译器目录的上一级目录中存在AutoHotkey.exe的副本(通常是这样).如果不存在AutoHotkey.exe,编译器仍可以运行但无法自动包含库函数. 从库中导入的函数和其他函数执行的一样好,因为在脚本开始执行前已经预加载了它们. 内置函数 在内置函数参数列表末尾的任何可选参数可以完全省略.例如,WinExist("Untitled-Notepad")是有效的,因为它的其他三个参数被认为是空的. 如果脚本定义了与内置函数同名的函数,那么内置函数会被覆盖.例如,脚本会调用它自己定义的WinExist()函数来代替标准的那个.然而,这样脚本将无法调用原来的函数. 在DLL文件中的外部函数可以使用DllCall()调用. 下列内置函数都可以通过点击它们的名称查看详细信息. 常用函数 函数 描述 FileExist 检查文件或文件夹是否存在且返回它的属性. GetKeyState 获取指定键盘按键是否被按下的状态,当指定按键被按下时返回true(1)否则返回false(0). InStr 从左侧或右侧截取给定字符串的一部分. RegExMatch 判断字符串是否包含某个匹配模式(正则表达式). RegExReplace 替换字符串中匹配模式(正则表达式)出现的地方. StrLen 获取给定字符串的长度. StrReplace 用新的字符串替换指定字符串出现的地方. StrSplit 使用指定的分隔符把一个字符串分解成多个子字符串并保存到数组中. SubStr 从字符串的指定位置获取一个或多个字符. WinActive 检查指定的窗口是否处于活动状态,并返回其唯一ID(HWND). WinExist 检查是否存在指定的窗口,并返回第一个匹配窗口的唯一ID(HWND). 杂项函数 函数 描述 Asc 返回指定字符串第一个字节或UTF-16编码单元的数值. Chr 返回指定数字所代表的字符编码中相对应的字符串(通常只有一个字节). DllCall 调用DLL文件中的函数,例如标准的WindowsAPI函数. Exception 创建一个用于抛出自定义异常的对象. FileOpen 打开文件,从其中读取特定内容和/或将新内容写入其中. Format 根据格式字符串,设置可变数量的输入值的格式. Func 获取指定函数的引用. GetKeyName/VK/SC 获取按键的名称/文本,虚拟按键码或扫描码. Hotstring 在脚本运行时创建,修改,启用或禁用热字串. IL_XXX ListView或TreeView控件用来添加图标/图片,创建或删除ImageLists的函数. InputHook 创建一个用于收集或拦截键盘输入的对象. IsByRef 如果指定的ByRef参数(按地址传递的参数)作为变量提供,则返回一个非零数字. IsFunc 如果脚本中存在指定的函数,则返回一个非零数字. IsLabel 如果脚本中存在指定的标签,则返回一个非零数字. IsObject 如果指定的值是对象,则返回一个非零数字. LoadPicture 从文件中加载图片并返回位图或图标句柄. LV_XXX 用于增加,插入,修改或删除ListView行/列的函数,还可以用于从中获取数据. MenuGetHandle 检索菜单的Win32菜单句柄. MenuGetName 检索给定其底层Win32菜单句柄的菜单的名称. NumGet 返回在指定地址+偏移的位置存储的二进制数. NumPut 以二进制格式把数字存储到指定地址+偏移的位置. ObjAddRef/ObjRelease 增加或减少对象的引用计数. ObjBindMethod 创建绑定函数对象,它能够调用给定对象的方法. ObjGetBase 检索对象的基对象. ObjRawGet 绕过对象的元函数,检索对象中的键值对. ObjRawSet 绕过对象的元函数,存储或覆盖对象中的一组键值对. ObjSetBase 设置对象的基对象. ObjXXX 相当于对象类型的内置方法的函数,如ObjInsertAt.通常建议使用相应的方法. OnClipboardChange 注册一个每当剪贴板内容发生改变时都会运行的函数或函数对象. OnError 指定一个在未处理错误发生时自动运行的函数. OnExit 指定一个在脚本退出时自动运行的函数. OnMessage 监听消息/事件. Ord 返回指定字符串中第一个字符的序号值(数字字符编码). SB_XXX 用于向状态栏控件添加文本/图标或划分状态栏的函数. StrGet 从内存地址复制字符串,并可以将其在不同代码页间进行转换. StrPut 复制字符串到内存地址,并可以对其在不同代码页间进行转换. RegisterCallback 创建机器码地址,当它被调用时会重定向到脚本中的函数. Trim/LTrim/RTrim 移除字符串的开头和/或末尾处的某些字符. TV_XXX 用于添加,修改或删除TreeView单元格的函数,还可用于从其中获取数据. VarSetCapacity 增加变量的容量或释放其内存. 数学函数 函数 描述 Abs 返回Number的绝对值. Ceil 返回Number的向上取整(不带任何.00后缀). Exp 返回e(近似值为2.71828182845905)的N次幂. Floor 返回Number的向下取整(不带任何.00后缀). Log 返回Number的对数(底数为10). Ln 返回Number的自然对数(底数为e). Max/Min 返回一个或多个数字的最大/最小值. Mod 返回被除数Dividend除以除数Divisor后得到的余数. Round 返回Number四舍五入到N个小数位的数字. Sqrt 返回Number的平方根. Sin/Cos/Tan 返回Number的sine(正弦)/cosine(余弦)/tangent(正切)值. ASin/ACos/ATan 返回Number的arcsine(反正弦)/arccosine(反余弦)/arctangent(反正切)的弧度值. COM 函数 描述 ComObjActive 检索已注册的COM对象. ComObjArray 创建用于COM的安全数组. ComObjConnect 将COM对象的事件源连接到具有给定前缀的函数. ComObjCreate 创建COM对象. ComObject 创建表示要作为参数或返回值传递的类型化值的对象. ComObjEnwrap/ComObjUnwrap 包装/解包COM对象. ComObjError 启用或禁用COM错误通知. ComObjFlags 检索或改变控制COM包装器对象行为的标志. ComObjGet 返回由COM组件提供的对象引用. ComObjMissing 创建要传递给COM方法的"缺少参数"对象. ComObjParameter 包装要作为参数传递给COM方法的值和类型. ComObjQuery 查询COM对象的接口或服务. ComObjType 从COM对象检索类型信息. ComObjValue 检索存储在COM包装器对象中的值或指针. 其他函数 Polyethene的命令函数:为每个有OutputVar的AutoHotkey命令提供了可调用的函数.可以通过#Include把这个库包含在任何脚本中.



請為這篇文章評分?