目前,(2016年7月)我没有找到任何图书馆去做,所以也许我们可以一起找到一个方法.
当然,这将涉及对每个操作系统的一些本地操作系统绑定的调用,但是关于如何执行此操作的信息非常少.
苹果电脑
从谷歌来看,应该使用addGlobalMonitorForEventsMatchingMask
编辑:无用的示例删除
Linux的
看起来像嫌疑人是XGrabKey,但是,在近距离https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+XGrabKey&type=Repositories&ref=searchresults的任何地方都没有示例代码
视窗
似乎我们需要使用RegisterHotKey,但试图找到一些无法找到的示例代码:https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+RegisterHotKey
一些有趣的跨平台研究项目(Java)是https://github.com/tulskiy/jkeymaster
任何帮助将不胜感激!
syscall
进行系统调用,无需任何额外的C代码或cgo编译器.
请注意,syscall软件包的在线官方文档仅显示linux接口.其他操作系统具有稍微不同的界面,例如在Windows上,syscall软件包还包含一个syscall.DLL类型,syscall.LoadDLL()和syscall.MustLoadDLL()函数等.要查看这些,请在本地运行godoc工具,例如
- godoc -http=:6060
这将启动一个托管类似godoc.org的网页的Web服务器,导航到http:// localhost:6060 / pkg / syscall /.
在这里,我提供一个完整的,可运行的Windows解决方案,在纯Go.完整的示例应用程序在Go Playground上可用.它不在操场上运行,下载并在本地运行(在Windows上).
我们定义类型来描述我们想要使用的热键.这不是Windows特定的,只是为了使我们的代码更好. Hotkey.String()方法提供热键的人性化显示名称,例如“Hotkey [Id:1,Alt Ctrl O]”.
- const (
- ModAlt = 1 << iota
- ModCtrl
- ModShift
- ModWin
- )
- type Hotkey struct {
- Id int // Unique id
- Modifiers int // Mask of modifiers
- KeyCode int // Key code,e.g. 'A'
- }
- // String returns a human-friendly display name of the hotkey
- // such as "Hotkey[Id: 1,Alt+Ctrl+O]"
- func (h *Hotkey) String() string {
- mod := &bytes.Buffer{}
- if h.Modifiers&ModAlt != 0 {
- mod.WriteString("Alt+")
- }
- if h.Modifiers&ModCtrl != 0 {
- mod.WriteString("Ctrl+")
- }
- if h.Modifiers&ModShift != 0 {
- mod.WriteString("Shift+")
- }
- if h.Modifiers&ModWin != 0 {
- mod.WriteString("Win+")
- }
- return fmt.Sprintf("Hotkey[Id: %d,%s%c]",h.Id,mod,h.KeyCode)
- }
windows user32.dll包含全局热键管理功能.我们加载它:
- user32 := syscall.MustLoadDLL("user32")
- defer user32.Release()
它具有RegisterHotkey()
注册全局热键的功能:
- reghotkey := user32.MustFindProc("RegisterHotKey")
使用它,让我们注册一些热键,即ALT CTRL O,ALT SHIFT M,ALT CTRL X(将用于退出应用程序):
- // Hotkeys to listen to:
- keys := map[int16]*Hotkey{
- 1: &Hotkey{1,ModAlt + ModCtrl,'O'},// ALT+CTRL+O
- 2: &Hotkey{2,ModAlt + ModShift,'M'},// ALT+SHIFT+M
- 3: &Hotkey{3,'X'},// ALT+CTRL+X
- }
- // Register hotkeys:
- for _,v := range keys {
- r1,_,err := reghotkey.Call(
- 0,uintptr(v.Id),uintptr(v.Modifiers),uintptr(v.KeyCode))
- if r1 == 1 {
- fmt.Println("Registered",v)
- } else {
- fmt.Println("Failed to register",v,",error:",err)
- }
- }
我们需要一种方法来“听”按压这些热键的事件.为此,user32.dll包含PeekMessage()
功能:
- peekmsg := user32.MustFindProc("PeekMessageW")
PeekMessage()将消息存储到MSG
结构体中,我们来定义它:
- type MSG struct {
- HWND uintptr
- UINT uintptr
- WPARAM int16
- LPARAM int64
- DWORD int32
- POINT struct{ X,Y int64 }
- }
现在这里是我们的听力循环,它监听和操作全局按键(这里只需简单地将按下的热键打印到控制台,如果按住CTRL ALT X则退出应用程序):
- for {
- var msg = &MSG{}
- peekmsg.Call(uintptr(unsafe.Pointer(msg)),1)
- // Registered id is in the WPARAM field:
- if id := msg.WPARAM; id != 0 {
- fmt.Println("Hotkey pressed:",keys[id])
- if id == 3 { // CTRL+ALT+X = Exit
- fmt.Println("CTRL+ALT+X pressed,goodbye...")
- return
- }
- }
- time.Sleep(time.Millisecond * 50)
- }
我们完成了
开始上述应用程序打印:
- Registered Hotkey[Id: 1,Alt+Ctrl+O]
- Registered Hotkey[Id: 2,Alt+Shift+M]
- Registered Hotkey[Id: 3,Alt+Ctrl+X]
现在让我们按一些注册的热键(任何应用程序都在关注,不一定是我们的应用程序),我们将在控制台看到:
- Hotkey pressed: Hotkey[Id: 1,Alt+Ctrl+O]
- Hotkey pressed: Hotkey[Id: 1,Alt+Ctrl+O]
- Hotkey pressed: Hotkey[Id: 2,Alt+Shift+M]
- Hotkey pressed: Hotkey[Id: 3,Alt+Ctrl+X]
- CTRL+ALT+X pressed,goodbye...