最近一直在研究golang下监听键盘和鼠标的操作事件功能, github上有也有非常优秀的开源库robotgo, 它地址如下, 有兴趣的同学可以去研究下:
但是目前它的键盘事件是阻塞的, 比如github上展示的一个例子
package main
import (
"fmt"
"github.com/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 __cplusplus
extern "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 main
import (
"fmt"
"os"
"time"
"github.com/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, 以下是地址:
欢迎各位大牛指点