誰かがGo(golang)でクロスプラットフォーム(Mac、Linux、Windows)のグローバルホットキーを作成したいとします。OSの任意の場所でホットキーの組み合わせを押して、ターミナルで何かが印刷されたとしましょう。
現在(2016年7月)それを行うライブラリが見つからないので、一緒に方法を見つけることができるかもしれません。
もちろん、OSごとにいくつかのネイティブOSバインディングを呼び出す必要がありますが、その方法に関する情報は非常にまばらです。
グーグルから判断すると、addGlobalMonitorForEventsMatchingMask
を使用する必要があります
編集:役に立たない例が削除されました
容疑者はXGrabKey
のようですが、近くにサンプルコードはありません https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+XGrabKey&type=リポジトリ&ref =検索結果
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ページをホストするWebサーバーが起動し、_http://localhost:6060/pkg/syscall/
_に移動します。
ここでは、純粋なGoで実行可能な完全なWindowsソリューションを紹介します。完全なサンプルアプリケーションは、 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)
}
_
ウィンドウ_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, ModAlt + ModCtrl, '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)), 0, 0, 0, 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...
_
それはできます。たとえば、ゲームエンジンAzul3dはそれを行うことができます https://github.com/azul3d/engine/tree/master/keyboard 。 AppDelegate.hファイルがないため、OSXスニペットはコンパイルされません。手作業で作成するか、最初に簿記を行うXCodeを使用してプロジェクトをコンパイルしてから、AppDelegate.hとAppDelegate.mを確認することができます。 Linuxでキーストロークストリームをログに記録するには、ここで実行される/ dev/input/event $ IDファイルを読み取ることができます https://github.com/MarinX/keylogger 。 Windowsでは、このコードのようないくつかのシステムコールが必要になります https://github.com/eiannone/keyboard 。 nixとwinの両方で、cgoは必要なく、syscallと純粋なGoに満足できます。