加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

在golang中实施全球热键?

发布时间:2020-12-16 19:22:50 所属栏目:大数据 来源:网络整理
导读:假设有人想在Go(golang)中创建一个跨平台(Mac,Linux,Windows)全球热键 – 您可以在操作系统的任何地方按一个热键组合,并且说出终端中打印的内容. 目前,(2016年7月)我没有找到任何图书馆去做,所以也许我们可以一起找到一个方法. 当然,这将涉及对每个操作系统
假设有人想在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工具,例如

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...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读