现在的位置: 首页 > 综合 > 正文

用AutoHotkey辅助切换中英文标点和智能切换中英文输入法

2013年09月27日 ⁄ 综合 ⁄ 共 5158字 ⁄ 字号 评论关闭

    昨天,有位朋友问我用AutoHotkey如何检测某个键处于长按状态,他的目的就是在长按状态,自动将输入的英文标点切换成中文标点,或者反过来。对于程序员来说,中英文标点的切换是家常便饭,在编写程序时要用英文标点,而在其他窗口要使用中文标点。经常会因为标点状态不对,导致要退格删除之前的标点输入,然后切换输入法的标点状态,再重新输新的标点。由于要频繁地删除错误标点,频繁切换输入法标点状态,真的很烦人,本文尝试使用AutoHotkey来辅助标点中英文状态切换,相信程序员会有很大的兴趣!

 

    对于刚才那位朋友打算通过检测长按状态来自动切换中英文标点的做法,我不怎么赞同,因为这样做会影响输入速度,不够利索。我一般采用两种方法来切换中英文标点:第一种方法是,当输入的标点不对时,马上补上一个符号,将其切换成另一种标点;第二种方法是,安装两个输入法,一个设置英文标点(例如:搜狗五笔),另一个设置成中文标点(如:QQ五笔),在编程窗口按一个热键自动将输入法切换成搜狗五笔,而在Office窗口或QQ窗口按同样的热键,却切换成QQ五笔。

 

    方法一:补按一个键的方法切换标点符号

    例如:我在聊QQ时,输出了一个英文句号“.”,但事实上我想要的是中文句号“。”,此时我在"."号后面立刻再输入一个英文逗号","并按空格,前面输入的英文句号立即变成了中文句号。

    再举个例子,在编写程序的时候,本来想输出//符号表示行注释,然而由于中文输入法处于中文标点状态,结果输入两个顿号、、。以前的做法需要删除这两个顿号,切换成英文输入法,输出//后再将输入法切换回中文输入法。现在的做法,在两个顿号的后面补上一个分号,再输入一个空格即可将两个顿号变成//。

    其实实现这个功能的AutoHotkey脚本代码很简单,看好了:

::.,::

    SendbyClip("。")

    return

:://;::    ; 其实输出//本身,目的在于防止输入法将//变成、、

    sendbyclip("//")

    return

    代码完毕,这里解释一下sendbyclip()函数,它的作用是通过剪贴板粘贴的方法,将要输出的内容粘贴到光标处。函数定义如下:

sendbyclip(var_string)

{

    ClipboardOld = %ClipboardAll%

    Clipboard =%var_string%

    sleep 100

    send ^v

    sleep 100

    Clipboard = %ClipboardOld%  ; Restore previous contents of clipboard.

}

下面,将我常用的英文标点切换成中文标点的脚本分享给大家:

::90;::     ;; 输入90加分号输出()

    SelectLeftSpaceChar()

    SendbyClip("()")

    send {left}

    return

::'';::     ;; 输入''加分号输出“”

    SelectLeftSpaceChar()

    SendbyClip("“”")

    send {left}

    return

:::,::      ;; 输入:加逗号输出 中文冒号

    SelectLeftSpaceChar()

    SendbyClip(":")

    return

::?,::      ;; 输入英文问号?加逗号输出中文问号?

    SelectLeftSpaceChar()

    SendbyClip("?")

    return

::,,::      ;; 输入两个英文逗号,变成一个中文逗号

    SelectLeftSpaceChar()

    SendbyClip(",")

    return

::.,::      ;; 输入英语点号加逗号,变成中文句号

    SelectLeftSpaceChar()

    SendbyClip("。")

    return

::--;::     ;; 输入两个减号加一个分号,变成中文破折号

    SelectLeftSpaceChar()

    SendbyClip("——")

    return   

::...;::    ;; 输入三个点号加分号,变成一个中文省略号

    SelectLeftSpaceChar()

    SendbyClip("……")

    以上是我常用切换英文标点到中文标点的方法, 你可以根据自己的需要写出更多的切换,接下来介绍第二种方法。

 

 

    方法二: 根据窗口智能切换输入法

 

    在编程窗口(如,VC、VB、BCB、VIM等),按自定义的某个热键(假设Ctrl+空格)会将输入法切换成搜狗五笔,而在其他窗口按Ctrl+空格会切换成QQ五笔。但我习惯用";c"作为切换中文输入法的热键,而用";e"作为切换成英文输入法的热键。

/* VC2005的窗口 */

#ifwinactive ahk_class wndclass_desked_gsk,MsoDockTop

::;c::    ; 切换到搜狗五笔   

    SelectLeftSpaceChar()

    SwitchIME("搜狗五笔")

    return

/* C++ Builder 窗口*/

#ifwinactive ahk_class TEditWindow

::;c::    ; 切换到搜狗五笔   

    SelectLeftSpaceChar()

    SwitchIME("搜狗五笔")

    return

/* 其他窗口 */

#ifwinactive

::;c::    ; 切换到QQ五笔   

    SelectLeftSpaceChar()

    switchime("QQ五笔")

    return

::;e::    ; 切换至英文

;    SelectLeftSpaceChar()

    switchime("中文 (简体) - 美式键盘")

    return

