-
Notifications
You must be signed in to change notification settings - Fork 1
/
typing_windows.go
100 lines (82 loc) · 2.03 KB
/
typing_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//go:build windows
package main
import (
"log"
"syscall"
"unicode/utf16"
"unsafe"
)
type KEYBDINPUT struct {
Vk uint16
Scan uint16
Flags uint32
Time uint32
ExtraInfo uintptr
}
type INPUT struct {
Type uint32
Ki KEYBDINPUT
Padding [8]byte
}
const (
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002
KEYEVENTF_SCANCODE = 0x0008
KEYEVENTF_UNICODE = 0x0004
MAX_KEYBOARD_LAYOUT = 10
Enter = 0x0D // VK_RETURN
)
type WindowsKeyboard struct {
focusedControl FocusedControl
}
var (
user32DLL = syscall.MustLoadDLL("user32.dll")
kernel32DLL = syscall.MustLoadDLL("kernel32.dll")
)
func NewKeyboard() *WindowsKeyboard {
return &WindowsKeyboard{
focusedControl: GetFocusedControl(),
}
}
func (k *WindowsKeyboard) IsFocusTheSame() bool {
return k.focusedControl.Is(GetFocusedControl())
}
func (k *WindowsKeyboard) utf16FromString(s string) []uint16 {
runes := utf16.Encode([]rune(s))
return append(runes, uint16(0))
}
func (k *WindowsKeyboard) sendInputs(inputs []INPUT) {
user32 := syscall.NewLazyDLL("user32.dll")
sendInput := user32.NewProc("SendInput")
count := uintptr(len(inputs))
size := uintptr(unsafe.Sizeof(inputs[0]))
ret, _, err := sendInput.Call(count, uintptr(unsafe.Pointer(&inputs[0])), size)
if int(ret) == 0 {
log.Println("Sending inputs failed.")
log.Fatal("Error:", err)
}
}
func (k *WindowsKeyboard) sendChar(key uint16) {
inputs := []INPUT{
{Type: INPUT_KEYBOARD, Ki: KEYBDINPUT{Flags: KEYEVENTF_UNICODE, Scan: key}},
{Type: INPUT_KEYBOARD, Ki: KEYBDINPUT{Flags: KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, Scan: key}},
}
k.sendInputs(inputs)
}
func (k *WindowsKeyboard) SendNewLine() {
inputs := []INPUT{
{Type: INPUT_KEYBOARD, Ki: KEYBDINPUT{Vk: Enter}},
{Type: INPUT_KEYBOARD, Ki: KEYBDINPUT{Vk: Enter, Flags: KEYEVENTF_KEYUP}},
}
k.sendInputs(inputs)
}
func (k *WindowsKeyboard) SendString(s string) {
for _, r := range s {
if r == 10 {
k.SendNewLine()
continue
}
k.sendChar(uint16(r))
}
}