从AutoHotkey启动程序说起


  陈轶自定义的系统快捷键是使用AutoHotkey的典型好例子。所谓“典型”,是指所用功能系AutoHotkey最基本、最常用者。所谓“好”,是指他总结出了自己的原则,比如“设置快捷键的时候,我首先考虑的是不会其他软件冲突……,所以最后使用的全局快捷键全部和Win键有关,原因是程序很少会把这个键关联到热键上去。” 要有自己的软件应用原则,这一点非常重要。因为,功能再多,也只属于软件;属于用户的,只有“应用”;而在纷繁的软件、千变万化的应用中,唯有“原则”才能让你不迷失于物、把握方向、不断前进。打个比方,没有提升出自己的原则,用过再多软件,也只是相当于读了中国的小学,又读美国的小学,再读法国的小学……;而提升出原则,则相当于从小学,进入中学。
  陈轶提及的快捷键,都是属于“快速启动某款程序”。我就此先做总结,后做扩展,并稍做评论,欢迎大家补充。

一、快速启动程序的另一个总结

  关于快速启动程序和文档,曾有一次未定稿总结,在理论篇提出了明确“需求、偏好、可承受成本”,是选择软件与方法的标准。在实践篇,把相关软件分了三类——但这种分类仍不够清晰,混杂了“通用vs专用”、“渐进vs终极”两个维度。现稍做补充。
  解决任何问题和需求,其方案可分为两类:专用方案、通用方案。比如,“如何批量转换图片”,走专用方案路线,就是搜索 batch image convert ;走通用路线,就是研究主流的图片类软件(如IrfanView、XnView),是否有此功能。相较而言,前者是“专家”或“秘方”;而后者是“大师”。当然,软件功能过多而体积庞大、且每一功能并不精深的情况,也是有的。但是,亦有一些绝顶软件,如TC、IrfanView,既博且深,深入掌握它们之后,对专用软件的需求会大幅度下降。一精胜十庸,一将能挡百万兵。
  所以,我多数情况下选择通用方法,这样所用软件数量虽少,但所能者多。
  回到快速启动,第一等通用方式就是利用操作系统的功能,比如win+r方式、批处理、vbs脚本。
  第二等通用方式,就是借助第三方更强大的脚本工具,比如AutoHotkey或AutoIt。
  专用方式当然就是专门的快速启动类软件,从略。
  实际上,还有一种“变通方式”,所谓至高境界,一花一叶皆可伤人,以刀行剑意,即是此理。比如,也可用Everything这样的搜索工具实现快速启动。

二、AutoHotkey启动程序的不同方法

  如果说AutoHotkey快速启动程序的应用中, #n:: run notepad 算是最基本、最实用的入门招式,则其变化、提升、进阶招式如下。

1. 从简单执行到区分场景

  #n:: run notepad 算是一键一招,无变化。而如下的代码,则是“一键多招,区分场景”。

  例1:win+t,打开TC:未启动则启动之,未激活则激活之,已正常则最小化。

#t::
DetectHiddenWindows, on
IfWinNotExist ahk_class TTOTAL_CMD
Run d:\Program Files\tc\TOTALCMD.EXE
Else
IfWinNotActive ahk_class TTOTAL_CMD
WinActivate
Else
WinMinimize
Return

  例2:我工作中要在不同系统中,为不同业务进行在线审批。按下win+a(agree),分别自动执行某些操作。

#a::
IfWinActive, cnooc/process
{……当在此类审批窗口时,按下win a(agree)表示同意后,自动执行的审批操作}
IfWinActive, Lotus Notes
{……当在Notes审批窗口时,按下win a(agree)表示同意后,自动执行的审批操作}
IfWinActive, bank
{……当在银行主数据类审批窗口时,按下win a(agree)表示同意后,自动执行的审批操作}

  再举一例,如下代码将ctrl-p在TC中定义上↑方向键,而在其他程序中不做定义。

^p::
IfWinActive Total Commander
send, {up}
else
sendplay, ^p
return