::;sw::        ;; 切换到搜狗五笔   

    SelectLeftSpaceChar()

    SwitchIME("搜狗五笔")

    return

::;qw::        ;; 切换到QQ五笔   

    SelectLeftSpaceChar()

    switchime("QQ五笔")

    return

 

几点说明:

一、关于#ifwinactive的说明

#ifwinactive  窗口标题

这行代码与C的预编译有点类似,含义为当这个窗口是当前活动窗口时,#ifwinactive 下面的热键代码会生效,直到遇到下一个#ifwinactive。比如:

#ifwinactive ahk_class wndclass_desked_gsk,MsoDockTop

::;c::    ; 切换到搜狗五笔   

    SelectLeftSpaceChar()

    SwitchIME("搜狗五笔")

    return

这段代码中,#ifwinactive后面的标题为ahk_class wndclass_desked_gsk,MsoDockTop

该标题中VC2005窗口。因此热键 ;c 仅当在VC2005窗口时会生效。

接下来的代码,遇到#ifwinactive ahk_class TEditWindow

意味着前面的#ifwinactive ahk_class wndclass_desked_gsk,MsoDockTop  结束,

接下来的代码在ahk_class TEditWindow窗口激活时会生效,即在C++ Builder窗口中才生效。

再接下来遇到 #ifwinactive

意味着#ifwinactive ahk_class TEditWindow  结束

由于#ifwinactive  后面没带窗口标题,

表示其下面的代码,在除了上面提到的窗口之外的窗口,会生效。

结果就是:

1、同样输入 ;c ,在VC与C++Builder中会切换成搜狗五笔输入法,而在其他窗口会切换成QQ五笔输入法。

2、但是在任意窗口输入 ;e 将会切换成英文输入法。这是因为,

在#ifwinactive ahk_class wndclass_desked_gsk,MsoDockTop

与#ifwinactive ahk_class TEditWindow  中均未定义 ;e

因此#ifwinactive 作用范围内生效,前面两个范围中没有定义该热键,它将在全局范围生效。

相同地,在全局范围内输入 ;sw  会切换成搜狗五笔,输入 ;qw 会切换成QQ五笔。

二、关于我用;c来切换中文输入法的原因。

    首先,之所以用分号作为热键的第一个字符,主要是考虑到用中文输入法相吻合。在大部分中文输入法中,分号键都有特殊的用途,特别是极点五笔,分号可用来启动命令直通车,这与我们这里热键的功能是多么地相似啊!使用分号键作为热键的第一个字符,不管你当前处于什么输入法,都不会影响到后面命令的输入。你可以尝试不用分号作为热键的第一个字符,但我相信用久了之后,你会体会到分号的妙处!

其次, 分号与c都在主键盘的位置, 他们作为热键切换输入法, 手无需离开主键盘标准位置, 不会因为按快捷键(如Ctrl+空格)而中断输入。

三、SelectLeftSpaceChar()函数说明

    这里需要特别说明的是,::;c:: 定义了热键;c,那么;c就相当于一个单词,当你输入这个单词后,这个热键的代码就会被执行。既然是单词,在输入的时候前后都要输入空格来与其他单词分隔,AutoHotkey才会认为它是一个单词,才会激活这个热键。比如,当你输入this;c 时,Autohotkey会认为你输入的this;c才是一个完整的单词,而;c只是单词的一部分,从而不会激活;c热键。因此,如果你想在输入this 之后通过热键;c来切换中文输入法,那么在输入this之后需要加个空格再输入;c , 即this ;c 。如此一来,就多输入了一个空格,有的时候这个空格是多余的,我们不希望这个空格的存在。那么SelectLeftSpaceChar()这个函数的作用,就是用来选中这个多余的空格。在选中这个多余的空格之后,你再输入内容时,会自动替换掉了这个空格,从而无需手工退格删除这个空格了。

SelectLeftSpaceChar()

{

    autotrim off

    ClipboardOld := ClipboardAll

    Clipboard = $error$

    send {shift down}{left}{shift up}

    send ^c

    clipwait

    if Clipboard = $error$

    {

        return            ;; 如果没有选中内容,则返回

    }

    ifInString clipboard, `n

    {

        send {down}                     ;; 如果选中的是回车符号,那么向下退回原位

    }

    else if Clipboard is not space

    {

        send {right}                    ;; 如果选中了一个非空白字符,则向右退回原位

    }

    Clipboard := ClipboardOld

    autotrim on

}

四、switchime()  函数说明

    switchime()  这个函数的作用很明显,就是切换到指定的输入法。其原理是,通过在注册表中查找指定的输入法名称,找到输入法注册的键,再调用API函数切换到该输入法。函数定义如下:

SwitchIME(name)

    Loop, HKLM, SYSTEM/CurrentControlSet/Control/Keyboard Layouts,1,1

    { 

        IfEqual,A_LoopRegName,Layout Text

        { 

            RegRead,Value

            IfInString,value,%name%

            { 

                RegExMatch(A_LoopRegSubKey,"[^//]+$",dwLayout)

                HKL:=DllCall("LoadKeyboardLayout", Str, dwLayout, UInt, 1)

                ControlGetFocus,ctl,A

                SendMessage,0x50,0,HKL,%ctl%,A

                Break

            }

        }

    }

}

本次就到这里,有什么问题欢迎联系我,感谢阅读。

抱歉!评论已关闭.