-
-
Save jordansissel/1e08b1c65157bde0f30a87c4fb569237 to your computer and use it in GitHub Desktop.
go lang keyboard capture
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"syscall" | |
//~ "time" | |
"unsafe" | |
"golang.org/x/sys/windows" | |
) | |
// String returns a human-friendly display name of the hotkey | |
// such as "Hotkey[Id: 1, Alt+Ctrl+O]" | |
var ( | |
user32 = windows.NewLazySystemDLL("user32.dll") | |
procSetWindowsHookEx = user32.NewProc("SetWindowsHookEx") | |
procLowLevelKeyboard = user32.NewProc("LowLevelKeyboardProc") | |
procCallNextHookEx = user32.NewProc("CallNextHookEx") | |
procUnhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx") | |
procGetMessage = user32.NewProc("GetMessageW") | |
procTranslateMessage = user32.NewProc("TranslateMessage") | |
procDispatchMessage = user32.NewProc("DispatchMessageW") | |
keyboardHook HHOOK | |
) | |
const ( | |
WH_KEYBOARD_LL = 13 | |
WH_KEYBOARD = 2 | |
WM_KEYDOWN = 256 | |
WM_SYSKEYDOWN = 260 | |
WM_KEYUP = 257 | |
WM_SYSKEYUP = 261 | |
WM_KEYFIRST = 256 | |
WM_KEYLAST = 264 | |
PM_NOREMOVE = 0x000 | |
PM_REMOVE = 0x001 | |
PM_NOYIELD = 0x002 | |
WM_LBUTTONDOWN = 513 | |
WM_RBUTTONDOWN = 516 | |
NULL = 0 | |
) | |
type ( | |
DWORD uint32 | |
WPARAM uintptr | |
LPARAM uintptr | |
LRESULT uintptr | |
HANDLE uintptr | |
HINSTANCE HANDLE | |
HHOOK HANDLE | |
HWND HANDLE | |
) | |
type HOOKPROC func(int, WPARAM, LPARAM) LRESULT | |
type KBDLLHOOKSTRUCT struct { | |
VkCode DWORD | |
ScanCode DWORD | |
Flags DWORD | |
Time DWORD | |
DwExtraInfo uintptr | |
} | |
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx | |
type POINT struct { | |
X, Y int32 | |
} | |
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx | |
type MSG struct { | |
Hwnd HWND | |
Message uint32 | |
WParam uintptr | |
LParam uintptr | |
Time uint32 | |
Pt POINT | |
} | |
func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK { | |
ret, _, _ := procSetWindowsHookEx.Call( | |
uintptr(idHook), | |
uintptr(syscall.NewCallback(lpfn)), | |
uintptr(hMod), | |
uintptr(dwThreadId), | |
) | |
return HHOOK(ret) | |
} | |
func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT { | |
ret, _, _ := procCallNextHookEx.Call( | |
uintptr(hhk), | |
uintptr(nCode), | |
uintptr(wParam), | |
uintptr(lParam), | |
) | |
return LRESULT(ret) | |
} | |
func UnhookWindowsHookEx(hhk HHOOK) bool { | |
ret, _, _ := procUnhookWindowsHookEx.Call( | |
uintptr(hhk), | |
) | |
return ret != 0 | |
} | |
func GetMessage(msg *MSG, hwnd HWND, msgFilterMin uint32, msgFilterMax uint32) int { | |
ret, _, _ := procGetMessage.Call( | |
uintptr(unsafe.Pointer(msg)), | |
uintptr(hwnd), | |
uintptr(msgFilterMin), | |
uintptr(msgFilterMax)) | |
return int(ret) | |
} | |
func TranslateMessage(msg *MSG) bool { | |
ret, _, _ := procTranslateMessage.Call( | |
uintptr(unsafe.Pointer(msg))) | |
return ret != 0 | |
} | |
func DispatchMessage(msg *MSG) uintptr { | |
ret, _, _ := procDispatchMessage.Call( | |
uintptr(unsafe.Pointer(msg))) | |
return ret | |
} | |
func LowLevelKeyboardProc (nCode int, wParam WPARAM, lParam LPARAM) LRESULT { | |
ret, _, _ := procLowLevelKeyboard.Call( | |
uintptr(nCode), | |
uintptr(wParam), | |
uintptr(lParam), | |
) | |
return LRESULT(ret) | |
} | |
func Start() { | |
// defer user32.Release() | |
keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, | |
(HOOKPROC)(func(nCode int, wparam WPARAM, lparam LPARAM) LRESULT { | |
if nCode == 0 && wparam == WM_KEYDOWN { | |
fmt.Println("key pressed:") | |
kbdstruct := (*KBDLLHOOKSTRUCT)(unsafe.Pointer(lparam)) | |
code := byte(kbdstruct.VkCode) | |
fmt.Sprintf("%q", code) | |
} | |
return CallNextHookEx(keyboardHook, nCode, wparam, lparam) | |
}), 0, 0) | |
var msg MSG | |
for GetMessage(&msg, 0, 0, 0) != 0 { | |
} | |
//~ for { | |
//~ | |
//~ GetMessage(uintptr(unsafe.Pointer(msg)), 0, 0, 0) | |
//~ TranslateMessage(msg) | |
//~ DispatchMessage(msg) | |
//~ // fmt.Println("key pressed:") | |
//~ | |
//~ } | |
UnhookWindowsHookEx(keyboardHook) | |
keyboardHook = 0 | |
} | |
func main() { | |
go Start() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment