zoukankan      html  css  js  c++  java
  • 自己动手,丰衣足食。普通键盘实现键盘宏(Windows和Mac版)

    很多高端机械键盘,支持宏定义,例如我们可以设置"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() {
    },";
     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 = "~!@#$%^&*()_+{}|:"<>? 
    ";
     60     string keys = "`1234567890-=[]\;',./";
     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 '
    ':
     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
    ", 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
    ", islower(key) ? key-32 : key, count);
    102     printf("Delay %d
    ", delay); //每次按键后延迟10毫秒
    103 }
    104 
    105 void callKey(OpType type, string key, int count) {
    106     procOpType(type);
    107     //printf(""%s"
    ", key.c_str());
    108     printf(""%s", %d
    ", key.c_str(), count);
    109     printf("Delay %d
    ", 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
    AppleScript_键盘宏_模板

    但是焦点会被dialog获取,需要在键盘宏之前把接收键盘宏的进程设为最前。

    tell process "XXXXXX"
        set frontmost to true
    end tell

    还是安装虚拟机好得多。。

  • 相关阅读:
    Codeforces 798C. Mike and gcd problem 模拟构造 数组gcd大于1
    Codeforces 796C. Bank Hacking
    Codeforces 792B. Counting-out Rhyme
    gym 101164 H.Pub crawl 凸包
    hdu 6053 TrickGCD 筛法
    hdu 6041 I Curse Myself 无向图找环+优先队列
    bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
    codeforces gym 101164 K Cutting 字符串hash
    树链剖分求lca
    UESTC 1697 简单GCD问题(一) 筛法
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/4778779.html
Copyright © 2011-2022 走看看