2. 从狭义的快捷键到广义快捷键

  一般人只把ctrl+s、F12这样的的键当作快捷键,这只是很狭义的理解。
  在IrfanView中,保存不是ctrl+s,而是s;在Vim中,复制是y,删除是d,粘贴是p——这是更快捷的快捷键。
  在MS Word中,alt-v-d 是显示文档结构图,alt-t-w 是统计字数;在桌面上,右键-r是属性——这些菜单、鼠标、键盘的组合使用,也是快捷键。
  回到AutoHotkey中,为了解决“狭义快捷键”不够用的情况,除了把一个键分场景映射之外,还有两大方法。

2.1 热字符串 (hotstring)

::znp::
run notepad
returnn

  这样,在大多数程序 [1]中,无论有无输入框,只要按下 znp 再加一个结束符(空格、回车等),即可执行记事本。其优点是全普通键盘操作,字符串无字数限制,便于记忆。更多参见AutoHotkey帮助文档。

2.2 普通键也可以组合

  所谓的组合键,仿佛汉字的形声字。比如ctrl+s,ctrl就是辅助键(或称为修饰键、特殊键、前辍键),s算是主键。但在AutoHotkey这种自由精神的倡导者眼中,辅助键不仅是 ctrl, alt, win, shift,其他键也可以担任辅助键!
  如果你认为传统意义的热键不够,推荐把z键再做为辅助键(基于位置、应用频度考虑)。这样,你可以实现 z+n 打开记事本……等功能了。

z & a::MsgBox You pressed z and a.
z & n::run notepad
z::send z
+z::send Z

  圣人者,方而不割。君子者,望之俨然,即之也温。AutoHotkey者,入门易而妙用无穷,在用户与windows程序之间飞舞往返,行天使之善,精灵之魔力。(完)

附:注释

  [1]: AutoHotkey的hot string在大多数情况下都能高优先级生效。但当另一些程序对键盘的优先级也很高、并且hotstring的字母在接受范围之内时,可能会引起失效或部分失效。例如:Total Commander 7.50a中,设定了任意字母直接激活快速搜索,上例(znp)中键入首字母z时,TC捕获并显示快速搜索框,继续输入np和结束符,并不能达到预期目的。再如,Lotus Notes的邮件列表中,也把键盘输入视为快速搜索。解决方法:①了解到原因是更高优先级的程序吃掉了第一个字符后,就可以先任输一字符让TC/Notes吃掉,再输入znp。这样就可以了。方法②,利用输入法的更高优先级,来屏蔽这类程序。比如在TC中激活输入法,再输入znp结束符,也能生效。
  [2]: 另外,hotstring通常用来解决缩写问题。有网友问:“我的ahk中有一个 ::chi::chinese 的hotstring ,在gvim中, 用 i 进入插入模式,这时候直接使用该hotstring的话,没有效果。非得在前面先输个标点符号(字母不行),比如 逗号 顿号 斜杠 什么的,hotstring才能正确响应” 答复如下: 默认情况下,需要键入 <分割符>chi<分割符> 才能触发, 你认为“已经输入了chi”,只是从自己和vim的立场。而在AutoHotkey看来,是分别是给出了ichi ixchi 的string,所以不触发chi的命令。 你可以修改hotstring或改变自己的键入。 或者,AutoHotkey也支持参数,来忽略前后的分割符,摘录略……,详见帮助。


