(摘) Golang在Windows中定义全局热键

声明:内容源自网络,版权归原作者所有。若有侵权请在网页聊天中联系我
package main

import (
	"flag"
	"fmt"
	"unsafe"

	"golang.org/x/sys/windows"
)

var (
	user32               = windows.NewLazySystemDLL("user32.dll")
	procRegisterHotKey   = user32.NewProc("RegisterHotKey")
	procGetMessage       = user32.NewProc("GetMessageW")
	procTranslateMessage = user32.NewProc("TranslateMessage")
	procDispatchMessage  = user32.NewProc("DispatchMessageW")
)

const (
	MOD_ALT     = 0x0001
	MOD_CONTROL = 0x0002
	MOD_SHIFT   = 0x0004
	MOD_WIN     = 0x0008
	WM_HOTKEY   = 0x0312
)

// MSG represents a Windows message
type MSG struct {
	HWND   uintptr
	UINT   uint32
	WPARAM uintptr
	LPARAM uintptr
	Time   uint32
	Pt     struct{ X, Y int32 }
}

// RegisterHotKey 注册热键
func RegisterHotKey(id int, modifiers uint, vk uint) error {
	ret, _, err := procRegisterHotKey.Call(
		0,
		uintptr(id),
		uintptr(modifiers),
		uintptr(vk),
	)
	if ret == 0 {
		return err
	}
	return nil
}

// StartHotKeyListener 启动热键监听
func StartHotKeyListener() {
	var msg MSG
	for {
		ret, _, _ := procGetMessage.Call(uintptr(unsafe.Pointer(&msg)), 0, 0, 0)

		if ret == 0 {
			break
		}

		if msg.UINT == WM_HOTKEY {
			fmt.Println("热键被触发!")
			// 在这里添加你想要执行的操作
		}

		procTranslateMessage.Call(uintptr(unsafe.Pointer(&msg)))
		procDispatchMessage.Call(uintptr(unsafe.Pointer(&msg)))
	}
}

func main() {
	// 命令行参数
	hotkey := flag.String("hotkey", "Ctrl+Alt+A", "热键组合,例如 Ctrl+Alt+A")
	flag.Parse()

	// 解析热键组合
	var modifiers uint
	var vk uint

	// 解析热键组合
	switch *hotkey {
	case "Ctrl+Alt+A":
		modifiers = MOD_CONTROL | MOD_ALT
		vk = 'A'
	case "Ctrl+Alt+B":
		modifiers = MOD_CONTROL | MOD_ALT
		vk = 'B'
	default:
		fmt.Println("不支持的热键组合:", *hotkey)
		return
	}

	// 注册热键
	err := RegisterHotKey(1, modifiers, vk)
	if err != nil {
		fmt.Println("注册热键失败:", err)
		return
	}

	fmt.Printf("热键 %s 已注册。按下这个组合键来触发事件。\n", *hotkey)

	// 启动热键监听
	StartHotKeyListener()
}

相关文章