标签:
很多高端机械键盘,支持宏定义,例如我们可以设置"D"键为"dota",这样当我们按一下宏开启键,再按一下"D"键,就等价于分别按了"d" "o" "t" "a"四个键。这时就可以把一些敲代码时常用的模板定义成键盘宏,到时候一键补全代码,既高效又装X。另外,玩游戏时想按出“下前下前拳”这样的组合技能也容易多了。
那么问题来了。。
山里来的买不起机械键盘的穷B同时又是程序员应该怎么办。。
其实这样简单的功能不一定非要硬件支持,借助一些现有软件模拟一下键盘就好了,在windows下有按键精灵和AutoHotKey这些神器,模拟起来很容易,而且体验非常完美。
我是借助按键精灵实现的,按键精灵语法很简单,例如 KeyPress "A", 3 就表示按A键3次,而且支持全局快捷键启动,支持监听用户输入,真是简单到无情。
不过问题又来了。。
键盘宏主要是按一系列按键,如果每个按键都写一行 KeyPress "X", 1 ,有的还得配合Shift键才能按出来,也是累,而且一行一句代码,看上去不直观,容易写错。
那就写个代码生成器就好了,我是用C语言+std::string实现的,直接把宏写成字符串,生成器自动输出相应的按键,粘贴到按键精灵中编译保存就好了。
贴一下代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 #include <string> 6 7 using std::string; 8 9 enum class OpType { 10 Press, 11 Down, 12 Up 13 }; 14 15 enum class CombKey { 16 Shift, 17 Ctrl, 18 Alt 19 }; 20 21 void initTransHash(); //初始化按shift才能打出的字符 22 void transfer(char c); //shift打出的字符转化为真正的按键 23 void procOpType(OpType type); //输出按键操作 24 void callKey(OpType type, char key, int count=1); //按键 25 void callKey(OpType type, string key, int count=1); //重载,按功能键 26 void keyComb(CombKey comb, char key); //组合键 27 28 29 const int delay = 2; 30 string transChar; 31 char transHash[256]; 32 33 34 int main() { 35 initTransHash(); 36 37 string keys = "function() {\n},"; 38 39 for(char key : keys) { 40 if(strchr(transChar.c_str(), key) != NULL) { 41 transfer(key); 42 } else { 43 if(isupper(key)) { 44 keyComb(CombKey::Shift, key); 45 } else { 46 callKey(OpType::Press, key); 47 } 48 } 49 } 50 } 51 52 void initTransHash() { 53 memset(transHash, 0, sizeof(transHash)); 54 55 // 56 // ~ ! @ # $ % ^ & * ( ) _ + { } | : \" < > ? 57 // ` 1 2 3 4 5 6 7 8 9 0 - = [ ] \\ ; ‘ , . / 58 59 transChar = "~!@#$%^&*()_+{}|:\"<>? \n"; 60 string keys = "`1234567890-=[]\\;‘,./\0\0"; 61 62 // transChar空格后面的字符不加入hash表 63 for(int i = 0; i < keys.size(); i++) { 64 transHash[transChar[i]] = keys[i]; 65 } 66 } 67 68 void transfer(char c) { 69 if(transHash[c]) { 70 keyComb(CombKey::Shift, transHash[c]); 71 return; 72 } 73 switch(c) { 74 case ‘\n‘: 75 callKey(OpType::Press, "Enter"); 76 break; 77 78 case ‘ ‘: 79 callKey(OpType::Press, "Space"); 80 break; 81 82 default: 83 printf("[Red] cant transfer: %c\n", c); 84 break; 85 } 86 } 87 88 void procOpType(OpType type) { 89 switch(type) { 90 case OpType::Press: 91 printf("KeyPress "); break; 92 case OpType::Down: 93 printf("KeyDown "); break; 94 case OpType::Up: 95 printf("KeyUp "); break; 96 } 97 } 98 99 void callKey(OpType type, char key, int count) { 100 procOpType(type); 101 printf("\"%c\", %d\n", islower(key) ? key-32 : key, count); 102 printf("Delay %d\n", delay); //每次按键后延迟10毫秒 103 } 104 105 void callKey(OpType type, string key, int count) { 106 procOpType(type); 107 //printf("\"%s\"\n", key.c_str()); 108 printf("\"%s\", %d\n", key.c_str(), count); 109 printf("Delay %d\n", delay); //每次按键后延迟10毫秒 110 } 111 112 void keyComb(CombKey comb, char key) { 113 string combKey; 114 switch(comb) { 115 case CombKey::Shift: 116 combKey = "Shift"; break; 117 case CombKey::Ctrl: 118 combKey = "Ctrl"; break; 119 case CombKey::Alt: 120 combKey = "Alt"; break; 121 default: 122 return; 123 } 124 125 callKey(OpType::Down, combKey); 126 callKey(OpType::Press, key); 127 callKey(OpType::Up, combKey); 128 }
然后把每一个键盘宏写成一个函数,通过按下按键精灵的全局快捷键启动,然后脚本监听用户按键,然后调用相应函数执行键盘宏就可以了,模板类似这样:
1 choose = WaitKey() 2 TracePrint choose 3 4 Select Case choose 5 Case 70 6 KeyPress "BackSpace", 1 7 Call F() 8 Case 72 9 KeyPress "BackSpace", 1 10 Call H() 11 End Select 12 13 // 按下F键 14 Sub F() 15 End Sub 16 17 // 按下H键 18 Sub H() 19 End Sub
(宏键也会打印出来,所以我在调用函数打印键盘宏之前,调用BackSpace删除了宏键的字符)
然后问题又来了。。
上班用的是Mac,Mac没有按键精灵呀。最简单的办法是安装windows虚拟机,物理机和虚拟机共享代码目录,在虚拟机中敲代码,其他工作仍然在物理机中进行,不影响工作流。(其实用了5个月的Mac了,个人感觉,在新鲜感过了之后,实用性比windows差远了)
另外如果不想通过虚拟机的方式,还可以使用AppleScript,但是AppleScript本身没有像按键精灵那样的全局启动快捷键,可以通过Automator把AppleScript设置为系统服务,然后给服务设置快捷键,但是AppleScript不方便监听用户按键事件,目前我只能通过dialog读取用户输入,所以做不到按键精灵那样完美,上面的生成器的代码稍微改动一下,就能作为AppleScript的键盘宏生成器了,下面是AppleScript的模板:
1 tell application "System Events" 2 display dialog "choose" default answer "" 3 set ans to text returned of result 4 5 if ans = "p" then 6 keystroke "1" 7 keystroke "0" 8 keystroke "0" 9 keystroke "8" 10 keystroke "6" 11 else 12 display dialog "unknown" 13 end if 14 15 end tell
但是焦点会被dialog获取,需要在键盘宏之前把接收键盘宏的进程设为最前。
tell process "XXXXXX" set frontmost to true end tell
还是安装虚拟机好得多。。
自己动手,丰衣足食。普通键盘实现键盘宏(Windows和Mac版)
标签:
原文地址:http://www.cnblogs.com/wolfred7464/p/4778779.html