word下载地址:http://pan.baidu.com/s/1jGJGagu
AutoIt教程:
第一天. 搭建并熟悉基本环境
1. 下载并安装AutoIt v3
AutoIt v3的官方下载页面地址:
http://www.autoitscript.com/autoit3/downloads.shtml
AutoIt V3的绿色版下载地址:
http://www.pc6.com/softview/SoftView_31114.html
AutoIt v3
的安装过程中,有一个选项需要注意:
建议选择”Edit the script“
这个页面是在设置在Windows资源管理器中双击.au3文件时的默认行为。最好选择“Edit the script”。早晚你会清楚,对于写程序的人来说,更多是在“Edit”而不是“Run”;另外,这也可以避免将来你“意外”执行了某个你并不想执行的AutoIt程序。
在其它的安装向导页面中一律直接按“Next>”键,直至安装完毕。
2. 下载并安装SciTE4AutoIt3
尽管autoit-v3-setup.exe中已经默认安装了一个简版的SciTE,但是最好还是去下载一个专门为AutoIt定制的SciTE4AutoIt3,其安装文件下载地址为:
http://www.autoitscript.com/cgi-bin/getfile.pl?../autoit3/scite/download/SciTE4AutoIt3.exe
在它的安装向导页面中一律按“Next>”键,直至安装完毕。
3. 修改一项Windows的默认设置
另外,Windows资源管理器中的默认设置之一是“隐藏已知文件类型的扩展名”[1] ,你最好将它改为“显示已知类性文件的扩展名”。否则你将来仅通过文件名 (无扩展名)和图标,根本无法分辨某个文件究竟是.au3源文件还是由.au3编译为.exe的可执行文件。
至于如何修改这个 选项,请用Google搜索(早晚你会明白善用Google多么重要;不懂用Google多么可怜):
- 如果你使用的是中文版Windows请点这个链接: 隐藏已知文件类型的扩展名 site:microsoft.com
- 如果你使用的是英文版Windows请点这个链接Do not show hidden files and folders site:microsoft.com
4. 创建au3文件
AutoIt v3的程序代码其实就是纯文本文件,你甚至可以用Windows自带的“记事本”程序(Notepad)编辑代码,而后保存为“.au3”文件(而非记事本程序默认的.txt文件)。另外,我们也可以在Windows资源管理器里的任何位置(比如桌面上)点鼠标右键,即可以看到一个“New> AutoIt V3 Script”的菜单:
新建AutoIt Script
5. 修改“新建模板”
刚刚安装AutoIt v3之后,在资源管理器里,通过点鼠标右键而后选择“New >AutoIt v3 Script”所创建的.au3文件里,都有一些预设的信息:
新建文件中的预设信息……
这些信息是可以修改的──它们都保存在“C:\Windows\ShellNew\Template.au3”文件之内。事实上,每个用户都有修改它的冲动。比如,你很可能想把“myName”替换为你的名字。而早晚你也会发现你有修改它的必要。
打开Windows资源管理器,浏览至“C:\Windows\ShellNew”目录,在“Template.au3”文件的图标上点鼠标右键,选择“EditScript”,即可打开SciTE编辑器,编辑其中的内容……(我最初的做法是直接删除所有内容,因为我每次只想要一个空白文档……)
6. 控制台输出窗口
最初使用SciTE的时候,它的“控制台输出窗口”是被“最小化”了的,你要把它的区域变得足够大,将来干起活来才方便。
放大控制台输出窗口
7. SciTE编辑器常用功能
SciTE是一款非常优秀的开源免费程序代码编辑器,理论上它支持所有的编程语言编辑(反正所有的程序代码基本上都保存为文本文件,只不过是尾缀各不相同而已)。SciTE具备一切现代程序代码编辑器常用的功能,比如关键字高亮,代码自动补全,随文帮助等等。
请尝试着输入以下一行代码:
ConsoleWrite("Hello!")
在输入“ConsoleWrite”的过程中,光标下方会出现一个提醒框;在你刚刚输入一个小写“c”的时候,屏幕显示是这样的:
再接着输入一个小写字母“o”,屏幕显示是这样的:
现在,你所需要输入的“ConsoleWrite”已经在“视野之中”了;你只需要按“下方向键”将蓝色条挪动到“ConsoleWrite”之上,
而后按回车键(Enter),刚刚你说输入的两个字母“co”就会被替换成大小写工整的ConsoleWrite:
现在,再输入一个左括号:
在光标的下方,可以看到该函数的简明介绍。(注意:暂且不要管“函数”是什么,也别管那简明介绍的内容究竟是什么意思……)
现在,再把光标挪回ConsoleWrite这一串字符中的任何一处,而后按F1键试试看。SciTE会打开AutoIt的帮助文件,而后自动定位到“ConsoleWrite”这个函数的文档页面。
随文帮助功能
另外,SciTE还支持变量自动补全(再次,暂时不要管“变量”是什么)。只要之前用到过的变量,它都会“光标跟随自动补全”:
变量的光标跟随自动补全功能
到此为止,你什么都没学会,倒是做了一堆事情。脑子里是一堆问号:“文本文件究竟是什么?”、“变量是什么?”,“函数是什么?”……别急,急也没用,一点一点来就是了。放心好了,这一切也许看起来很复杂,可实际上根本没有那么难。
另外,yonken将AutoIt 3.1.1版本的帮助文件翻译成了中文,可以在网络上找到,其中一个可用的下载地址是:http://u.115.com/file/f1833f1794。
可事实上,我希望这个教程的读者有初中以上的英语水平,能够阅读一些简单的英文文档。计算机的帮助文件(以及其它相关文档)中所使用的是极为简单、极为格式化的英语,很容易读懂,不会有过难的语法现象;遇到生词查词典就是了。将来你就会知道,所谓的编程工作中,1/3以上的时间是在阅读各种各样的文档;1/3以上的时间是在寻找相关的、且详尽的文档;剩下的有1/3不到的时间里,绝大部分在除错;如果代码量大到一定程度,那么还要花越来越长的时间写文档……其实只有极少的时间在写代码,与常人想象得恰恰相反,这其实很可能是整体工作量之中最没有技术含量的部分。所以,必须从一开始就习惯大量阅读英文文档──这才是真正的基本功。 还有一个必须从一开始就适应阅读英文文档的原因在于,翻译过来的文档很可能有差错的同时,又总是来得慢一拍。所以,我并不推荐你使用AutoIt中文版帮助。
作业
硬着头皮把AutoIt帮助文件中的两个章节读完(要精读,不论是否能够读懂──也就是说,即便读不懂(也当然不可能完全读懂),也要一个字不差地读完):
· Language Reference
· Keyword/StatementReference
AutoIt教程:
第二天. 最基本的概念
学习的一个秘密是:无论什么东西,不一定非要先搞懂,而是可以先随便试试,胡乱用用。年纪越大的人,越害怕“随便试试”;面对陌生的环境,越坚信自己还不懂,甚至不可能懂,宁可“无为而治”……
新建一个AutoIt文件,将其命名为Testing1.au3,输入以下代码:
$a =100
$b =100
$c =$a +$b
ConsoleWrite($c)
而后按F5键查看运行结果:
注意红框中的内容(点击上图看大图)
再新建一个AutoIt文件,将其命名为Testing2.au3,输入以下代码:
$s1 ="AutoIt"
$s2 ="Script"
$s3 =$s1 &$s2
ConsoleWrite($s3)
而后按F5键查看运行结果:
注意红框中的内容(点击上图看大图)
再新建一个AutoIt文件,将其命名为Testing3.au3,输入以下代码:
$b1 =True
$b2 =False
$b3 =$b1 And$b2
ConsoleWrite($b3)
$b4 =$b1 Or$b2
ConsoleWrite($b4)
而后按F5键查看运行结果:
注意红框中的内容(点击上图看大图)
计算机最擅长干的事(之一)当然是“计算”,不过,在编程语言里,我们更多使用“运算”这个术语,而不是“计算”,因为在自然语言中,“计算”这个动词的对象往往仅限于“数字”,而程序所要处理的“计算对象”,除了数字之外,还有很多种。比如,你刚刚试过的三段代码,分别是数值运算、字符串运算,和逻辑运算。
1. “变量”(Variable)
在AutoIt中,“$”符号用来标识变量。变量(variables)是用来保存数据(data)的,比如用来保存一个数值(digit),或者一个字符串(string),或者一个逻辑值(也称布林值,boolean)。所以,一个变量由以下三个部分构成:
- 变量名(name)
- 变量类型(type)
- 变量值(value)
比如,
- 在Testing1.au3中,$a这个变量,它的名称是“$a”,类型是“数值”,值是“100“
- 在Testing2.au3中,$s1这个变量,它的名称是“$s1”,类型是“字符串”,值是“AutoIt”
- 在Testing3.au3中,$b1这个变量,它的名称是“$b1”,类型是“字符串”,值是“True”
在AutoIt中,
- 变量必须以“$”开头做为标识
- 变量名的第一个字符必须是大小写字母或者下划线,其它部分还可以由数字构成
2. 运算符(Operator)
计算数值的运算符很直观:
- 加:+
- 减:-
- 乘:*
- 除:/
- 幂:^
字符串的运算符最常用的只有一个:
- 合并:&
逻辑运算符包括
- 与:And
- 或:Or
- 非:Not
- 等于:==
- 不等于:<>
- 大于:>
- 大于等于:>=
- 小于:<
- 小于等于:<=
3. 表达式(Expression)
表达式由变量(或“值”)与运算符构成。最终,每个合法的表达式都有运算结果,可被保存为某个变量的值。在这一行代码中:
$c =$a +$b
“$a + $b”就是一个表达式,它由两个变量($a、$b,它们各自已经拥有一个“数值类型”的“值”)和一个运算符(+)构成。最终,这个表达式的值是200,该行代码执行过后,这个值(200)被保存到变量$c之中,即,从此之后,变量$c的值为200。
4. 赋值(Assignment)
$a =100
或者
$c =$a +$b
看起来非常直观,可其中也有需要认真处理的细节。
新建一个AutoIt文件,将其命名为Testing4.au3,输入以下代码:
$a =100
$b =100
$c =$a +$b +$c
ConsoleWrite($c)
而后按F5键查看运行结果:
这一次,出错了……
SciTE提醒你,第3行第18个字符处(3,18)出了问题:
WARNING: $c: possibly used before declaration.
表达式中的任何变量,必须拥有“值”才能够参与运算。在这一行代码执行之前,我们并没有定义$c这个变量的值,所以它无法参与运算──于是SciTE报错了。
让我们重新来过,新建一个AutoIt文件,将其命名为Testing5.au3,输入以下代码(这一次,不要急于按F5运行代码,先用脑子演练一番):
$a =100
$b =100
$c =$a +$b
$c =$a +$b +$c
ConsoleWrite($c)
这一次,这段代码中的每一个表达式中的每一个变量都有值。
- 第1行代码执行过后,变量$a的值为100;
- 第2行代码执行过后,变量$b的值为100;
- 第3行代码执行过后,变量$c的值为100+100,即,200;
- ……
现在,既是难点又是要点的东西来了:“=”的意义。这个平时被我们称为等号的符号是绝大多数新手所能遇到的第一个真正的障碍。
注意:在程序代码中,“=”这个符号,并不对应这自然语言中的“等于”──在程序代码中,我们就不应该称它为“等号”!
“=”这个符号的意义用自然语言准确表述是这样的(稍微有点啰唆):
把它右边的表达式的运算结果保存为它左边的变量值。
也就是说,到了第4行代码,AutoIt编译器(又是一个暂时无需深入了解的概念)先去计算等号右边的表达式,$a + $b + $c,相当于100 + 100 + 200,即,最终结果为400;而后,把这个结果保存到$c中去,也就是说,在这一行代码结束之后,变量$c的值变了:不再是原来第3行结束之时的200,而是400了。
现在,你可以按一下F5查看一下结果了……
为了避免歧义与误解,我们最好称“=”为赋值符号。很多人嫌麻烦,“固执”地把“=”称为“等号”,而将来因此造成无数的麻烦以及相当不堪的后果……最可怜的是,当麻烦降临,后果不堪设想之时,他们全然不知根源竟然在这么个不起眼的地方。
AutoIt教程:
第三天. 循环
尽管我从不相信速成,但也知道有些事情必须速战速决。事实上,我一直在忽略一些(其实非常重要的)细节,带着读者向前向前向前……这并不是想要囫囵吞枣,而是为了尽快有个“概览”,而后再重新来过。反刍,也是学习的诀窍之一。
计算机的另外一个长项是“不厌其烦”,无论你让它做什么,只要
- 你要求的是它确实能做的(比如它不大可能每天定时煎两个荷包蛋给你);
- 你说得足够清楚(程序正确无误);
那么它就会百分百照做,并且绝不怕重复——你让它做多少遍它就做多少遍。
我们小时候都计算过1+2+3…+10等于55;并且那时候我们还学过所谓的“优化算法”,
1+10=11
2+9=11
3+8=11
4+7=11
5+6=11
所以,只需要算5×11等于多少就可以了。
有了编程能力之后,你可以无需任何“优化算法”[1],迅速得知1+2+3…+n等于多少,无论n是多少……
现在,请分别建立以下三个文件,输入相应的代码,分别执行,查看结果。
Testing6.au3
$r =0
For $i= 1To 256
$r= $r+ $i
Next
ConsoleWrite($r)
Testing7.au3
$r =0
$i =1
While $i<= 256
$r= $r+ $i
$i= $i+ 1
WEnd
ConsoleWrite($r)
Testing8.au3
$r =0
$i =1
Do
$r= $r+ $i
$i= $i+ 1
Until $i> 256
ConsoleWrite($r)
这三个程序的输出结果都是一样的,它们都在计算从1加到256的结果是多少:32896(=1+2+3…+256)。
先让我们看看Testing6.au3的代码。
- 第1行,变量$r被设置了一个“初始值”,0。
- 第2行至第4行,For…Next,是一个循环结构。在循环的过程中,变量$i的值从1开始依次递增,变为2、3、4…直至256为止。此后才会接着执行第5行代码。
- 第3行代码处于循环结构之中,
- 第一次执行的时候,$r = $r + 1(这次$i的值是1);所以,$r = 0 + 1,即,在这行代码执行过后,变量$r的值变成了1;
- 第二次执行的时候,$r = $r + 2(这次$i的值是2);所以,$r = 1 + 2,即,在这行代码执行过后,变量$r的值变成了3;
- 第二次执行的时候,$r = $r + 3(这次$i的值是3);所以,$r = 3 + 3,即,在这行代码执行过后,变量$r的值变成了6;
- 以此类推……
- 直至$i的值递增为256之时,之前的$r的值再次被加上256之后,循环至此结束
- 执行Next语句之后的代码,即第5行代码——输出结果,32896。
而Testing7.au3和Testing8.au3,只不过是用了另外两个循环结构而已:While…WEnd和Do… Until。这两个循环结构的语法更加接近自然语言,基本上就是“Plain English”,很容易看懂。
请认真思考为什么Testing7.au3中的表达式($i <= 256)用的是“<=”,而Testing8.au3中的表达式($i > 256)用的是“>”?
作业:
· 仔细阅读AutoIt帮助文件中Keyword/Statement Reference中的关于For…Next、While…WEnd、以及Do…Until的内容,把其中的每一个例子都尝试着运行一遍。在运行之前,请用脑演练一遍代码,看看执行结果是否与想象得相同……
· 写一个程序,计算“从1乘到某个特定的数字”的结果。
· 把上面的程序总共写成三个版本,分别用For…Next、While…WEnd、以及Do…Until的循环结构,完成同样的功能。
Footnotes:
- 这个例子中所需要的计算太简单,所以,“算法”上的优化没有太大作用。而在大型的软件工程中,算法优化非常重要,效果也异常惊人。不过,大多数普通用户的“任务”,往往用“笨方法”更划算……
AutoIt教程:
第四天. 输入与输出、判断与分支
学什么东西,往往并不需要脑袋聪明。可是需要“头皮很硬”──因为你总是需要“硬着头皮读/做下去……”
新建一个AutoIt文件,将其命名为Testing9.au3,输入以下代码:
$n =InputBox("Input","To what number do you want to add up?")
$r =0
For $i= 1To $n
$r= $r+ $i
Next
MsgBox(0, "Output", "The sum from 1to " & $n &" is " & $r)
请按F5查看执行结果。
先是跳出一个含有输入框的对话框,要求你输入一个数字,比如,1024:
而后跳出一个对话框,显示计算结果:
Testing9.au3看起来像是个真正的程序了,因为它包含了所谓程序的三个重要组成部分:
- 输入
- 处理
- 输出
所谓程序,就是一系列的操作说明──是你(作为程序的作者)用计算机能够理解的语言编写[1] 的。而后计算机去执行这些操作。在操作过程中,有可能需要你(作为程序的用户)提供一些数据(输入)以便进行进一步的操作(操作),也有可能为了满足你(作为程序的用户)的需求而向你提供一定的反馈(输出)。
将来无论你去学哪一种新的编程语言,记住:第一件事情是去搞清楚它的“输入/输出”的方式,因为你作为程序作者也好,作为程序用户也罢,必须与计算机“互动”。在此之前,我们一致“硬着头皮”用ConsoleWrite()这个函数,现在我们又有了一个看起来比较“现代”的输出方式──MsgBox()……
Input()和MsgBox()都是函数(一个你到目前为止还必须“不懂装懂”的概念)。你可以打开AutoIt帮助文件,去看看这两个函数的文档页面,看不懂没关系,但多看几遍,在没有任何人为你讲解的情况下,你都会渐渐明白更多。现在要知道的是这些(请控制一下自己的好奇心,暂时只要知道下面这些就够了,以后有的是机会回来弄透──也必须回来弄透……):
在第1行,等号右边的Input()这个函数,相当于一个表达式,它的结果就是你在输入框里所输入的内容;于是,这一行代码执行过后,你输入的是什么,变量$n的值就是什么。Input()里面有两个字符串,第一个是用来定义显示在对话框标题的(在这个程序中,我们将其定制为“Input”;当然,你可以随便改改试试看);第二个是用来定义对话框面板上的内容的(在这个程序里,“To what number do you want to add up to?”)。
在第6行,MsgBox()这个函数的执行结果是跳出一个对话框;括号里的第一个参数是“0”,它定义的是“对话框类型”,第二个参数“Output”,定义的是对话框的标题;而第三个参数,是一个表达式,把以下几个字符串合并起来,显示在对话框面板中:
"The sum from 1 to "
$n
" is "
$r
现在的问题在于,万一这个程序的用户不是你自己,他在输入框里输入的不是正整数怎么办?比如输入的是“ten”,或者,“-10”……你自己不妨反复试试看这些“非常规输入”。
至于最终结果为什么是“0”而不是别的什么,可以暂时不去理会──反正结果不是我们所预期的。
现在的问题是,作为程序作者的你,如何确保程序用户输入的是正确的数字呢?
让我们在第一行代码之后补上几行(Testing10.au3):
$n =InputBox("Input","To what number do you want to add upto?")
If NotStringIsDigit($n) Then
MsgBox(0, "Warning!", "You didn'tinput a valid number. Press OK to quit...")
Exit
EndIf
$r =0
For $i= 1To $n
$r= $r+ $i
Next
MsgBox(0, "Output", "The sum from 1to " & $n &" is " & $r)
第2行里的StringIsDigit()又是一个函数。如果作为参数传递给它的字符串全部由数字构成,那么这个函数将返回“True”这个逻辑值;否则的话,它就返回“False”这个逻辑值──暂时了解这些就够了,请你硬着头皮接着往下看……
第2行到第5行代码,是一个If…Then的“判断分支”语句,将其翻译成自然语言就是
如果$n不是数字的话,就显示对话框,提示用户“You didn’t input avalid number. Press OK to quit…”,而后退出程序
否则的话(即,如果$n是数字的话),就跳过Then…EndIf之间的代码,继续执行EndIf之后的代码……
可是,这样还是不令你满意,因为,你要的实际上是“如果用户输入的不是数字,那么就让他重新输入,直到用户输入正确数字,则为用户显示计算结果……”
注意这里的“直到……”,用编程语言表达的话,就是“用一个循环,直到某个条件满足跳出循环”。请阅读以下的代码(Testing11.au3):
Do
$n= InputBox("Input", "To what numberdo you want to add up to?")
IfNot StringIsDigit($n) Then MsgBox(0, "Warning!","You didn't input a valid number. Please tryagain...", 1)
Until StringIsDigit($n)
$r =0
For $i= 1To $n
$r= $r+ $i
Next
MsgBox(0, "Output", "The sum from 1to " & $n &" is " & $r)
至此为止,你已经看到了“循环”(Loop)和“分支”(Branch)的功用。许多年之后的今天,我还清楚地记得当年我学会这两个“简单”概念之时的震惊:本质上来看,所有程序的最重要部分就是这两个概念构成的──以后你会渐渐明白,绝大部分的计算/运算,最终是为了“分支”和“循环”服务而已;也就是说,用“循环”和“分支”可以做任何事情……从逻辑上把所有任务抽象为这么两个简单概念,真是美丽到了极致。
照例,我们又暂时忽略了许多重要的细节──我知到你的“强迫症”快要发作了──不过,我们还要硬着头皮往前走很久才行……
Footnotes:
- 在这里,当然是AutoIt v3。在你的计算机安装AutoIt v3之前,你的计算机是不可能理解.au3文件中的内容的……
AutoIt教程:
第五天. 函数
新的知识必然与过往的任何知识都不同,否则它就不“新”了。“类比思考”可以帮我们运用已有的知识对比着了解新的知识,然而很多的时候,要更多甚至全然关注于“不同”之处才行。另外,如果遇到的是“仅仅看起来像已知的某样东西而已,可实际上却全然不同的”新知识,那么“类比思考”就不适用了。而思考之时,“类比”无所不在,于是,控制它需要一些挣扎……
编程语言中的函数(Function)和数学里的函数(你肯定学过一些的)压根就不是一回事儿,它们只是“恰巧”名字相同而已。(这就好像“table”这个概念可以指两个完全没关系的概念一样──“桌子”和“表格”。看,我们又是用类比进行理解……只不过,这次没什么问题。)
在程序里,所谓函数,本质上来看就是一段有特定功能的代码。一个函数由以下几个部分构成:
- 函数名
- 参数
- 返回值
- 定义
- 调用
在这里停上三五分钟,把这五个要素牢牢记住──靠死记硬背,在你还不知道它们究竟指什么之前,就先把这几个名称牢牢记住。要做到有人问你“函数构成有几个部分?”的时候,你脱口而出这五个名称……然后再继续阅读下去。
新建一个AutoIt文件,将其命名为Testing12.au3,输入以下代码:
Func __AddUpTo($n)
$r= 0
For$i =1 To$n
$r = $r + $i
Next
Return$r
EndFunc
按F5执行,这段代码不输出任何结果。
这段代码只是定义了一个函数,定义函数的语法是:Func…EndFunc:
- 它的函数名为__AddUpTo()
- 调用这个函数时,需要提供一个参数
- 这个函数的返回值是(1+2+3…+n)的值
再补上两行,使其变成这个样子:
Func __AddUpTo($n)
$r= 0
For$i =1 To$n
$r = $r + $i
Next
Return$r
EndFunc
$result =__AddUpTo(100)
MsgBox(0, "Result", $result)
按F5查看结果:
当计算机阅读你的指示(即,你写的程序)之时,读到第一行,它看到Func,就知道你是在定义一个函数,它“理解”了,然后找到EndFun,看看后面有没有“可执行”的代码……
而后,它在第8行,读到了一个函数“调用”,即,你向__AddUpTo()这个函数传递了一个参数(100)。
它在当前文件中去寻找有没有这个函数的定义(当然有,在第1行定义的……),找到之后,开始执行__AddUpTo()这个函数区块中(Func … EndFunc)的内容……
此时,$n = 100,因为你刚刚在调用__AddUpTo()的时候,在括号里写了100,所以,在Func __AddUpTo($n)开始执行的时候,$n 被赋值为 100。
而后内部的运算,你都看得懂,最终的结果是变量$r的值为5050(1+2+3…+100)
然后,函数__AddUpTo()把根据传递进来的参数(100)计算出来的结果(5050)返回给第8行的代码,“$result = __AddUpTo(100)”,即,从此之后,变量$result的值就是5050。
再然后,第9行代码呼出一个对话框,显示结果……
现在,新建一个AutoIt文件,将其命名为Testing13.au3,输入以下代码:
Func __AddFromUpTo($a, $b)
$r= 0
For$i =$a To$b
$r = $r + $i
Next
Return$r
EndFunc
$result =__AddFromUpTo(101, 200)
MsgBox(0, "Result", $result)
这次我们定义的函数名称叫__AddFromUpTo(),它需要两个参数,返回值是从第一个参数加到第二个参数究竟等于多少:
现在,尝试一下,把Testing13.au3第9行的代码改为:
$result =__AddFromUpTo(200)
而后按F5执行,结果是跳出一个“出错提示”对话框:
这是因为当初定义__AddFromUpTo()就指明调用它的时候需要提供两个参数,而现在却只提供了一个参数,所以,计算机“糊涂”了,弄不明白你究竟想干什么……
新建一个AutoIt文件,将其命名为Testing14.au3,输入以下代码(不要按F5查看结果,而是先尝试着用脑演练一番,看看自己能不能想出正确结果……):
Func __AddFromUpTo($a=1, $b=100)
$r= 0
For$i =$a To$b
$r = $r + $i
Next
Return$r
EndFunc
$result =__AddFromUpTo()
MsgBox(0, "Result", $result)
$result =__AddFromUpTo(50)
MsgBox(0, "Result", $result)
$result =__AddFromUpTo(101,200)
MsgBox(0, "Result", $result)
这一次,我们在定义__AddFromUpTo()之时,为它的两个参数都提供了“默认值”,第一个参数默认是1,第二个参数默认是2。即,如果在调用这个函数的时候并未向其传递参数的话,那么就使用默认值进行运算(并返回相应的结果)。所以,
- 调用__AddFromUpTo(),相当于没有提供任何参数,所以它按默认值运算,返回的应该是(5050);
- 调用__AddFromUpTo(50),相当于向__AddFromUpTo()函数提供了第一个参数(50),而第二个参数由于未被提供,所以采用默认值(100),于是,这个函数调用所返回的应该是3825(50+51+52…100);
- 调用__AddFromUpTo(101,200),向该函数提供了它所需要的全部两个参数,所以,该函数内部的运算不使用任何默认值,而是计算从101加到200的结果,并返回(15050)。
现在按F5查看一下执行结果:
现在,再回顾一下我们刚刚遇到的一些概念:
- 函数名
- 参数、默认参数
- 返回值
- 定义
- 调用
作业:
重新去反复阅读若干遍ConsoleWrite()、InputBox()和MsgBox()这三个函数的帮助文档。
AutoIt教程:
第六天. 数组
变量(Variable)是用来保存一个数据的,数组(Array)是用来保存一系列数据的。比如,我们可以把一个班里所有人的名字保存到一个数组之中。事实上,你可以把数组理解为“最简单形式的数据库”,或者“只有一列数据的表单”。
Dim $name[5]
$name[0] = "Tom"
$name[1] = "Jerry"
$name[2] = "Mike"
$name[3] = "Joey"
$name[4] = "Jane"
注意,方括号内的“下标”,是zero-based,即,从零开始。所以,在第1行代码中我们定义了一个总计有5个元素的数组,名称是$name,第一个元素用$name[0]表示,最后一个元素用$name[4]表示。数组中的每一个元素,相当于一个变量,可以保存一个数据。
用一个循环语句,就可以遍历(逐一访问,或读,或存)所有元素:
For $i= 0To 4
MsgBox(0, $i, $name[$i], 1)
Next
数组的操作向来很麻烦。不过,幸运的是,AutoIt安装的过程中提供了很多UDF,即所谓的“用户自定义函数库”。UDF,是User Defined Function的首字母缩写。AutoIt是免费开源的软件,所以有很多人参与了开发过程,同时写了许多各式各样的,能够完成特定功能的函数。一旦你需要使用数组,最方便的方法就是直接调用一些UDF中的函数。
引用UDF函数库的方法是在程序开头添上这样一句:
#include <Array.au3>
之后,你就可以用_ArraySort()为某个数组排序,用_ArraySwap()为某两个元素调换位置,用_ArrayDisplay()显示一个数组内容,或者用_ArrayUnique()查询某个元素的值在整个数组中是否是唯一的……
UDF中关于数组管理的所有函数……
如果一个数组是“动态形成的”,或者,在程序运行过程中,数组增加或减少了一些元素,那么我们可以用UBound()函数得知某个特定数组的元素数量。
新建一个AutoIt文件,将其命名为Testing15.au3,输入以下代码,并按F5运行,查看结果:
#include <Array.au3>
Dim $name[5]
$name[0] = "Tom"
$name[1] = "Jerry"
$name[2] = "Mike"
$name[3] = "Joey"
$name[4] = "Jane"
For $i= 0To 4
MsgBox(0, $i, $name[$i], 1)
Next
_ArrayDisplay($name)
_ArrayAdd($name, "Mary")
_ArrayDisplay($name)
MsgBox(0, "Info", "Now the array$name has " & UBound($name) & "elements...")
_ArraySort($name)
_ArrayDisplay($name)
_ArrayReverse($name)
_ArrayDisplay($name)
注意:当_ArrayDisplay()显示对话框的时候,程序会暂停,知道你按关闭按钮关闭该对话框之后,程序将继续运行。
作业:
把所有UDF中的关于数组管理的函数都拿出来调用、试验一遍。与此同时,还要“硬着头皮”精读每个函数的帮助文档……
提示:调用每个函数之后,都可以调用_ArrayDisplay()来查看数组的内容变化……
第七天. 文件读写
用AutoIt可以很方便地读写文本文件。
新建一个AutoIt文件,将其命名为Testing16.au3,输入以下代码:
;Once I read in an article:
;
; Take a piece of paper, right now, and write out theword ATTITUDE.
; Now assign each letter the number that letter correspondsto and
; add those numbers up. Guess what, they add up to 100%.A=1, T=20,
; T=20, I=9, T=20, U=21, D=4, E=5 = 100%. Attitude iseverything folks.
; You can’t hide it; you can’t even deny it.;
; It’s who you are. It’s the outside of your inside.
;
;I thought, Oh! Really?
;Seconds later, I became suspicious of this claim...
;OK, let's find out the truth, since we have tools toutilize...
InetGet("http://www.kilgarriff.co.uk/BNClists/lemma.al", "lemma.al", 0)
$file =FileOpen("lemma.al",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
$lineElements= StringSplit($line, " ")
IfAddUpCharactersInWordAsNumber($lineElements[3]) == 100Then
ConsoleWrite($lineElements[3] & @CRLF)
EndIf
WEnd
FileClose($file)
MsgBox(0, "", "Finished!")
Func AddUpCharactersInWordAsNumber($word)
$wordLowerCase= StringLower($word)
$Characters= StringSplit($wordLowerCase, "")
$count= 0
For$i =1 To$Characters[0]
$count =$count +Asc($Characters[$i]) - 96
Next
Return$count
EndFunc
按F5查看一下运行结果。
再隔一篇文章,我才会详细解释这些代码──因为还有一些细节需要交代。
让我们先了解一下AutoIt是怎样进行文件读写的。请阅读一下以下代码:
$file =FileOpen("lemma.al",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
...
WEnd
FileClose($file)
查看帮助文档的话,它告诉你说,FileOpen()这个函数返回一个File “Handle”(翻译成中文,是一个不知所云的词组“文件句柄”)。实际上,还不如干脆把这一行代码完整翻译成自然语言:
$file =FileOpen("lemma.al",0)
相当于:
从此之后,我们就可以用变量$file指代那个以只读模式打开并保存于内存中的”lemma.al”文件。[1]
While后面的1是怎么回事儿?
帮助文件里,While…WEnd的示例是这么写的:
While
statements
...
WEnd
While后面接一个表达式,即,“当这个表达式为真之时,循环执行以下代码……”
事实上,对AutoIt来说,1也是一个表达式,这个表达式的运算结果就是1。AutoIt从设计初始,就被定义为“弱类型”语言,即,对数据类型的定义不严格(至于这句话究竟是什么意思,以后的文章中会详细解释)。于是,在AutoIt中,1和True是一回事(暂时别奇怪你为什么搞不清楚这句话的因果关系,反正记住1和True是一回事就行了)──都可以当作表达式,且它们的值是相同的。
所以,
While 1
...
WEnd
是个无限循环。While 1 … WEnd之间的代码会无穷无尽地重复执行下去,除非……
请注意这行代码:
If @error= -1 ThenExitLoop
在循环内部,每次执行
$line =FileReadLine($file)
的时候,FileReadLine()都从$file里读出一行内容,并保存到变量$line之中($line就成了一个字符串变量)……
FileReadLine()的帮助文档里写着:
Return Value
Success: Returns a line of text.
Special: Sets @error to -1 if end-of-file is reached.
也就是说,当读到文件结尾的时候,这个函数会把@error的值设置为-1。
这里有两个东西要解释:
- end-of-file,又常常被缩写为EOF。它是所有文本文件的末尾的一个用记事本打开看不到的字符(文本文件中用记事本打开看不到的字符有很多,比如换行符Carriage Return Line Feed……)。当FileReadLine()读到这个字符之时,它就“知道”文件已经全部读取完毕了。
- @error,是AutoIt内建的一个“宏”,它的初始值是0。你不妨新建一个AutoIt文件,输入一行代码:
ConsoleWrite(@error)
看看@error的初始值到底是什么……
所以,以下代码:
$file =FileOpen("lemma.al",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
ConsoleWrite($line)
WEnd
FileClose($file)
的意思是说:
- 以“读模式”打开lemma.al文件;
- 逐行读取lemma.al文件内容;
- 将每一行内容输出至控制台;
- 关闭lemmal.al文件。
作业:
1. Testing16.au3里用了好几个“陌生”的函数,请逐一去查阅相关文档。
2. 尝试理解每一行代码,并分析整个程序的运行流程。
Footnotes:
- FileOpen()的第二个参数是用来指定文件读取模式的,0为读模式,1为写模式……具体请参阅FileOpen()帮助文档。
AutoIt教程:
第八天. 阅读帮助文件
AutoIt实际上很强大,至少“足够强大”。除了它的内建函数相当丰富之外[1] ,还有大量的UDF,并且,在AutoIt论坛上时时刻刻都有人在不断地补充各种功用的新UDF。
尽管看起来很简单,这一节可能是最重要的内容。
先让我们拿MsgBox()这个函数作为讲解起点。打开MsgBox()这个函数的帮助文档,我们最先看到的是它的简要说明和参数定义:
MsgBox
Displays a simple message box with optional timeout.
MsgBox ( flag, "title","text" [, timeout [,hwnd]])
参数定义中的方括号(“[ ]”)的含义是,“该参数在函数定义中设定了默认值,所以,这个参数是可选参数”,即,可以不指定这个参数,如果不指定的话,则直接使用函数定义的默认值──而这个默认值究竟是什么,在接下来的文档中有详细的解释。
Parameters
flag | The flag indicates the type of message box and the possible button combinations. See remarks. |
title | The title of the message box. |
text | The text of the message box. |
timeout | [optional] Timeout in seconds. After the timeout has elapsed the message box will be automatically closed. The default is 0, which is no timeout. |
hwnd | [optional] The window handle to use as the parent for this dialog. |
读过文档之后,就会知道
MsgBox(4096, "Test", "This box hasno timeout limit", 0)
和
MsgBox(4096, "Test", "This box hasno timeout limit")
是一样的。
而“4096”究竟是什么意思,在接下来的文档中可以找到:
decimal flag | Button-related Result | hexadecimal flag |
4096 | System modal (dialog has an icon) | 0×1000 |
在使用MsgBox()的话,AutoIt用这个函数的返回值来判断用户究竟按下了对话框中的哪一个按钮,比如,如果用户按下的是“OK”(确定)按钮,那么返回值是1;如果按下的是“ABORT”(取消)按钮,则返回值是3;如果在Time Out的时间内没有任何动作,返回值是-1……
请尝试一下以下代码(Testing17.au3):
While 1
$n= MsgBox(3, 'MsgBox Demo', 'Please Press one ofthe buttons...')
Select
Case $n== 6
MsgBox(0, 'Info', 'You pressed "YES"',2)
Case $n== 7
MsgBox(0, 'Info', 'You pressed "NO"',2)
Case $n== 2
MsgBox(0, 'Info', 'You pressed "CANCEL", and quit the program...', 2)
ExitLoop
EndSelect
WEnd
注意:在AutoIt中,每个函数都是有“返回值”的──即便在定义的时候没有给出返回值,AutoIt也会自动返回一个0……
请尝试一下以下代码(Testing18.au3):
Func __DoNothing()
EndFunc
MsgBox(0, "", "Function__DoNothing() returns " &__DoNothing())
如果函数调用处于表达式之中,那么它的返回值讲参与表达式计算;如果函数只是被调用(比如,一行代码中只有一个MsgBox()函数)而已,那么它的返回值将被“扔掉”(Throw out)。
另外,调用UDF的时候,需要“引用”定义文件,语法是:#Include <Filename.au3>。之前我们已经见过具体的例子,比如想使用_ArrayDisplay这个函数的话,那么就得在程序开头加上#Include<Array.au3>。_ArrayDisplay的参数定义如下:
#Include
_ArrayDisplay(Const ByRef $avArray[, $sTitle= "Array:ListView Display" [, $iItemLimit =-1[, $iTranspose= 0[, $sSeparator= ""[, $sReplace= "|"[, $sHeader= ""]]]]]])
以后当你需要做什么事情的时候,
- 先去看看AutoIt帮助文档,看看有没有能够完成相应功能的函数
- 认真阅读该函数的帮助文档,以及其中的范例
- 将此函数把玩一阵,测试它的方方面面
- 将其应用到你的程序中去……
- 最后,如果你有兴趣的话,可以去阅读一下那些UDF的源码(都是公开的),学习它们的构建方法……
学会看帮助文档,就好像是学会查词典一样,是最基础,却又最重要的技能。听起来很荒唐,但确实有很多人学了一辈子英语却不懂如何查词典,于是一辈子有解决不完的问题,而又不知道症结究竟在哪里;同样的道理,有很多人学了很久的编程,却从来没有认真研究过如何查看文档,于是最终与那些学英语却不会查词典的人同一个下场,并且从不自知。
Wikipedia上有个很好的条目,建议所有人都去认真阅读一下:http://en.wikipedia.org/wiki/Rtfm
Footnotes:
- 以后你会知道,任何一种编程语言,真正强大的地方都在于它们各自的“函数库”(Library)……
AutoIt教程:
第九天. 问题、方案与实现
第7节里提到过的问题,实际上在《把时间当作朋友》一书中出现过,作为反驳“成功学谬误”的例子:
除了“以偏概全”、“单向成立”之外,“成功学”书籍里甚至不乏赤裸裸的、厚颜无耻逻辑混乱。最令我印象深刻的赤裸裸地逻辑混乱的“成功学”例子是关于“态度改变一切”的一个例子。我知道,也相信“有些时候,仅仅态度上的改变就真的可以带来不同的结果”。然而,我认为用以下的逻辑让我接受,或者让任何人接受,都不仅是不可能的,甚至是不道德的。
如果将字母 A 到 Z 分别编上 1 到 26 的分数,(A=1,B=2…,Z=26) ,那么:
· 你的知识(KNOWLEDGE)得到 96 分(11+14+15+23+12+5+4+7+5=96)
· 你的努力(HARDWORK)也只得到 98 分(8+1+18+4+23+15+18+11=98)
· 你的态度(ATTITUDE)才是左右你生命的全部,因为1+20+20+9+20+21+4+5=100
拜托,有点基础逻辑好不好呢?事实上,用这种方法计算,结果等于100的单词多的去了:
alienation (疏远)
apoplectic (中风患者)
boycott (联合抵制)
cacophony (杂音、刺耳的音调)
chimpanzee (黑猩猩)
connivance (纵容)
coyness (羞怯)
flurry (慌张)
frisson (颤抖)
impotence (阳痿)
inflation (通货膨胀)
pussy (小猫<俚>女阴/阴户)
socialism (社会主义)
status (身份、地位)
stress (压力)
surcharge (超载, 追加罚款, 额外费)
syndicate (财团)
tuppence (微不足道的东西)
turkey (火鸡,无用的东西)
Wednesday (星期三)
wholesale (批发)
以上罗列的只是我在BNC英文词汇表中找到的一千多个中的一小部分名词而已。对了,形容词useless如果按照这种算法,结果也等于100。补记:刚刚写完,顺手在GOOGLE上搜索了一下 “KNOWLEDGE 11+14+15+23+12+5+4+7+5=96″。得到的结果特别值得回味:前150项几乎都来自中文网站。搜索结果的第16页才开始陆续有一些英文网站提到这个莫名其妙的算法,在GOOGLE搜索结果的第151项 看到这么一篇:指出 bullshit = 103,于是接着说,“So, it stands to reasonthat hard work and knowledge will get you close, attitude will get you there,but bullshit will put you over the top.” 还有更逗的,作者又接着指出另外一个词:asskissing=127 !
当时我就想,要是有很多莫名其妙的词按这种算法加起来也等于100呢?我猜肯定有的!只不过,用手工计算是(几乎)不可能的事情。还好,我有工具[1] 和技能,所以,就可以去验证,而后“精彩而又直接地”驳斥这种荒谬的说法。
有些时候我们非常依赖工具和技能。在心存狐疑之时,拥有工具掌握技能的人,可以去验证;而没有工具没有技能的人,只能“心有余力不足”。事实上,大多数“力不足”的人“心并无余”,他们甚至不会“心存狐疑”,而是直接“被震惊”、“被惊喜”,“被打动”……直接被这种说法带到坑里去了……
问题是:“有哪些词按这种算法也等于100?”──而解决方案倒也简单:
- 找一个词表(如有必要,就把它转换为文本文件,便于程序阅读)
- 逐一计算
- 把那些按这种算法计算等于100的词挑出来
刚开始的时候,其实没必要一定要先去找个词表,我只新建了名称为一个“wordlist.txt”的文件,其中只有以下几行内容:
Hardwork
Attitude
Knowledge
Success
Anything
而后我们就可以写这样的代码处理这个文本文件中的每一行:
$file =FileOpen("wordlist.txt",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
;test if sum of character values in this word equals to 100, if so, print it tothe output...
WEnd
FileClose($file)
注意,在AutoIt代码中,分号“;”后面的内容是“注释”,是给代码阅读者看的,AutoIt在执行代码的时候,忽略一切“;”和它后面的内容。注释的写法有若干种,请参阅帮助文档。
现在的问题是,如何才能计算出一个单词按这种算法等于多少呢?我到AutoIt的帮助文件里翻了翻与字符串(String)相关的函数,看看有没有能够用得上的……当然有,我找到了个StringSplit()。它会把一个字符串按照指定的“分隔符”拆分成若干段,而后把这些拆分后的片段按顺序保存在一个数组之中返回……如果分隔符是空字符(即,“”),那么它就把一个字符串拆分成一个字母一个片段……就是它了!
大致看了一下帮助文档,而后写了个代码片段测试这个函数:
#Include
_ArrayDisplay(StringSplit("Success", ""))
结果竟然出错了……仔细看了看出错提示,才发现_ArrayDisplay()这个函数第一个参数标明了是ByRef的,即,只接受变量作为参数,不接受表达式或函数调用。所以,改了改测试代码:
#Include
$a =StringSplit("Success","")
_ArrayDisplay($a)
运行结果如下:
看懂了,原来StringSplit()返回的是一个这样的数组:$a[0]之中保存的是“分割后片段的个数”(即,Success这个字符串总计7个字母),而后的元素则为每一个字母……
现在的问题是,如何让a=1,b=2… c=26呢?
在AutoIt帮助文件的Variables and Conversion章节中,找到一个函数Asc()。这个函数返回一个字符对应的ASCII代码。例如:
Asc(“0″) == 48, Asc(“9″) == 57, Asc(“A”) == 65, Asc(“Z”) == 90, Asc(“a”)== 97, Asc(“z”) == 122
所以,Asc(“a”) == 97 、 Asc(“b”) == 98 … 于是,只要用这个函数的返回值再减去96就可以得到1、2、…26这些数值了。不过,还有个问题,大小写字母的值不一样,Asc(“A”) == 65,而Asc(“a”) == 97……再去看看跟String相关的函数,找到一个StringLower()──我们可以先用它把一个词中的字符全部转换为小写,而后再进行计算……
现在我们可以写出(或起码能够完全理解)以下的代码了:
$file =FileOpen("wordlist.txt",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
;test if sum of character values in this word equals to 100, if so, print it tothe output...
$wordLowerCase= StringLower($line)
$Characters= StringSplit($wordLowerCase, "")
$sum= 0
For$i =1 To$characters[0]
$sum = $sum + Asc($characters[$i]) - 96
Next
MsgBox(0, $line, $sum)
WEnd
仔细看看,就会发现“计算总和”的过程是可以被独立出来的,那还不如把它写成一个函数,将来可以随意调用呢:
$file =FileOpen("wordlist.txt",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
;test if sum of character values in this word equals to 100, if so, print it tothe output...
$sum= AddUpCharactersInWordAsNumber($line)
MsgBox(0, $line, $sum)
WEnd
Func AddUpCharactersInWordAsNumber($word)
$wordLowerCase= StringLower($word)
$Characters= StringSplit($wordLowerCase, "")
$count= 0
For$i =1 To$Characters[0]
$count =$count +Asc($Characters[$i]) - 96
Next
Return$count
EndFunc
如此这般之后,我们可以去找一个很全的英文词汇表去测试了。我到网上Google了一下“BNC Frequency Word List”,很快在kilgarriff.co.uk这个网站上找到一个词汇表,“lemma.al”。网站上有这个词表的格式说明:
The format for the list is:
sort-order,frequency, word, word-class
and a sample from the top of the alphabetically-ordered list is:
5 2186369 a det
2107 4249abandon v
5204 1110abbey n
966 10468ability n
321 30454able a
这个比较好办,就用我们刚刚用过的StringSplit()函数,用一个空格(” “)作为分隔符,就能把每一行中的“word”提取出来,然后在调用我们刚写过的AddUpCharactersInWordAsNumber()函数就可以算出数值……
然后,程序就变成了这个样子:
InetGet("http://www.kilgarriff.co.uk/BNClists/lemma.al", "lemma.al", 0)
$file =FileOpen("lemma.al",0)
While 1
$line= FileReadLine($file)
If@error =-1Then ExitLoop
$lineElements= StringSplit($line, " ")
IfAddUpCharactersInWordAsNumber($lineElements[3]) == 100Then
ConsoleWrite($lineElements[3] & @CRLF)
EndIf
WEnd
FileClose($file)
MsgBox(0, "", "Finished!")
Func AddUpCharactersInWordAsNumber($word)
$wordLowerCase= StringLower($word)
$Characters= StringSplit($wordLowerCase, "")
$count= 0
For$i =1 To$Characters[0]
$count =$count +Asc($Characters[$i]) - 96
Next
Return$count
EndFunc
如果你想把结果都写到一个文本文件之中,可以把第9行的
ConsoleWrite($lineElements[3] &@CRLF)
改成
FileWriteLine("result.txt", $lineElements[3])
而FileWriteLine()这个函数的用法,当然要参见帮助文档。
作业:
· 把程序里的StringLower()函数换成StringUpper(),并修改其它相应的部分,使其得出正常结果。
· 这里有个更长的词表:http://www.kilgarriff.co.uk/BNClists/all.al.gz,下载后解压缩,看看这个词表中有哪些词按这种算法等于100?
· 这里还有一个词表:http://www.bckelk.ukfsn.org/words/wlist.zip,下载后解压缩,看看这个词表中有哪些词按这种算法等于100?
· 回顾一下之前的所有文章,确保每一行代码都读得懂……
Footnotes:
- 当时我用的是Python,现在是在讲解AutoIt,所以当然得用AutoIt重写一遍。
AutoIt教程:
第十天. 模拟键盘鼠标操作
AutoIt的独特之处之一在于它可以非常方便地模拟Windows上的键盘鼠标操作,进而“自动”、“批量”地完成一些复杂而又重复的操作。
想象一下:
你有一个词表,你想把它的所有单词在Collins COUBILD中的释义文本拷贝出来。
那么,你原本只能这样:
打开词表文本文件;
新建一个文本文档(如果想要保留格式的话,就要新建一个rtf文件──用“写字板”程序,而非“记事本”)
打开Collins词典(Collins COBUILDDictionary On CDROM)
从词表文件中Control+C拷贝出一个词
切换到Collins词典,将刚刚拷贝的词粘贴到输入框中,而后按回车键
再从菜单中选择Edit,再选择Copy Entry
切换到写字板程序,按Control+V粘贴
…
周而复始,直至所有词汇全部处理完毕……
也许过去你就是这么做的。可是,现在你可以像这段录像所演示的那样:RetriveEntryTextFromCollins(或者你可以在这个链接上点击鼠标右键,选择“另存为……”将其下载到本地查看。)
程序的代码很简单(点击这个链接下载这个代码和它所用到的词表文件;另,你的电脑上应该已经安装好Collins COBUILD Dictionary On CDROM;还有,在执行这个程序之前,你得先打开一个写字板程序、打开Collins词典……):
$file = FileOpen("WordList.txt")
While 1
$line = FileReadLine($file)
If @error = -1 Then ExitLoop
CopyEntryFromCollinsToWordPad($line, "Document - WordPad")
WEnd
Func CopyEntryFromCollinsToWordPad($Entry, $WordPadTitle = "文档 - 写字板", $CollinsTitle = "Collins COBUILD - Lexicon")
ControlSend($CollinsTitle, "", "Edit2", $Entry & "{Enter}", 0)
WinWait($CollinsTitle,"")
If Not WinActive($CollinsTitle,"") Then WinActivate($CollinsTitle,"")
WinWaitActive($CollinsTitle,"")
Send("{ALTDOWN}{ALTUP}ee")
WinWait($WordPadTitle,"")
If Not WinActive($WordPadTitle,"") Then WinActivate($WordPadTitle,"")
WinWaitActive($WordPadTitle,"")
Send("{CTRLDOWN}v{CTRLUP}")
Send("{Enter}")
Send("================================")
Send("{Enter}")
EndFunc
; Finished!
MsgBox(0, "AutoIt Message", "Finished!")
试用过后,请打开AutoIt帮助文件,细读这段代码中所用到的所有函数帮助文档。
另,AutoIt有一个“AutoIt Windows Info”程序(在开始菜单中可以找到),是用来获得Windows窗口信息的,调用出来把玩一下:
AutoIt教程:
第十一天. 什么叫“为所欲为”
相信我,总有一天,你会被一些程序惹恼。
金山词霸的生词本就是这么个程序,尽管它也确实很有用。
这个程序窗口上的所有按钮都没有快捷键!也就是说,如果你想编辑哪一个条目的话,就能用鼠标操作,先选中要编辑的条目,而后用鼠标点击“编辑”按钮,然后在跳出的窗口中操作键盘,再然后你的手要离开键盘,拿起鼠标,继续以后的操作……(这种程序一看就是“员工按最小工作量完成老板交代的工作”的结果,本质上它根本就不是写给用户的。)
不过,如果你会用AutoIt的话,那么,你就不仅不会因此生气,还可能会因此高兴──因为你很快就可以解决问题,而与此同时,你知道生气无奈的是别人,并且大有人在……
If NotProcessExists("NewWord2008.exe")Then Run("C:\ProgramFiles\Kingsoft\PowerWord_Oxford\NewWord2008.exe")
HotKeySet("!a", "AddButtonClick")
HotKeySet("!e", "EditButtonClick")
HotKeySet("!d", "DeleteButtonClick")
HotKeySet("!s", "SaveButtonClick")
While 1
IfNot ProcessExists("NewWord2008.exe") Then ExitLoop
Sleep(100)
WEnd
Func AddButtonClick()
ControlClick("生词本", "", "Button9")
EndFunc
Func EditButtonClick()
ControlClick("生词本", "", "Button10")
EndFunc
Func DeleteButtonClick()
ControlClick("生词本", "", "Button11")
EndFunc
Func SaveButtonClick()
ControlClick("生词本", "", "Button12")
EndFunc
以后你就可以用这个程序启动金山词霸的生词本,而后可以用以下快捷键控制程序:
- Alt+A: 添加
- Alt+E: 编辑
- Alt+D: 删除
- Alt+S: 保存
尽管程序简单,但理解起来还是比较绕的;请逐一查询陌生函数的帮助文档。