在golang中实施全球热键?

前端之家收集整理的这篇文章主要介绍了在golang中实施全球热键?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设有人想在Go(golang)中创建一个跨平台(Mac,Linux,Windows)全球热键 – 您可以在操作系统的任何地方按一个热键组合,并且说出终端中打印的内容.

目前,(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

任何帮助将不胜感激!

大多数操作系统都可以使用简单的系统调用,在Go中,您可以使用软件包 syscall进行系统调用,无需任何额外的C代码或cgo编译器.

请注意,syscall软件包的在线官方文档仅显示linux接口.其他操作系统具有稍微不同的界面,例如在Windows上,syscall软件包还包含一个syscall.DLL类型,syscall.LoadDLL()和syscall.MustLoadDLL()函数等.要查看这些,请在本地运行godoc工具,例如

  1. 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]”.

  1. const (
  2. ModAlt = 1 << iota
  3. ModCtrl
  4. ModShift
  5. ModWin
  6. )
  7.  
  8. type Hotkey struct {
  9. Id int // Unique id
  10. Modifiers int // Mask of modifiers
  11. KeyCode int // Key code,e.g. 'A'
  12. }
  13.  
  14. // String returns a human-friendly display name of the hotkey
  15. // such as "Hotkey[Id: 1,Alt+Ctrl+O]"
  16. func (h *Hotkey) String() string {
  17. mod := &bytes.Buffer{}
  18. if h.Modifiers&ModAlt != 0 {
  19. mod.WriteString("Alt+")
  20. }
  21. if h.Modifiers&ModCtrl != 0 {
  22. mod.WriteString("Ctrl+")
  23. }
  24. if h.Modifiers&ModShift != 0 {
  25. mod.WriteString("Shift+")
  26. }
  27. if h.Modifiers&ModWin != 0 {
  28. mod.WriteString("Win+")
  29. }
  30. return fmt.Sprintf("Hotkey[Id: %d,%s%c]",h.Id,mod,h.KeyCode)
  31. }

windows user32.dll包含全局热键管理功能.我们加载它:

  1. user32 := syscall.MustLoadDLL("user32")
  2. defer user32.Release()

它具有RegisterHotkey()注册全局热键的功能

  1. reghotkey := user32.MustFindProc("RegisterHotKey")

使用它,让我们注册一些热键,即ALT CTRL O,ALT SHIFT M,ALT CTRL X(将用于退出应用程序):

  1. // Hotkeys to listen to:
  2. keys := map[int16]*Hotkey{
  3. 1: &Hotkey{1,ModAlt + ModCtrl,'O'},// ALT+CTRL+O
  4. 2: &Hotkey{2,ModAlt + ModShift,'M'},// ALT+SHIFT+M
  5. 3: &Hotkey{3,'X'},// ALT+CTRL+X
  6. }
  7.  
  8. // Register hotkeys:
  9. for _,v := range keys {
  10. r1,_,err := reghotkey.Call(
  11. 0,uintptr(v.Id),uintptr(v.Modifiers),uintptr(v.KeyCode))
  12. if r1 == 1 {
  13. fmt.Println("Registered",v)
  14. } else {
  15. fmt.Println("Failed to register",v,",error:",err)
  16. }
  17. }

我们需要一种方法来“听”按压这些热键的事件.为此,user32.dll包含PeekMessage()功能

  1. peekmsg := user32.MustFindProc("PeekMessageW")

PeekMessage()将消息存储到MSG结构体中,我们来定义它:

  1. type MSG struct {
  2. HWND uintptr
  3. UINT uintptr
  4. WPARAM int16
  5. LPARAM int64
  6. DWORD int32
  7. POINT struct{ X,Y int64 }
  8. }

现在这里是我们的听力循环,它监听和操作全局按键(这里只需简单地将按下的热键打印到控制台,如果按住CTRL ALT X则退出应用程序):

  1. for {
  2. var msg = &MSG{}
  3. peekmsg.Call(uintptr(unsafe.Pointer(msg)),1)
  4.  
  5. // Registered id is in the WPARAM field:
  6. if id := msg.WPARAM; id != 0 {
  7. fmt.Println("Hotkey pressed:",keys[id])
  8. if id == 3 { // CTRL+ALT+X = Exit
  9. fmt.Println("CTRL+ALT+X pressed,goodbye...")
  10. return
  11. }
  12. }
  13.  
  14. time.Sleep(time.Millisecond * 50)
  15. }

我们完成了

开始上述应用程序打印:

  1. Registered Hotkey[Id: 1,Alt+Ctrl+O]
  2. Registered Hotkey[Id: 2,Alt+Shift+M]
  3. Registered Hotkey[Id: 3,Alt+Ctrl+X]

现在让我们按一些注册的热键(任何应用程序都在关注,不一定是我们的应用程序),我们将在控制台看到:

  1. Hotkey pressed: Hotkey[Id: 1,Alt+Ctrl+O]
  2. Hotkey pressed: Hotkey[Id: 1,Alt+Ctrl+O]
  3. Hotkey pressed: Hotkey[Id: 2,Alt+Shift+M]
  4. Hotkey pressed: Hotkey[Id: 3,Alt+Ctrl+X]
  5. CTRL+ALT+X pressed,goodbye...

猜你在找的Go相关文章