《“从AutoHotkey启动程序说起”》 有 41 条评论

      • gui的代码简单举例:
        ---------------
        lalt & q::
        gui,destroy
        Gui, Add, Button, x185 y16 w80 h20 , cclean
        gui,show,,我的工具箱
        return

        buttoncclean:
        run,tool.alonetool.ccleanerCCleaner.exe
        gui,cancel
        return
        ————-
        x185 y16表示按钮坐标
        w80 h20表示按钮高度和宽度
        可以用smartgui制作gui框架,这样就能很好的控制上面的两个要素
        tool.alone文件夹放在autohotkey根目录下

  1. 非常感谢, 收益匪浅.
    当初就是通过善用佳软 认识了ahk, 到现在已经离不开ahk和我的那些热键了, 用别人的电脑都有些别扭了.
    顺便想请教下, ahk能不能实现如下功能:
    当scroll lock键盘灯亮时, ahk脚本中的热键有效, 反之ahk热键无效, 或ahk程序处于suspend状态.

    我在帮助文档中找了半天, 也没有合适的指令, 都是’ifwinactive’之类的,用某个程序的开启来控制脚本是否运行, 而没有用键盘的某个键来控制脚本是否运行的.

    在此先谢过了.

  2. 从这篇里又学到了不少。
    ahk是唯一一个被我设置随win启动的软件,然后再用快捷键打开需要的程序,感觉很方便。
    计时器功能也常用,其他的还没怎么研究。><

  3. 快捷键的组合其实还可以扩展更多。
    要点是加入“模式“,可以复用快捷键,比如:
    在标题栏上点中键,最小化窗口
    在explorer的空白处点中键,后退
    当鼠标移动到屏幕边缘点中键,显示桌面
    三种模式下都用中键,定义的功能可以不同。也就是说无形中把快捷键的定义能力扩大了3倍。

    带模式的快捷键定义,可以用ahk写脚本(复杂一些),也可以用powerpro定义(有图形化界面,不过软件本身也相当复杂)。

    快捷键定义方式虽然多,但并不是所有软件都能适用。

    举例说明下,xbeta中的单字母快捷键,兼容性就不能做到完美。因为在使用快捷键之前输入过中文。再使用单字母快捷键就必须手动切换输入法到英文,这样反而降低了效率。
    兼容性最好的还是ctrl,alt,shift加字母组合的快捷键。这也是很多软件为了兼容,没定义特别功能快捷键的原因。

    个人感觉,更强大和通用的快捷键模式,应该是menu式的。可以用user menu的方式来放置用户自定义的功能。具体方案可以参照tc的hot menu。
    比如ctrl+d呼出菜单,用单字母选择自己想要的功能。
    也就是说自定义的快捷键都可以用ctrl+d,xxx的字母序列各出,优点如下:
    1. 兼容性完美。只需要设定调用菜单的一个快捷键而已。其他功能都在菜单里完成,和其他软件快捷键不冲突。
    2. 定义的功能数量多,如果用3个字母,可以定义26×26×26种功能,足够了……
    3. 可以看到文字提示,更直观的学习快捷键。
    其实我说的这种快捷键方式,就是用alt+字母访问菜单功能快捷键的扩展,需要自己定义菜单。可以使用强大的autohotkey来自己做出菜单!

  4. 研究过AHK,也用过win+r
    不过现在都把常用的快捷方式都放到开始菜单中了,键盘近的话就先win键,在摁快捷方式的首字母选择;鼠标键的话,就直接点了
    个人感觉多那么一步两步的操作其实对效率的影响并没有多大,反之,简介直观,方便易用才是最重要的

  5. 错字太多,修改一下:
    研究过AHK,也用过win+r
    不过现在把常用的快捷方式都放到开始菜单中了,键盘近的话就先win键,在摁快捷方式的首字母选择;鼠标近的话,就直接点了
    个人感觉多那么一步两步的操作其实对效率的影响并没有多大,反之,简洁直观,方便易用才是最重要的

  6. 关于TC的那段代码比我写的简洁多了,学习了,毕竟不是计算机专业。
    #a:: ;运行TotalCommander,快捷键win+a
    WinShow ahk_class TTOTAL_CMD
    IfWinNotExist ahk_class TTOTAL_CMD
    {
    run d:shortcutsT.lnk
    ;运行TotalCommander
    WinWait ahk_class TTOTAL_CMD
    WinActivate
    WinMaximize
    return
    }

    IfWinActive ahk_class TTOTAL_CMD
    {
    WinMinimize
    Return
    }

    IfWinNotActive ahk_class TTOTAL_CMD
    {

    WinActivate
    WinMaximize ahk_class TTOTAL_CMD
    Return
    }

  7. 请问各位知道有什么办法确认某组快捷键是被哪个应用程序占用的吗?
    在设置快捷键的时候,经常会发现某组快捷键已经被其他程序占用,可是又不知道到底是被什么程序占用,只好换用其他的组合,结果越来越乱。

  8. 我一直采win+r,直接启动的程序也不多,大约不超过5个,太多记不住,有回忆快捷键的时间,还不如直接点了。在这方面,还是善用佳软的观点实在,适合才是最好的。

    不过现在转到win7了,win+r或许都可以不用了,win7自带的快速启动十分方便,与win+r不相上下的,不知道善用佳软用的什么系统,对win7什么看法。

    ps:在这打个小广告,我在vimperator中提了个问题,那里人不多了,有知道的可以指点一下吗?

    谢谢。

  9. 关于快捷键,我一般是用Win+R作为常用,另外再结合极点五笔的命令直通车,基本上大部分操作都可用快捷键或快捷命令完成,极点的直通车可是一大亮点,有用的可以试试

  10. 请问一下,我想用AHK脚本完成如下功能:用putty上某个站,等连上之后输入用户名密码。
    现在总体功能可以实现,但“等连上之后”这步没有好的办法。我只能让它等待几秒钟,但这个站时快时慢,有时候瞬间就连上,有时候要等十几秒,如果我设置等待时间过短就无法正确输入用户名密码,等待时间过长则有点浪费。所以想问问,AHK能不能判断是否连上?(连上的话,putty窗口会显示login之类的字样,不知道AHK是否有这种判断?)
    感谢!
    (xbeta注: winwait支持wintext,详见AutoHotkey极为详细的帮助文档。)

    • 我试用winwait,窗口xxxx,wintext,login
      解决了测试login的情况。但是之后用
      winwait,窗口xxxx,wintext,password没法测试到出现password的情况。

  11. 我也有同样的需求,我的方法是判断窗口中出现的特定字符串,一旦出现,就开始动作。
    例如我的环境是,要求一旦出现$, 就证明登录成功,然后执行su – root 等操作。 我写了一个函数,供你参考。
    WinWaitForChar(pid,vChar,vTimeout)
    {
    SetTitleMatchMode 2
    myclipsaved := ClipboardAll
    clipboard =

    loop
    {
    PostMessage, 0x112, 0x170, 0, , ahk_pid %pid%
    ClipWait,1
    If clipboard contains $
    {
    clipboard :=myclipsaved
    WinActivate ,ahk_pid %pid%
    break
    }

    if A_TimeIdle > %vTimeout%
    {
    clipboard :=myclipsaved
    break
    }
    clipboard =
    }

    }

    真正调用的时候,就
    Run, putty.exe -ssh -pw xxx-l xxx %myhostname%,,Max,mypid
    WinWaitForChar(mypid,”$”,8000)

    其中8000是8秒的timeout值,防止登录窗口过长时间没反应。

  12. 俺是这样启动TC的(暂时没钱注册……)

    #t::
    ;;; Total Commander 自动运行,点击,切换
    DetectHiddenWindows, on
    IfWinNotExist ahk_class TTOTAL_CMD
    {
    Run C:totalcmdTOTALCMD.EXE
    WinWait ,Total Commander ahk_class TNASTYNAGSCREEN
    sleep 500
    IfWinExist ,Total Commander ahk_class TNASTYNAGSCREEN
    ;;自动点击
    Winactivate
    WinWaitActive
    ControlGetText ,TCText, TPanel2
    if TCText = 1
    {
    send 1
    }
    else if TCText = 2
    {
    send 2
    }
    else
    {
    send 3
    }
    }
    Else
    IfWinNotActive ahk_class TTOTAL_CMD
    WinActivate
    Else
    WinMinimize
    Return

  13. 在善用佳软的脚本做修改,想作一个类似的firefox应用,但不成功。
    firefoxd在最小化时不能被激活,但是如果作为当前窗口,可以被最小化。估计是第三行有误,但找不出问题。请高手指点一下。谢谢。
    #f::
    DetectHiddenWindows, On
    IfWinNotActive ahk_class MozillaWindowClass
    WinActivate
    Else
    WinMinimize
    Return

  14. 如何定义纯字母的快捷键呢?比如我定义 ”abc”触发一个功能 在依次按下了键盘字母 ”abc”后就执行。而不是用windows、Alt、shift等键,因为这些键容易被占用!

  15. 不知道AHK能不能仅在某个程序中检测快捷键,其它程序中则忽略掉它;
    其实是想在本地存一些常用命令,只在putty中才启用这些快捷键,这样冲突也会少很多

  16. 我刚下载AutoHotkey,它自动创建了一个脚本,然后显示
    Script lines most recently executed (oldest first). Press [F5] to refresh. The seconds elapsed between a line and the one after it is in parentheses to the right (if not 0). The bottommost line’s elapsed time is the number of seconds since it executed.

    016: Return (2.62)

    Press [F5] to refresh.

    我应该怎么编辑它?

发表回复

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据