事件处理器(Handler)是AppleScript的专有名词,可以理解为其他程序语言中得函数(Function,如:C语言)、方法(Method,如:Java)或者是子程序(Subroutines)。 简单来说,事件处理器在AppleScript中的价值就是减少大段类似代码,提高代码可复用性。 可以借用事件处理器来编写超酷的“Drag & Drop App”以及“文件夹脚本”。
基本的事件处理器
事件处理器是一段代码的集合,通过呼叫它的名称(即“调用”)来执行其中的具体代码。 事件处理器如果没有被调用,那么其中的代码将永远不可能被执行。最基本的事件处理器定义和调用过程,如下:
on HelloWorld() --定义开始
display dialog "Hello,world" --事件处理器中具体要执行的代码
end HelloWorld --定义结束
HelloWorld() --调用
其中: HelloWord 是这个事件处理器的名称,请特别留心名称后面的括号,正式这对括号,才把变量名称和事件处理器名称区分开来。
又一个非常重要的问题需要强调:任何事件处理器无法在Tell语句块内直接被调用,如果确实需要调用,应该使用HelloWorld() of me。请记住“of me”
带参数的事件处理器
所谓事件处理器,应当是智能的---它应可以根据不同的场景根据同样的规则做出不同的响应。 我们可以通过“参数”把场景告诉事件处理器。 AppleScript提供了两种参数格式,位置参数(Positional Parameters)和 标签参数(Labeled Parameters)。
位置参数: 是和其他语言类似的常规参数格式。
标签参数: 是为了体现AppleScript贴近生活语言而设计的。 不过,如果没有处理好,标签参数将会非常的悲剧。因此建议:少使用标签参数。
位置参数根据参数出现的前后顺序来区分。 要使用位置参数,应当将变量名称(不应和现有名称重复,应该取一个新名称,仅供事件处理器内部使用,体现“局部变量”的概念)置于括号内。至于参数个数没有限制,多个参数以逗号分隔。如:
on Hello(somebody,howLong) --定义开始
display dialog somebody giving up after howLong
--该对话框将在指定时间后自动消失
end Hello --定义结束
Hello("Apple",2)
Hello("Microsoft",1)
Hello("User",3)
上面的代码以somebody和t作为参数传递给名为“Hello”的事件处理器。 对于有参数的事件处理器,调用时必须给出设定数量参数。**不同于严谨的高级语言,AS中得参数不需要指出参数类型,直接写变量名称即可。
标签参数对于英语好的人非常有帮助,因为它让代码看起来就像是日常对话。 此外使用标签参数可以不按照参数本来的顺序,即使颠倒顺序,AS也能正确运行。实现与上面位置参数示例相同功能,标签参数如下:
on Hello to somebody for howLong --定义开始
display dialog somebody giving up after howLong
end Hello --定义结束
Hello to "Apple" for 2 --调用
Hello for 1 to "Microsoft" --颠倒顺序也可以正确执行
Hello to "User" for 3
AppleScript允许使用很多介词来“有意义”地区分各个参数。包括about,above,against,apart from,around,aside from,at,below,beneath,beside,between,by,for,from,given,instead of,into,on,onto,out of,over,since,thru(or through),under等。 但是,每个介词只能出现一次。
返回值
事件处理器不仅可以处理,也可以告诉你它做了什么。 和其他编程语言类似,AS也使用return关键字。
on add(x,y)
set answer to (x + y)
return answer
end add
display dialog add(1,2) --获取add处理器的返回值
不仅可以return一个变量(代码:return aVarName),也可以单独使用return来结束事件处理器运行。
run和open事件处理器
AS为脚本应用程序(Script Application)提供了一些特殊的事件处理器。 包括run,open,quit和idle。使用起来和自定义的事件处理器一样,“on run”和“end run”。请注意:如果直接运行脚本,它们通常不会正常工作,只有将脚本保存为“应用程序”后,它们才能够正确运行。
run
run是一个默认的事件处理器,它是脚本运行的入口,任何不在其他事件处理器里的代码都隶属于run事件处理器。 通常我们不需要、也没有必要显式声明run事件处理器。 请记住:如果你显式声明了run,那么不能有任何代码位于事件处理器外,即所有代码必须位于你的事件处理器中或者是run事件处理器中。
open
open对于AppleScript开发者来说是非常有用的,它可以实现超酷的“Drag & Drop App”(使用拖放实现某些功能的程序),它仅仅对于保存为“应用程序”的脚本有效。
open其实是一个Max OS的系统命令,一旦用户在Finder中把文件或文件夹拖放到某程序或脚本的图标上,它就立刻收到open这个系统命令,如果你得AppleScript脚本中包含了open事件处理器,那么它将会处理这个情况。
open事件处理器可以、通常也一定会添加参数(标签参数),如“on open aFile”,aFile是参数,告诉脚本什么东西被拖放到了它的图标上。
下面实例代码的功能是:*如果用户将文件或者文件夹,拖放到脚本程序图标上,脚本会打开“文本编辑”(TextEdit)软件,并列出所拖放的文件的完整路径列表:
on open names
set pathNamesString to "" --首先设定一个空的文本
repeat with i in names
--在这个循环中,处理了每个被拖放到程序图标上的文件
--所做的工作就是记录下文件路径并加上回车,添加到本来的文本中
set iPath to (i as text)
set pathNamesString to pathNamesString & iPath & return
end repeat
--将记录下来的文件路径列表写入到文件
tell application "TextEdit"
set paragraph 1 of front document to pathNamesString
end tell
return
end open
再次强调:为了让脚本按照预想地工作,必须将它保存为“应用程序”,然后把文件拖放到该图标上。留意一下它的图标,看起来和一般的脚本没什么区别,但是它有个小箭头! 显示它是一个很牛的“Drag & Drop App”
保持打开的脚本应用程序
要实现本节的功能,请确保将脚本存储为应用程序,并勾选“保持打开”,如下图。 
为实现脚本“保持打开”,我们经常用到两个预设事件处理器:idle 和 quit。
idle
这个事件处理器用于处理应用程序空闲时的后台任务,它具有循环的功能,只要不退出或者有其他任务,它就会隔一段时间自动执行其中的代码一次。其默认时间间隔是30秒,我们可以通过“return n”命令来控制时间间隔,如“return 10” ,告诉AppleScript每隔10秒执行一次Idle中的任务。
quit
它用于处理用户手动退出保持运行的程序时要执行的任务。 其中,必须包含有“continue quit”命令,否则程序将不可能正常退出。 也就是说,即使触发了quit事件处理器,该保持打开的应用程序也不一定会退出。 应用程序将在执行“continue quit”命令时退出。
关于保持打开的脚本应用程序,示例如下:
on idle
beep 2 --蜂鸣两声
display dialog "程序正在运行" giving up after 1
return 5 --设定每隔5秒执行一次
end idle
on quit
display dialog "真的要退出?" buttons {"是的","不"} --询问是否退出
if button returned of result = "是的" then
continue quit --只有这个命令才会让它真正退出
end if
end quit
再次提示:如果直接从AppleScript编辑器中运行,将看不到结果,请保存后双击该程序运行。
文件夹操作
Finder右键菜单中得“文件夹操作”(Folder Action)命令,当文件或文件夹发生更改时,“文件夹操作”就会被激活。 这里的“文件夹操作”其实就是AS脚本,它们存储在“资源库\Scripts\Folder Action Scripts\”(或者用户资源库下相应的)文件夹中。 需要在相应文件夹的右键菜单中激活文件夹操作。
关于编写自己的文件夹操作脚本,我们可以在AppleScript字典Standard Addition-Fold Actions中找到,里面有5个命令,通过事件处理器的方式,我们可以编辑对应命令。 这5个命令都有很多参数可选,示例:
on adding folder items to theFolder after receiving theItemList
--发现文件夹添加文件就弹出对话框,显示有几个文件添加了
display dialog ((count theItemList) & "个项目被添加到了该文件夹")
as text buttons {"好","立即查看"}
--选择立即查看则打开文件夹
if button returned of result = "立即查看" then
tel application "Finder"
open theFolder
end tell
end if
end adding folder items to
要使用这个脚本,首先需要将脚本保存到上文所述的指定位置,然后右击想要执行操作的文件夹,选择“文件夹操作设置”,按照屏幕提示选择你所编写的脚本。
文件夹操作的缺点是运行速度较慢,好处是不影响系统使用。可以编写一个脚本来监视重要的文件夹,将各种操作写入到文件,而用户全然不知有个脚本正在记录一举一动。