数位板配置通用画笔橡皮快捷键
1. 背景
因为有在PDF
上写写画画的需求,所以买了一块高漫M6
的数位板,便宜入门能用就行。然后在实际使用过程当中,发现偶尔得在几个不同的软件之间切换,而他们的快捷键不同甚至说根本就没有快捷键。这就很难受了,因为一般沉浸式书写的时候,最讨厌打断节奏了。
在多处调研解决方案时,发现了一个AutoHotkey
的操作1。但是我感觉这个好像需要一个软件一直在后台运行,这样才能监测到用户对不同窗口按下的同快捷键。以及我并不熟悉AutoHotkey
这个工具,查了下资料发现功能还挺强大的,感觉用在这里有些臃肿和浪费。不过这个方法给我带来启发,我们完全可以单独写脚本来触发功能。
无论是模拟鼠标点击屏幕上的工具,还是模拟键盘来使用快捷键,都能用编程语言实现,可以分别写画笔和橡皮的启动脚本。那么还有一个问题就是,这样的脚本该如何触发呢?诶,高漫M6
的驱动里面就有方法。为某个键设置快捷键的时候,可以设定其运行指定的exe
文件,这不就可行了嘛
还有一个问题,这里得写一下我常用的软件。那么首先是神中神,OneNote
,这个在知乎有很多关于快捷键的讨论2。我看了下发现自己的版本不适用,然后也懒得倒退版本。或者也有适用版本的,但是感觉不够优雅,按键有点复杂。然后是Xodo PDF
,也很不错,我是在微软应用商店安装的,支持快捷键。但问题就是写一段时间之后,当笔迹多了之后,会变卡,或者是笔迹漂移什么的。接下来是DrawBoard PDF
,也很不错,但我愣是一直没发现它还支持快捷键,还是在上面那个教程1的评论区看到的。还有就是BookxNote
,在B站
发现的一个读书笔记软件,基本没咋用。再说一个Inkodo
,好像是可以压感练书法的,没具体用过。以及神奇的ZoomIt
,基本可以在任何地方进行屏幕标注。还有一个是微软自带的白板,Microsoft Whiteboard
,感觉跟OneNote
差不多,但是白板看上去更自由一些,以及这个快捷键是真难搞。
噢,对了,我这脚本是用C
语言写的,然后gcc
一通编译。由于本人不擅此道,以及脚本实在太过简单,所以什么版本之类的应该不用在意。
2. 实现
2.1. 主要思路
首先是整体的说法,就,在一个具体的PDF
软件当中,当用户需要切换画笔的时候,只需要按下手写笔的下键,然后会触发我们自己写的exe
应用程序,来模拟点击工具栏里屏幕画笔的按钮,或者是模拟按下快捷键切到画笔。当然仅仅这样是不够的,我们还要适配不同软件的情况,做到多个软件使用同一个脚本。然后就是单个脚本只做单个功能,运行这个脚本就是切换到画笔,想要切换到橡皮得运行另一个脚本。
这里我们来说一说单个脚本的思路吧,这里以画笔为例。首先我们要检测当前所在的窗口是什么软件,因为这意味着我们使用什么方式去触发画笔,比如说在OneNote
需要点击屏幕的特定区域,而Xodo
直接按I
键就能触发墨水Ink
的画笔功能。接着就顺理成章,根据不同的软件,用不同的方式去触发画笔,反正不是点击屏幕就是模拟键盘按压。当然还有一个问题,那就是用鼠标点击之后,鼠标的位置还要返回原位置,也就是得预先记录触发脚本时鼠标的位置。
2.2. 识别窗口
这个貌似也是挺麻烦的,我最早的想法是直接根据窗口去抓进程,去看看属于哪个软件,以此来确定接下来需要触发的快捷键。但是查了下教程3发现好像挺复杂的,然后试了下还没复现成功,于是决定尝试获取窗口标题。找了篇教程4,复现成功了,就决定使用GetWindowText()
但是拿到窗口标题,也还需要进一步地加工。比如说我在OneNote
开了个名为draft
的笔记本,然后标题栏里面就也会出现这个单词,但是其他笔记本又不叫这个名字,所以直接获取到的窗口标题栏并不能作为标识。



