最近一直在研究golang下监听键盘和鼠标的操作事件功能, github上有也有非常优秀的开源库robotgo, 它地址如下, 有兴趣的同学可以去研究下:
/go-vgo/robotgo
但是目前它的键盘事件是阻塞的, 比如github上展示的一个例子
package mainimport ("fmt""/go-vgo/robotgo")func main() {ok := robotgo.AddEvents("q", "ctrl", "shift")if ok {fmt.Println("add events...")}keve := robotgo.AddEvent("k")if keve {fmt.Println("you press... ", "k")}mleft := robotgo.AddEvent("mleft")if mleft {fmt.Println("you press... ", "mouse left button")}}
这段代码的功能很简单, 就是三个事件:
a) ctrl + shift + q组合事件
b) k键点击事件
c) 鼠标左键点击事件
但在使用这段代码的过程中, 程序阻塞在了第一个监听事件, 你先按k键是监听不到的, 只能先按ctrl + shift + q组合键, 再按k键, 最后按鼠标左键, 程序退出.
而目前我使用的场景是在一个循环中轮询监听键盘的事件, 不能阻塞. 所以我根据win c/c++中的键盘和鼠标异步监听事件的代码, 改写到golang里, 同样也非常感谢无私的同学把自己的见解发到网上, 给我了启发. 下面就是项目部分:
1, 代码目录结构如下:
2, windevice.h-头文件函数声明如下:
#ifndef WINDEVICE_H_#define WINDEVICE_H_#include <stdbool.h>#ifdef __cplusplusextern "C" {#endif// 键按下或者抬起// 1-处于按下状态// 0-处于抬起状态int keyDownUp(int e);// 设置屏幕坐标bool setCursorPos(int x, int y);// 鼠标事件void mouseEvent(int dwFlags, int dx, int dy, int dwData, long long dwExtraInfo);#ifdef __cplusplus}#endif#endif // WINDEVICE_H_
3, windevice.c-源文件代码如下:
#include <windows.h>#include "windevice.h"int keyDownUp(int e){return (GetAsyncKeyState(e) & 0x8000) ? 1:0;}bool setCursorPos(int x, int y){return SetCursorPos(x, y);}void mouseEvent(int dwFlags, int dx, int dy, int dwData, long long dwExtraInfo){mouse_event(dwFlags, dx, dy, dwData, dwExtraInfo);}
4, golang的windev包宏定义macro.go就不展示了, 里面的宏定义是支持的事件, 来自winuser.h头文件, 并增加了自己的宏定义.
5, golang的windev包代码实现windev.go如下:
package windev/*#cgo CFLAGS: -I./cdep#cgo LDFLAGS: -L./lib -lwindevice#include "windevice.h"*/import "C"// KeyDownUp ..func KeyDownUp(e int) C.int{return C.keyDownUp(C.int(e))}// SetCursorPos ..func SetCursorPos(x, y int) C.bool{return C.setCursorPos(C.int(x), C.int(y))}// MouseEvent ..func MouseEvent(dwFlags, dx, dy, dwData int, dwExtraInfo int64) {C.mouseEvent(C.int(dwFlags), C.int(dx), C.int(dy), C.int(dwData), C.longlong(dwExtraInfo))}
我自己把windevice.h/c编译了一个静态库, 放在了lib下, 可以在windev.go里直接使用
golang测试代码如下:
package mainimport ("fmt""os""time""/cppdebug/windev")func main() {for i := 0; i < 10; i++ {// 按Q键退出if windev.KeyDownUp(windev.VK_CHARQ) == 1 {fmt.Println("exit")os.Exit(-1)}// 设置鼠标的位置if windev.SetCursorPos(910, 300) {fmt.Println("set pos")}// 鼠标的滑轮事件, 页面向下滑动windev.MouseEvent(windev.MOUSEEVENTF_WHEEL, 0, 0, -100, 0)// 鼠标左键按下和松开事件windev.MouseEvent(windev.MOUSEEVENTF_LEFTDOWN|windev.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)time.Sleep(time.Second)}}
最后, 我把代码上传到github, 以下是地址:
/cppdebug/windev
欢迎各位大牛指点