package input import ( "runtime" "strings" ) func PressKey(key, action string, modifiers []string) error { vk, ok := vkCode(key) if !ok { return ErrBadKey } runtime.LockOSThread() defer runtime.UnlockOSThread() if err := attachInputDesktop(); err != nil { return err } modVKs := make([]uint16, 0, len(modifiers)) for _, mod := range modifiers { modVK, ok := vkCode(mod) if !ok { return ErrBadKey } modVKs = append(modVKs, modVK) } var inputs []winInput for _, modVK := range modVKs { inputs = append(inputs, keyInput(modVK, false)) } switch strings.ToLower(strings.TrimSpace(action)) { case "down": inputs = append(inputs, keyInput(vk, false)) case "up": inputs = append(inputs, keyInput(vk, true)) default: inputs = append(inputs, keyInput(vk, false), keyInput(vk, true)) for i := len(modVKs) - 1; i >= 0; i-- { inputs = append(inputs, keyInput(modVKs[i], true)) } } return sendKeyboardInputs(inputs) } func keyInput(vk uint16, keyUp bool) winInput { flags := uint32(0) if keyUp { flags |= keyeventfKeyup } if isExtendedVK(vk) { flags |= keyeventfExtended } return winInput{ Type: inputKeyboard, Ki: keyboardData{ Vk: vk, Flags: flags, }, } } func isExtendedVK(vk uint16) bool { switch vk { case 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x2D, 0x2E, 0x5B, 0x5C, 0x5D: return true default: return false } }