前:所謂修飾鍵,就是Ctrl,Alt,Shift,Win這些按鍵。
Update: 我使用AHK寫了一個功能更豐富的腳本:https://github.com/h46incon/ModifierCustomizer
一、功能:
- 能自定義新的修飾鍵
- 在這個修飾鍵的基礎上可以定義新的組合快捷鍵
- 對於快捷鍵的功能,呃,只能進行映射到別的按鍵
- 如把<Capslock+J>映射至下方向鍵(Vim黨的福音)
制作這個工具的原因就是Vim用慣了,就不想使用方向鍵了。所以就想着能使用別的快捷鍵代替這幾個方向鍵。
而由於想使得這個程序更通用,就不想占用現有的快捷鍵,比如天知道<Ctrl+h>在哪個軟件中會是什么功能。所以想法就是Ctrl,Alt,Shift,Win之外,能增加修飾鍵。比如就在左Shift鍵上方的Capslock鍵。(其實我把Capslock鍵和ESC鍵換過來了……)
具體來講,自定義修飾鍵的工作方式如下:
- 當按下修飾鍵時,不觸發這個按鍵,而是等待
- 若直接彈起這個修飾鍵,則觸發該按鍵:按下、彈起 兩個事件
- 若有普通鍵按下、彈起,則根據需要進行重映射。(這里需要將處於按下狀態的重映射按鍵記錄起來)
- 若彈起修飾鍵時,仍要需要映射的鍵未彈起,則彈起這個按鍵
二、實現:
選擇的語言是C++,然后配置文件是用xml儲存的,xml解析的庫是tinyxml2。
1. 資源管理
對於資源的管理使用的是RAII的方式,這些使用的是劉未鵬C++11(及現代C++風格)和快速迭代式開發這里提到的很方便的設施,用起來就像這樣:
FILE* conf_file = fopen(file_name, "r"); ScopeGuard close_conf_file( [&]{fclose(conf_file);} );
另外,這里還有一個宏,所以你要是嫌麻煩的話,連close_conf_file這樣的類名都不用自己起了……就像這樣:
#define SCOPEGUARD_LINENAME_CAT(name, line) name##line #define SCOPEGUARD_LINENAME(name, line) SCOPEGUARD_LINENAME_CAT(name, line) #define ON_SCOPE_EXIT(callback) ScopeGuard SCOPEGUARD_LINENAME(EXIT, __LINE__) (callback) // Acquire Resource1 ON_SCOPE_EXIT( [&] { /* Release Resource1 */ })
2. 鍵盤事件相關的API
- LowLevelConvertKeyInput: 用來在全局范圍內接受鍵盤事件
- keybd_event:向系統發送按鍵事件
- SetWindowsHookEx: 添加系統鈎子。由於這個鈎子不需要插入別的程序的運行空間中,所以也不需要編譯成DLL。
- GetMessage,TranslateMessage,DispatchMessage:消息循環
3. 托盤
用goagent的托盤:https://github.com/goagent/taskbar
做了一些修改:比如刪掉了托盤菜單的一些項目,並增加了窗口延遲隱藏的選項。
使用VS2013可以打開這個項目,但是API有了一些變化了。需要把taskbar.cpp文件的第123行改一下(只是結構體成員的名字變了)。
編譯好之后,他默認會打開cmd.exe。然后使用Reshacker修改一下這個程序的相關字符串和圖標就可以了:
至於這么難看的圖標嘛,不要在意細節……然后我是用PS直接生成的ICO,256*256的,所以有點大了哈……
4. VS2013的C++運行時庫
VS2012開始(VS2010不知道,08還不會),默認情況下編譯出來的程序需要額外的運行時庫了。但是咱編個幾百行代碼的程序,也不想弄得這么麻煩。
這里需要修改一下使用的運行時庫,即將默認/MD選項改為/MT。改好之后編出來的程序就可以直接扔到別的電腦上跑了(XP的話仍需要另外設置)
三、程序下載:
http://files.cnblogs.com/h46incon/KeyRemaper.zip