但是好在我们可以观察到,页面标题栏的末尾一般跟的是软件的名称,所以我们需要对这串字符做一下小小的分割。但很遗憾的,C
语言是很基础的,所以分割字符串这种工具需要自行造轮子。而我这也不是什么大工程,不需要那么完备的轮子,于是找了个教程5自行删减了一版。
2.3. 模拟按键
这个挺简单的,找个教程6,用keybd_event
就行,照着官方文档对应的表7查一查对应。
2.4. 模拟点击
这个就有点意思了,因为坐标需要换算一下。首先我们要先知道自己屏幕的分辨率,然后根据这个分辨率确定画笔按钮所在的区域,选一个落在这个区域的点,使得点击这个坐标点就能触发画笔。关于如何获取坐标点,已经有很多方案了,很多截图工具自带的就有,比如Snipaste
或者是QQ
自带的截图。总之开启截图后,鼠标拉到右下角,那个坐标基本就是分辨率,我的是1920*1080
。然后鼠标放在画笔图标上,这个坐标就是启动点。
关于如何换算,参考这篇教程8里面的细节,以我的分辨率为例,大致的公式是:
65536
∗
(
x
_
l
o
c
+
1
)
/
1920
65536 * (x\_loc + 1)/1920
65536∗(x_loc+1)/1920和
65536
∗
(
y
_
l
o
c
+
1
)
/
1080
65536 * (y\_loc + 1)/1080
65536∗(y_loc+1)/1080,反正就是把坐标放缩或者说标准化到0-65536
这个范围内。由于我的坐标是0
开始的,所以加了个1
。实际上无所谓,这点偏移量没啥影响。
2.5. 调试细节
2.5.1. 窗口标题
主要的调试工作是在获取窗口名称的时候。首先我们需要找的是,程序获取的窗口名称是啥。然后就像代码里面的,get
之后我拿MessageBox
打印了一下。毕竟编译的时候去除窗口了,而更为巧妙的调试方式我也不会,所以只好用笨办法了。就像这样:
#include <stdio.h>
#include <windows.h>
#include <string.h>
// #include <stdlib.h>
int main() {
HWND foreground = GetForegroundWindow();
if (foreground)
{
char window_title[256];
GetWindowText(foreground, window_title, 256);
// char window_title[] = "draft - draft - OneNote";
// char *window_title_origin = strdup(window_title);
char delim[] = " ";
char *token_iter = NULL;
char *token_result = NULL;
for(
token_iter = strtok(window_title, delim);
token_iter != NULL;
token_iter = strtok(NULL, delim)
){
token_result = token_iter;
}
// MessageBox(NULL,token_result,NULL, MB_OK );
// MessageBox(NULL,strcat(strcat(token_result,"\n"),window_title_origin),NULL, MB_OK );
// trim(token_result);
char concat_result[32];
sprintf(concat_result, "TT%sTT", token_result);
MessageBox(NULL,concat_result,NULL, MB_OK );
}
return 0;
}
把这段代码编译成可执行文件,然后绑定到数位板的快捷按键上面。接着去打开OneNote
这样的窗口,点击窗口聚集,然后按一下刚刚绑定的快捷键,看一看这个窗口标题被截取到的关键词是什么,截取到的关键词就是判断条件
还有一个地方是关于分割字符串的,我也试过其他的分割字符,但是都不如空格好使。反正空格分割出来的七零八落的,也能给每个软件一个唯一的标识,反正够用了。
2.5.2. 按键无效
这个问题出现在调试微软白板的时候,明明跟其他软件一样设置好了快捷键,但还是不起作用,这个时候就要仔细地、一步一步地查找问题了。
2.5.2.1. 扫描代码
我首先想到的是,代码里面的判断条件激活了吗?也就是说代码是否执行到了这一部分…因为之前确实有过这样的情况,就是我把窗口标题的单词拼写错了,导致代码没有运行到这一部分。那么话说回来,我在这个判断条件里面埋了个MessageBox
,正确触发了,看来没问题。
接下来看看按键,我把keybd_event
模拟按键换了,改成win+s
,也就是唤醒搜索框,这个也成功了,在白板里面能正确触发。
看起来,就是说,模拟白板快捷键的时候出问题了,比如说画笔快捷键alt+w+1
,那就以此为关键词搜索吧
在搜索引擎上,确实找到了keybd_event
失效的问题,详见这个9。大概就是说,需要改一下参数,增加一个扫描代码
按照这个里面的表格,更改了第二个参数,画笔、橡皮、套索都可以了,但是手形工具还不行
2.5.2.2. 手形问题
按照教程,我们得用Spy++
,直接去GitHub
吧,是这个12
这个教程貌似不适用于我这里的情况,所以贴一下我处理的方法吧:
首先,解压下载的包,里面貌似包括了好几个版本,我选了spy14.00.25420
。点进这个文件夹之后,由于电脑是64
位,所以我直接启动了spyxx_amd64
关于Spy++
捕捉日志的设置,如下:
首先去找日志部分,先点sqy
再点log
那个
打开日志设置,默认的就是窗口设置,勾选监测所有窗口,然后去设置捕捉的消息类型
先清除所有选项,然后选监测所有键盘消息。教程里面只选了WM_HOTKEY
,但是我发现只选这个捕捉不到快捷键,最后记得点确定
现在主窗口就会显示所有的键盘消息了,理论上此时主窗口是空白。但如果你敲了键盘的话,是会有一些其他日志的,右键清除即可
2.5.2.2.1. 释放代码
接着切换到白板窗口,先按键盘上面的alt+s
,然后再按数位板快捷键,也就是运行我们写好的代码编译出来的可执行文件。首先需要停止记录日志,要不然再按一下别的按键,会污染日志,操作如下:
理论上来说,我这里捕捉到的是10
条日志,上面那张图片多了一条,是捕捉到了我在截屏的时候,win+shift+s
的那个s
,我也不知道为什么就只捕捉到一个s
。那么下面这张图片是我再一次捕捉到的日志,为什么这里只有10
条而没有截屏呢?是因为我停止了记录日志,然后按F1
呼叫Snipaste
的全屏快捷键,截下来这张日志图片:
由于我们先按的键盘,后运行的可执行程序,所有从这里我们可以看到的是,前五行代表键盘消息,后五行代表虚拟键盘的消息。一个很显然的问题是,s
键在这里释放的时候,物理键盘的扫描代码是0x1F
,跟按下的时候一样,并不是教程里面的0x9F
,那我们改一下看看吧
2.5.2.2.2. 按键顺序
很遗憾的是,改完释放代码,还是不行,那只能再抓一下日志了。步骤如上,日志如下:
很神奇,我看了下大概是前面的前缀不同,一个是WM_SYSKEYIP
,另一个是WM_KEYUP
;然后就是,后面的有个参数不同。
查了下,后面那个参数大概意味着,alt
键有没有被按下
那这两行日志的区别就是,按下按键之后,松开按键的时候,先松开s
再松开alt
有效,否则无效
我感觉有点扯,于是用实体键盘模拟了一下,先松开alt
是真不行
其实在第一次捕捉日志的时候,这个点就被我注意到了。当时觉得没啥问题,没想到这么神奇
于是我们调换一下松开按键的顺序,问题解决了
2.5.3 其他问题
以及一些其他问题就是,我之前有一次死活都触发不了手写,最后发现是因为zoomit
没启动,这真是,太神奇了。
不过这好像在OneNote
当中也有不好用的时候,我有时切换笔的按两次。不过这好像不是bug
,而是OneNote
自带的什么机制,反正就是切换工具时也有相关规则。无所谓,不咋影响使用,暂时不用管。
啊,对,高漫驱动里面那个,Windows Ink
一般可以关掉,貌似没啥用。在使用Zoomit
的时候,开启这个会使得鼠标指针消失,也就是说在屏幕上看不到代表鼠标的点,这在做批注的时候十分难受。
2.6. 编译代码
我先直接编译了代码,发现默认图标挺丑的,于是就寻思能不能放个自定义的,然后找了篇教程14。大概过程就是,首先你需要一个ico
图标文件,可以去这里15输入PNG
什么的进行转换。至于PNG
,反正只是自己用,应该不会涉及什么版权之类的,直接百度搜画笔图标什么的。
编译图标其实还挺烦的,首先要有个rc
文件,比如pen.rc
:
1 ICON "pen.ico"
大概格式貌似是,第一列是个数字,然后第二列是个单词,第三列双引号引住文件名。我也是直接抄的教程,只改了下文件名。
接着需要把rc
编译成o
:
windres pen.rc -o pen.o
然后理论上来说就可以直接gcc
了,但是我发现直接gcc
直接编译的结果会出现黑窗口,于是又找了个教程16,加个-mwindows
参数,最终命令如下:
gcc -mwindows pen.c pen.o -o pen.exe
2.7. 设置按键
点开高漫的驱动,然后点手写笔的快捷键,选运行程序
,然后填入刚刚编译好的文件的路径
2.8. 原快捷键
2.8.1. Xodo
Xodo
主页面左下角点设置,然后点键盘快捷键,然后下滑就能找到
2.8.2. DrawBoard
DrawBoard
同样主页左下角,然后去帮助,滑到底部点快捷键
弹出页面下滑到底部,可以发现数字键对应工具栏当中的工具。至于如何调整工具栏,我想这是十分简单的事情,理论上来说随便摸索一下就可以,在此处不做赘述。
2.8.3. 微软白板
也可以在工具按钮上方悬停鼠标,过一会儿它自己也会弹出来
3. 代码
3.1. 画笔
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
void click_point_and_return(int x_loc, int y_loc){
POINT pt;
GetCursorPos(&pt);
// remember the mouse location now
mouse_event(
MOUSEEVENTF_ABSOLUTE
// use absolute coordinates
|MOUSEEVENTF_MOVE
|MOUSEEVENTF_LEFTUP
|MOUSEEVENTF_LEFTDOWN
,65536 * (x_loc + 1)/1920
,65536 * (y_loc + 1)/1080
// here we use snipaste to get the coordinates
// due to snipaste locate point at 1920*1080
// but mouse_event at 65536*65536
// so it needs to be normalized
,0
,0
);
// left click at (280,90) means black pen
SetCursorPos(pt.x,pt.y);
// return to original position
}
int main() {
HWND foreground = GetForegroundWindow();
// get the handle of current window
if (foreground)
{
char window_title[256];
GetWindowText(foreground, window_title, 256);
// get correspond tittle
char delim[] = " ";
// use space to split the tittle text
char *token_iter = NULL;
// store the split piece
char *token_result = NULL;
// store the last piece of split result and often is software name
for(
token_iter = strtok(window_title, delim);
token_iter != NULL;
token_iter = strtok(NULL, delim)
){
token_result = token_iter;
}
// MessageBox(NULL,token_result,NULL, MB_OK );
// char concat_result[32];
// sprintf(concat_result, "TT%sTT", token_result);
// MessageBox(NULL,correspond,NULL, MB_OK );
if(strcmp("OneNote",token_result)==0){
click_point_and_return(280,90);
// Onenote: click to change to the black pen
}
else if(strcmp("PDF",token_result)==0){
keybd_event(0x33, 0, 0, 0);
keybd_event(0x33, 0, KEYEVENTF_KEYUP, 0);
// Drawboard PDF: press 3 to change to the black pen
}else if(strcmp("Xodo",token_result)==0){
keybd_event(0x49, 0, 0, 0);
keybd_event(0x49, 0, KEYEVENTF_KEYUP, 0);
// PDF reader by Xodo: press I to change to the black pen
}else if(strcmp("Pro",token_result)==0){
keybd_event(0x49, 0, 0, 0);
keybd_event(0x49, 0, KEYEVENTF_KEYUP, 0);
// BookxNote Pro: press I to change to the black pen
}else if(strcmp("Whiteboard",token_result)==0){
// MessageBox(NULL,token_result,NULL, MB_OK );
keybd_event(0xA4, 0x38, 0, 0);
// ALT
keybd_event(0x57, 0x11, 0, 0);
// W
keybd_event(0x31, 0x02, 0, 0);
// 1
keybd_event(0xA4, 0xB8, KEYEVENTF_KEYUP, 0);
keybd_event(0x57, 0x91, KEYEVENTF_KEYUP, 0);
keybd_event(0x31, 0x82, KEYEVENTF_KEYUP, 0);
// Microsoft Whiteboard : press ALT+W+1 to change to the black pen
}else{
keybd_event(0xA2, 0, 0, 0);
// ctrl
keybd_event(0x32, 0, 0, 0);
// 2
keybd_event(0xA2, 0, KEYEVENTF_KEYUP, 0);
keybd_event(0x32, 0, KEYEVENTF_KEYUP, 0);
// other window : press ctrl + 2 to change to the pen
}
// }else if(strcmp("粉笔课堂-首页",token_result)==0){
// keybd_event(0xA2, 0, 0, 0);
// keybd_event(0x32, 0, 0, 0);
// keybd_event(0xA2, 0, KEYEVENTF_KEYUP, 0);
// keybd_event(0x32, 0, KEYEVENTF_KEYUP, 0);
// // fen bi : press ctrl + 2 to change to the pen
// }else{
// exit(0);
// }
}
return 0;
}
3.2. 橡皮
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
void click_point_and_return(int x_loc, int y_loc){
POINT pt;
GetCursorPos(&pt);
// remember the mouse location now
mouse_event(
MOUSEEVENTF_ABSOLUTE
// use absolute coordinates
|MOUSEEVENTF_MOVE
|MOUSEEVENTF_LEFTUP
|MOUSEEVENTF_LEFTDOWN
,65536 * (x_loc + 1)/1920
,65536 * (y_loc + 1)/1080
// here we use snipaste to get the coordinates
// due to snipaste locate point at 1920*1080
// but mouse_event at 65536*65536
// so it needs to be normalized
,0
,0
);
// left click at (280,90) means black pen
SetCursorPos(pt.x,pt.y);
// return to original position
}
int main() {
HWND foreground = GetForegroundWindow();
// get the handle of current window
if (foreground)
{
char window_title[256];
GetWindowText(foreground, window_title, 256);
// get correspond tittle
char delim[] = " ";
// use space to split the tittle text
char *token_iter = NULL;
// store the split piece
char *token_result = NULL;
// store the last piece of split result and often is software name
for(
token_iter = strtok(window_title, delim);
token_iter != NULL;
token_iter = strtok(NULL, delim)
){
token_result = token_iter;
}
// MessageBox(NULL,token_result,NULL, MB_OK );
// char concat_result[32];
// sprintf(concat_result, "TT%sTT", token_result);
// MessageBox(NULL,correspond,NULL, MB_OK );
if(strcmp("OneNote",token_result)==0){
click_point_and_return(230,90);
// Onenote: click to change to the eraser
}
else if(strcmp("PDF",token_result)==0){
keybd_event(0x32, 0, 0, 0);
keybd_event(0x32, 0, KEYEVENTF_KEYUP, 0);
// Drawboard PDF: press 2 to change to the eraser
}else if(strcmp("Xodo",token_result)==0){
keybd_event(0x45, 0, 0, 0);
keybd_event(0x45, 0, KEYEVENTF_KEYUP, 0);
// PDF reader by Xodo: press E to change to the eraser
}else if(strcmp("Pro",token_result)==0){
keybd_event(0x45, 0, 0, 0);
keybd_event(0x45, 0, KEYEVENTF_KEYUP, 0);
// BookxNote Pro: press E to change to the eraser
}else if(strcmp("Whiteboard",token_result)==0){
keybd_event(0xA4, 0x38, 0, 0);
// ALT
keybd_event(0x58, 0x2d, 0, 0);
// X
// MessageBox(NULL,token_result,NULL, MB_OK );
keybd_event(0xA4, 0xB8, KEYEVENTF_KEYUP, 0);
keybd_event(0x58, 0xad, KEYEVENTF_KEYUP, 0);
// Microsoft Whiteboard : press ALT+X to change to the eraser
}else{
keybd_event(0x1B, 0, 0, 0);
keybd_event(0x1B, 0, KEYEVENTF_KEYUP, 0);
// other window : press ESC to exit the pen mode
}
// }else if(strcmp("Window",token_result)==0){
// keybd_event(0x1B, 0, 0, 0);
// keybd_event(0x1B, 0, KEYEVENTF_KEYUP, 0);
// // fen bi : press ESC to change to the eraser
// }else{
// exit(0);
// }
}
return 0;
}
3.3. 套索
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
void click_point_and_return(int x_loc, int y_loc){
POINT pt;
GetCursorPos(&pt);
// remember the mouse location now
mouse_event(
MOUSEEVENTF_ABSOLUTE
// use absolute coordinates
|MOUSEEVENTF_MOVE
|MOUSEEVENTF_LEFTUP
|MOUSEEVENTF_LEFTDOWN
,65536 * (x_loc + 1)/1920
,65536 * (y_loc + 1)/1080
// here we use snipaste to get the coordinates
// due to snipaste locate point at 1920*1080
// but mouse_event at 65536*65536
// so it needs to be normalized
,0
,0
);
// left click at (280,90) means black pen
SetCursorPos(pt.x,pt.y);
// return to original position
}
int main() {
HWND foreground = GetForegroundWindow();
// get the handle of current window
if (foreground)
{
char window_title[256];
GetWindowText(foreground, window_title, 256);
// get correspond tittle
char delim[] = " ";
// use space to split the tittle text
char *token_iter = NULL;
// store the split piece
char *token_result = NULL;
// store the last piece of split result and often is software name
for(
token_iter = strtok(window_title, delim);
token_iter != NULL;
token_iter = strtok(NULL, delim)
){
token_result = token_iter;
}
// MessageBox(NULL,token_result,NULL, MB_OK );
// char concat_result[32];
// sprintf(concat_result, "TT%sTT", token_result);
// MessageBox(NULL,correspond,NULL, MB_OK );
if(strcmp("OneNote",token_result)==0){
click_point_and_return(170,90);
// Onenote: click to change to the lasso tool
}else if(strcmp("PDF",token_result)==0){
keybd_event(0x31, 0, 0, 0);
keybd_event(0x31, 0, KEYEVENTF_KEYUP, 0);
// Drawboard PDF: press 1 to change to the lasso tool
}else if(strcmp("Xodo",token_result)==0){
keybd_event(VK_LCONTROL, 0, 0, 0);
keybd_event(0x4C, 0, 0, 0);
keybd_event(VK_LCONTROL, 0, KEYEVENTF_KEYUP, 0);
keybd_event(0x4C, 0, KEYEVENTF_KEYUP, 0);
// PDF reader by Xodo: press Ctrl+L to change to the lasso tool
}else if(strcmp("Pro",token_result)==0){
keybd_event(0x50, 0, 0, 0);
keybd_event(0x50, 0, KEYEVENTF_KEYUP, 0);
// BookxNote Pro: press P to change to the pan tool
// There's no lasso for BookxNote Pro like others
// Actuall BookxNote Pro's lasso is a pen
}else if(strcmp("Whiteboard",token_result)==0){
keybd_event(0xA4, 0x38, 0, 0);
// ALT
keybd_event(0x51, 0x10, 0, 0);
// Q
keybd_event(0xA4, 0xB8, KEYEVENTF_KEYUP, 0);
keybd_event(0x51, 0x90, KEYEVENTF_KEYUP, 0);
// Microsoft Whiteboard : press ALT+Q to change to the lasso tool
}else{
exit(0);
}
}
return 0;
}
3.4. 选择
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
void click_point_and_return(int x_loc, int y_loc){
POINT pt;
GetCursorPos(&pt);
// remember the mouse location now
mouse_event(
MOUSEEVENTF_ABSOLUTE
// use absolute coordinates
|MOUSEEVENTF_MOVE
|MOUSEEVENTF_LEFTUP
|MOUSEEVENTF_LEFTDOWN
,65536 * (x_loc + 1)/1920
,65536 * (y_loc + 1)/1080
// here we use snipaste to get the coordinates
// due to snipaste locate point at 1920*1080
// but mouse_event at 65536*65536
// so it needs to be normalized
,0
,0
);
// left click at (280,90) means black pen
SetCursorPos(pt.x,pt.y);
// return to original position
}
int main() {
HWND foreground = GetForegroundWindow();
// get the handle of current window
if (foreground)
{
char window_title[256];
GetWindowText(foreground, window_title, 256);
// get correspond tittle
char delim[] = " ";
// use space to split the tittle text
char *token_iter = NULL;
// store the split piece
char *token_result = NULL;
// store the last piece of split result and often is software name
for(
token_iter = strtok(window_title, delim);
token_iter != NULL;
token_iter = strtok(NULL, delim)
){
token_result = token_iter;
}
// MessageBox(NULL,token_result,NULL, MB_OK );
// char concat_result[32];
// sprintf(concat_result, "TT%sTT", token_result);
// MessageBox(NULL,correspond,NULL, MB_OK );
if(strcmp("OneNote",token_result)==0){
click_point_and_return(125,90);
// Onenote: click to change to the select tool
}
else if(strcmp("PDF",token_result)==0){
keybd_event(VK_SPACE, 0, 0, 0);
keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
// Drawboard PDF: press space to change to the pan tool
}else if(strcmp("Xodo",token_result)==0){
keybd_event(0x50, 0, 0, 0);
keybd_event(0x50, 0, KEYEVENTF_KEYUP, 0);
// PDF reader by Xodo: press P to change to the pan tool
}else if(strcmp("Pro",token_result)==0){
keybd_event(0x50, 0, 0, 0);
keybd_event(0x50, 0, KEYEVENTF_KEYUP, 0);
// BookxNote Pro: press P to change to the pan tool
}else if(strcmp("Whiteboard",token_result)==0){
keybd_event(0xA4, 0x38, 0, 0);
// ALT
keybd_event(0x53, 0x1F, 0, 0);
// S
// MessageBox(NULL,token_result,NULL, MB_OK );
keybd_event(0x53, 0x1F, KEYEVENTF_KEYUP, 0);
keybd_event(0xA4, 0xB8, KEYEVENTF_KEYUP, 0);
// Microsoft Whiteboard : press ALT+S to change to the pan tool
}else{
exit(0);
}
}
return 0;
}
3.5. 编译
windres pen.rc -o pen.o
windres eraser.rc -o eraser.o
windres lasso.rc -o lasso.o
windres select.rc -o select.o
gcc -mwindows pen.c pen.o -o pen.exe
gcc -mwindows eraser.c eraser.o -o eraser.exe
gcc -mwindows select.c select.o -o select.exe
(gcc -mwindows -Wall try.c -o try) -and (./try.exe)
gcc -mwindows pen_2.c pen.o -o D:\\Software\\Tools\\pen.exe
gcc -mwindows eraser_2.c eraser.o -o D:\\Software\\Tools\\eraser.exe
gcc -mwindows select_2.c select.o -o D:\\Software\\Tools\\select.exe
gcc -mwindows lasso_2.c lasso.o -o D:\\Software\\Tools\\lasso.exe