2016年9月13日 星期二

讓 windows 10也能像 OS X般的切換輸入法

小弟我算是橫跨 win、mac 兩個桌上型作業系統的人吧,

公司只有提供 windows系統的桌機,而我個人又選擇了 macbook pro來當行動解決方案。
以往用的是10多年前的xp,基本上都沒啥大事。但是最近手殘把它換成 windows 10,才覺得新的中、英文切換根本是個笑話。加上 win,mac兩邊跳,常常錯亂。所以想說來把 windows的切換方式向 mac致敬一下。

除了專用程式外,鍵盤按鍵的致敬,最快最好的方式應該屬使用 AutoHotKey這個程式了吧。看了一下,其實不只我,日本韓國戰鬥民族,都曾對這個議題發過文章,也都是用 AutoHotKey來處理(廢話,就是以AutoHotKey當關鍵字去搜尋的呀!)。但是,這個議題似乎很早就有人提過了,而且是在 windows 7的時代。不過,windows 10和 7的輸入法切換的理念根本不是同一檔次的,雖然很多 dllcall都一樣,我還是看不太懂。

話說,日本的 Script應該是最完整的,但是因為寫法太正統,小弟我功力不足,改不動。在沈寂了幾個月之後,受不了的我又再度出擊,這次很幸運的,竟然在神人最多的 ptt上看到了一線曙光。更重要的是,它是 2012年的資料,比那種 2007年的問題還有用千百倍。

所以我的 script如下(斷行請自我接起來):

IME_STATUS(hWindow)
{
IMEWnd := DllCall("imm32.dll\ImmGetDefaultIMEWnd", "Uint", hWindow)
buf := DllCall("user32.dll\SendMessageA", "UInt", IMEWnd, "UInt", 0x0283, "Int", 0x0005, "Int", 0)
Return buf
}

IME_ON(hWindow, ON)
{
IMEWnd := DllCall("imm32.dll\ImmGetDefaultIMEWnd", "Uint", hWindow)
buf := DllCall("user32.dll\SendMessageA", "UInt", IMEWnd, "UInt", 0x0283, "Int", 0x0006, "Int", ON)
Return buf
}

Shift::
send {shift}
return

CapsLock::
DetectHiddenWindows, On
hWindow := WinExist("A")
statusIME_1 := IME_STATUS(hWindow)
Capslocked := GetKeyState("Capslock", "T")

if (statusIME_1 > 0) {
IME_ON(hWindow, false)
SetCapsLockState, off
}
else if (statusIME_1 = 0) {
IME_ON(hWindow, true)
statusIME_2 := IME_STATUS(hWindow)
if (statusIME_2 > 0) {
SetCapsLockState, on
}
else if (Capslocked = 0 ) {
SetCapsLockState, on
}
else {
SetCapsLockState, off
}
}
return

#ScrollLock::
SetCapsLockState, off
return
存成 .ahk就可以用了。

現在來說明一下我的想法:
1。要先讓 shift切換 英數/中文 的功能失效。
所以,把單按 shift的事件攔截下來,再多丟一個單按 shift的事件,等於 shift被按兩次,就不會切換輸入法了。啊有人會問說,設定的地方,不是可以關掉 shift切換輸入法的功能嗎?是的,是可以關的,但是只限於注音,我常用的行列就沒有設定可以改。

2。要讓 CapsLock可以切換 英數/中文。
如同在 mac中,英數時為小寫,中文時按 shift+英文 時,也是出現小寫。所以要同時控制系統大小寫的狀態,以及中文輸入法的啟動狀態。因此,必需用條件式來判斷。原來系統有的 ctrl-space的切換功能,就不去動它了。

3。要有其他切換系統大小寫的狀態的按鍵。
因為我用的是無線鍵盤,所以大小寫的燈不見得會和鍵盤的燈一致。

現在是爽爽用,不必小指頭在那邊搞不清楚狀況瘋狂的把 CapsLock及 shift亂按一通。

沒有留言: