mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Add accelerator code
This commit is contained in:
parent
5adf8004ac
commit
bd0e3b407a
4 changed files with 852 additions and 8 deletions
|
|
@ -44,6 +44,7 @@ require (
|
|||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
||||
github.com/samber/lo v1.27.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -82,7 +83,6 @@ require (
|
|||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package systray
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/samber/lo"
|
||||
platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu"
|
||||
"github.com/wailsapp/wails/v2/internal/platform/win32"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
|
|
@ -36,12 +38,14 @@ func (r *RadioGroup) MenuID(item *menu.MenuItem) int {
|
|||
}
|
||||
|
||||
type PopupMenu struct {
|
||||
menu win32.PopupMenu
|
||||
parent win32.HWND
|
||||
menuMapping map[int]*menu.MenuItem
|
||||
checkboxItems map[*menu.MenuItem][]int
|
||||
radioGroups map[*menu.MenuItem][]*RadioGroup
|
||||
menuData *menu.Menu
|
||||
menu win32.PopupMenu
|
||||
parent win32.HWND
|
||||
menuMapping map[int]*menu.MenuItem
|
||||
checkboxItems map[*menu.MenuItem][]int
|
||||
radioGroups map[*menu.MenuItem][]*RadioGroup
|
||||
menuData *menu.Menu
|
||||
shortcuts map[*menu.MenuItem]win32.Accelerator
|
||||
acceleratorTable uintptr
|
||||
}
|
||||
|
||||
func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error {
|
||||
|
|
@ -93,7 +97,20 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu,
|
|||
itemID = int(submenu)
|
||||
}
|
||||
|
||||
ret = parentMenu.Append(uintptr(flags), uintptr(itemID), item.Label)
|
||||
var menuText = item.Label
|
||||
if item.Accelerator != nil {
|
||||
shortcut := win32.AcceleratorToShortcut(item.Accelerator)
|
||||
menuText = fmt.Sprintf("%s\t%s", menuText, shortcut)
|
||||
if _, exists := p.shortcuts[item]; !exists {
|
||||
p.shortcuts[item] = win32.Accelerator{
|
||||
Virtual: byte(shortcut.Modifiers),
|
||||
Key: uint16(shortcut.Key),
|
||||
Cmd: uint16(itemID),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = parentMenu.Append(uintptr(flags), uintptr(itemID), menuText)
|
||||
if ret == false {
|
||||
return errors.New("AppendMenu failed")
|
||||
}
|
||||
|
|
@ -108,6 +125,7 @@ func (p *PopupMenu) Update() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.updateAccelerators()
|
||||
p.updateRadioGroups()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -118,6 +136,7 @@ func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) {
|
|||
menuData: inputMenu,
|
||||
checkboxItems: make(map[*menu.MenuItem][]int),
|
||||
radioGroups: make(map[*menu.MenuItem][]*RadioGroup),
|
||||
shortcuts: make(map[*menu.MenuItem]win32.Accelerator),
|
||||
}
|
||||
err := result.Update()
|
||||
platformMenu.MenuManager.AddMenu(inputMenu, result.UpdateMenuItem)
|
||||
|
|
@ -181,3 +200,7 @@ func (p *PopupMenu) updateRadioGroup(item *menu.MenuItem) {
|
|||
p.menu.CheckRadio(startID, endID, thisMenuID)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PopupMenu) updateAccelerators() {
|
||||
p.acceleratorTable = win32.CreateAcceleratorTable(lo.Values(p.shortcuts))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ var (
|
|||
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
|
||||
procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW")
|
||||
procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute")
|
||||
procGetKeyState = moduser32.NewProc("GetKeyState")
|
||||
procCreateAcceleratorTable = moduser32.NewProc("CreateAcceleratorTableW")
|
||||
procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW")
|
||||
|
||||
modshell32 = syscall.NewLazyDLL("shell32.dll")
|
||||
procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW")
|
||||
|
|
@ -125,6 +128,11 @@ const (
|
|||
WM_USER = 0x0400
|
||||
WM_TRAYICON = WM_USER + 69
|
||||
WM_SETTINGCHANGE = 0x001A
|
||||
WM_KEYDOWN = 256
|
||||
WM_KEYUP = 257
|
||||
WM_SYSKEYDOWN = 260
|
||||
WM_SYSKEYUP = 261
|
||||
WM_MENUCHAR = 288
|
||||
|
||||
WS_EX_APPWINDOW = 0x00040000
|
||||
WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000
|
||||
|
|
@ -173,6 +181,7 @@ const (
|
|||
IDI_APPLICATION = 32512
|
||||
WM_APP = 32768
|
||||
WM_COMMAND = 273
|
||||
WM_SYSCOMMAND = 274
|
||||
|
||||
MenuItemMsgID = WM_APP + 1024
|
||||
NotifyIconMessageId = WM_APP + iota
|
||||
|
|
@ -248,3 +257,7 @@ func DispatchMessage(msg *MSG) uintptr {
|
|||
func PostQuitMessage(exitCode int32) {
|
||||
procPostQuitMessage.Call(uintptr(exitCode))
|
||||
}
|
||||
|
||||
func LoHiWords(input uint32) (uint16, uint16) {
|
||||
return uint16(input & 0xffff), uint16(input >> 16 & 0xffff)
|
||||
}
|
||||
|
|
|
|||
808
v2/internal/platform/win32/keyboard.go
Normal file
808
v2/internal/platform/win32/keyboard.go
Normal file
|
|
@ -0,0 +1,808 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
|
||||
* Copyright (C) 2010-2013 Allen Dang. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package win32
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu/keys"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Key uint16
|
||||
|
||||
func (k Key) String() string {
|
||||
return key2string[k]
|
||||
}
|
||||
|
||||
// Virtual key codes
|
||||
const (
|
||||
VK_LBUTTON = 1
|
||||
VK_RBUTTON = 2
|
||||
VK_CANCEL = 3
|
||||
VK_MBUTTON = 4
|
||||
VK_XBUTTON1 = 5
|
||||
VK_XBUTTON2 = 6
|
||||
VK_BACK = 8
|
||||
VK_TAB = 9
|
||||
VK_CLEAR = 12
|
||||
VK_RETURN = 13
|
||||
VK_SHIFT = 16
|
||||
VK_CONTROL = 17
|
||||
VK_MENU = 18
|
||||
VK_PAUSE = 19
|
||||
VK_CAPITAL = 20
|
||||
VK_KANA = 0x15
|
||||
VK_HANGEUL = 0x15
|
||||
VK_HANGUL = 0x15
|
||||
VK_JUNJA = 0x17
|
||||
VK_FINAL = 0x18
|
||||
VK_HANJA = 0x19
|
||||
VK_KANJI = 0x19
|
||||
VK_ESCAPE = 0x1B
|
||||
VK_CONVERT = 0x1C
|
||||
VK_NONCONVERT = 0x1D
|
||||
VK_ACCEPT = 0x1E
|
||||
VK_MODECHANGE = 0x1F
|
||||
VK_SPACE = 32
|
||||
VK_PRIOR = 33
|
||||
VK_NEXT = 34
|
||||
VK_END = 35
|
||||
VK_HOME = 36
|
||||
VK_LEFT = 37
|
||||
VK_UP = 38
|
||||
VK_RIGHT = 39
|
||||
VK_DOWN = 40
|
||||
VK_SELECT = 41
|
||||
VK_PRINT = 42
|
||||
VK_EXECUTE = 43
|
||||
VK_SNAPSHOT = 44
|
||||
VK_INSERT = 45
|
||||
VK_DELETE = 46
|
||||
VK_HELP = 47
|
||||
VK_LWIN = 0x5B
|
||||
VK_RWIN = 0x5C
|
||||
VK_APPS = 0x5D
|
||||
VK_SLEEP = 0x5F
|
||||
VK_NUMPAD0 = 0x60
|
||||
VK_NUMPAD1 = 0x61
|
||||
VK_NUMPAD2 = 0x62
|
||||
VK_NUMPAD3 = 0x63
|
||||
VK_NUMPAD4 = 0x64
|
||||
VK_NUMPAD5 = 0x65
|
||||
VK_NUMPAD6 = 0x66
|
||||
VK_NUMPAD7 = 0x67
|
||||
VK_NUMPAD8 = 0x68
|
||||
VK_NUMPAD9 = 0x69
|
||||
VK_MULTIPLY = 0x6A
|
||||
VK_ADD = 0x6B
|
||||
VK_SEPARATOR = 0x6C
|
||||
VK_SUBTRACT = 0x6D
|
||||
VK_DECIMAL = 0x6E
|
||||
VK_DIVIDE = 0x6F
|
||||
VK_F1 = 0x70
|
||||
VK_F2 = 0x71
|
||||
VK_F3 = 0x72
|
||||
VK_F4 = 0x73
|
||||
VK_F5 = 0x74
|
||||
VK_F6 = 0x75
|
||||
VK_F7 = 0x76
|
||||
VK_F8 = 0x77
|
||||
VK_F9 = 0x78
|
||||
VK_F10 = 0x79
|
||||
VK_F11 = 0x7A
|
||||
VK_F12 = 0x7B
|
||||
VK_F13 = 0x7C
|
||||
VK_F14 = 0x7D
|
||||
VK_F15 = 0x7E
|
||||
VK_F16 = 0x7F
|
||||
VK_F17 = 0x80
|
||||
VK_F18 = 0x81
|
||||
VK_F19 = 0x82
|
||||
VK_F20 = 0x83
|
||||
VK_F21 = 0x84
|
||||
VK_F22 = 0x85
|
||||
VK_F23 = 0x86
|
||||
VK_F24 = 0x87
|
||||
VK_NUMLOCK = 0x90
|
||||
VK_SCROLL = 0x91
|
||||
VK_LSHIFT = 0xA0
|
||||
VK_RSHIFT = 0xA1
|
||||
VK_LCONTROL = 0xA2
|
||||
VK_RCONTROL = 0xA3
|
||||
VK_LMENU = 0xA4
|
||||
VK_RMENU = 0xA5
|
||||
VK_BROWSER_BACK = 0xA6
|
||||
VK_BROWSER_FORWARD = 0xA7
|
||||
VK_BROWSER_REFRESH = 0xA8
|
||||
VK_BROWSER_STOP = 0xA9
|
||||
VK_BROWSER_SEARCH = 0xAA
|
||||
VK_BROWSER_FAVORITES = 0xAB
|
||||
VK_BROWSER_HOME = 0xAC
|
||||
VK_VOLUME_MUTE = 0xAD
|
||||
VK_VOLUME_DOWN = 0xAE
|
||||
VK_VOLUME_UP = 0xAF
|
||||
VK_MEDIA_NEXT_TRACK = 0xB0
|
||||
VK_MEDIA_PREV_TRACK = 0xB1
|
||||
VK_MEDIA_STOP = 0xB2
|
||||
VK_MEDIA_PLAY_PAUSE = 0xB3
|
||||
VK_LAUNCH_MAIL = 0xB4
|
||||
VK_LAUNCH_MEDIA_SELECT = 0xB5
|
||||
VK_LAUNCH_APP1 = 0xB6
|
||||
VK_LAUNCH_APP2 = 0xB7
|
||||
VK_OEM_1 = 0xBA
|
||||
VK_OEM_PLUS = 0xBB
|
||||
VK_OEM_COMMA = 0xBC
|
||||
VK_OEM_MINUS = 0xBD
|
||||
VK_OEM_PERIOD = 0xBE
|
||||
VK_OEM_2 = 0xBF
|
||||
VK_OEM_3 = 0xC0
|
||||
VK_OEM_4 = 0xDB
|
||||
VK_OEM_5 = 0xDC
|
||||
VK_OEM_6 = 0xDD
|
||||
VK_OEM_7 = 0xDE
|
||||
VK_OEM_8 = 0xDF
|
||||
VK_OEM_102 = 0xE2
|
||||
VK_PROCESSKEY = 0xE5
|
||||
VK_PACKET = 0xE7
|
||||
VK_ATTN = 0xF6
|
||||
VK_CRSEL = 0xF7
|
||||
VK_EXSEL = 0xF8
|
||||
VK_EREOF = 0xF9
|
||||
VK_PLAY = 0xFA
|
||||
VK_ZOOM = 0xFB
|
||||
VK_NONAME = 0xFC
|
||||
VK_PA1 = 0xFD
|
||||
VK_OEM_CLEAR = 0xFE
|
||||
)
|
||||
|
||||
const (
|
||||
KeyLButton Key = VK_LBUTTON
|
||||
KeyRButton Key = VK_RBUTTON
|
||||
KeyCancel Key = VK_CANCEL
|
||||
KeyMButton Key = VK_MBUTTON
|
||||
KeyXButton1 Key = VK_XBUTTON1
|
||||
KeyXButton2 Key = VK_XBUTTON2
|
||||
KeyBack Key = VK_BACK
|
||||
KeyTab Key = VK_TAB
|
||||
KeyClear Key = VK_CLEAR
|
||||
KeyReturn Key = VK_RETURN
|
||||
KeyShift Key = VK_SHIFT
|
||||
KeyControl Key = VK_CONTROL
|
||||
KeyAlt Key = VK_MENU
|
||||
KeyMenu Key = VK_MENU
|
||||
KeyPause Key = VK_PAUSE
|
||||
KeyCapital Key = VK_CAPITAL
|
||||
KeyKana Key = VK_KANA
|
||||
KeyHangul Key = VK_HANGUL
|
||||
KeyJunja Key = VK_JUNJA
|
||||
KeyFinal Key = VK_FINAL
|
||||
KeyHanja Key = VK_HANJA
|
||||
KeyKanji Key = VK_KANJI
|
||||
KeyEscape Key = VK_ESCAPE
|
||||
KeyConvert Key = VK_CONVERT
|
||||
KeyNonconvert Key = VK_NONCONVERT
|
||||
KeyAccept Key = VK_ACCEPT
|
||||
KeyModeChange Key = VK_MODECHANGE
|
||||
KeySpace Key = VK_SPACE
|
||||
KeyPrior Key = VK_PRIOR
|
||||
KeyNext Key = VK_NEXT
|
||||
KeyEnd Key = VK_END
|
||||
KeyHome Key = VK_HOME
|
||||
KeyLeft Key = VK_LEFT
|
||||
KeyUp Key = VK_UP
|
||||
KeyRight Key = VK_RIGHT
|
||||
KeyDown Key = VK_DOWN
|
||||
KeySelect Key = VK_SELECT
|
||||
KeyPrint Key = VK_PRINT
|
||||
KeyExecute Key = VK_EXECUTE
|
||||
KeySnapshot Key = VK_SNAPSHOT
|
||||
KeyInsert Key = VK_INSERT
|
||||
KeyDelete Key = VK_DELETE
|
||||
KeyHelp Key = VK_HELP
|
||||
Key0 Key = 0x30
|
||||
Key1 Key = 0x31
|
||||
Key2 Key = 0x32
|
||||
Key3 Key = 0x33
|
||||
Key4 Key = 0x34
|
||||
Key5 Key = 0x35
|
||||
Key6 Key = 0x36
|
||||
Key7 Key = 0x37
|
||||
Key8 Key = 0x38
|
||||
Key9 Key = 0x39
|
||||
KeyA Key = 0x41
|
||||
KeyB Key = 0x42
|
||||
KeyC Key = 0x43
|
||||
KeyD Key = 0x44
|
||||
KeyE Key = 0x45
|
||||
KeyF Key = 0x46
|
||||
KeyG Key = 0x47
|
||||
KeyH Key = 0x48
|
||||
KeyI Key = 0x49
|
||||
KeyJ Key = 0x4A
|
||||
KeyK Key = 0x4B
|
||||
KeyL Key = 0x4C
|
||||
KeyM Key = 0x4D
|
||||
KeyN Key = 0x4E
|
||||
KeyO Key = 0x4F
|
||||
KeyP Key = 0x50
|
||||
KeyQ Key = 0x51
|
||||
KeyR Key = 0x52
|
||||
KeyS Key = 0x53
|
||||
KeyT Key = 0x54
|
||||
KeyU Key = 0x55
|
||||
KeyV Key = 0x56
|
||||
KeyW Key = 0x57
|
||||
KeyX Key = 0x58
|
||||
KeyY Key = 0x59
|
||||
KeyZ Key = 0x5A
|
||||
KeyLWIN Key = VK_LWIN
|
||||
KeyRWIN Key = VK_RWIN
|
||||
KeyApps Key = VK_APPS
|
||||
KeySleep Key = VK_SLEEP
|
||||
KeyNumpad0 Key = VK_NUMPAD0
|
||||
KeyNumpad1 Key = VK_NUMPAD1
|
||||
KeyNumpad2 Key = VK_NUMPAD2
|
||||
KeyNumpad3 Key = VK_NUMPAD3
|
||||
KeyNumpad4 Key = VK_NUMPAD4
|
||||
KeyNumpad5 Key = VK_NUMPAD5
|
||||
KeyNumpad6 Key = VK_NUMPAD6
|
||||
KeyNumpad7 Key = VK_NUMPAD7
|
||||
KeyNumpad8 Key = VK_NUMPAD8
|
||||
KeyNumpad9 Key = VK_NUMPAD9
|
||||
KeyMultiply Key = VK_MULTIPLY
|
||||
KeyAdd Key = VK_ADD
|
||||
KeySeparator Key = VK_SEPARATOR
|
||||
KeySubtract Key = VK_SUBTRACT
|
||||
KeyDecimal Key = VK_DECIMAL
|
||||
KeyDivide Key = VK_DIVIDE
|
||||
KeyF1 Key = VK_F1
|
||||
KeyF2 Key = VK_F2
|
||||
KeyF3 Key = VK_F3
|
||||
KeyF4 Key = VK_F4
|
||||
KeyF5 Key = VK_F5
|
||||
KeyF6 Key = VK_F6
|
||||
KeyF7 Key = VK_F7
|
||||
KeyF8 Key = VK_F8
|
||||
KeyF9 Key = VK_F9
|
||||
KeyF10 Key = VK_F10
|
||||
KeyF11 Key = VK_F11
|
||||
KeyF12 Key = VK_F12
|
||||
KeyF13 Key = VK_F13
|
||||
KeyF14 Key = VK_F14
|
||||
KeyF15 Key = VK_F15
|
||||
KeyF16 Key = VK_F16
|
||||
KeyF17 Key = VK_F17
|
||||
KeyF18 Key = VK_F18
|
||||
KeyF19 Key = VK_F19
|
||||
KeyF20 Key = VK_F20
|
||||
KeyF21 Key = VK_F21
|
||||
KeyF22 Key = VK_F22
|
||||
KeyF23 Key = VK_F23
|
||||
KeyF24 Key = VK_F24
|
||||
KeyNumlock Key = VK_NUMLOCK
|
||||
KeyScroll Key = VK_SCROLL
|
||||
KeyLShift Key = VK_LSHIFT
|
||||
KeyRShift Key = VK_RSHIFT
|
||||
KeyLControl Key = VK_LCONTROL
|
||||
KeyRControl Key = VK_RCONTROL
|
||||
KeyLAlt Key = VK_LMENU
|
||||
KeyLMenu Key = VK_LMENU
|
||||
KeyRAlt Key = VK_RMENU
|
||||
KeyRMenu Key = VK_RMENU
|
||||
KeyBrowserBack Key = VK_BROWSER_BACK
|
||||
KeyBrowserForward Key = VK_BROWSER_FORWARD
|
||||
KeyBrowserRefresh Key = VK_BROWSER_REFRESH
|
||||
KeyBrowserStop Key = VK_BROWSER_STOP
|
||||
KeyBrowserSearch Key = VK_BROWSER_SEARCH
|
||||
KeyBrowserFavorites Key = VK_BROWSER_FAVORITES
|
||||
KeyBrowserHome Key = VK_BROWSER_HOME
|
||||
KeyVolumeMute Key = VK_VOLUME_MUTE
|
||||
KeyVolumeDown Key = VK_VOLUME_DOWN
|
||||
KeyVolumeUp Key = VK_VOLUME_UP
|
||||
KeyMediaNextTrack Key = VK_MEDIA_NEXT_TRACK
|
||||
KeyMediaPrevTrack Key = VK_MEDIA_PREV_TRACK
|
||||
KeyMediaStop Key = VK_MEDIA_STOP
|
||||
KeyMediaPlayPause Key = VK_MEDIA_PLAY_PAUSE
|
||||
KeyLaunchMail Key = VK_LAUNCH_MAIL
|
||||
KeyLaunchMediaSelect Key = VK_LAUNCH_MEDIA_SELECT
|
||||
KeyLaunchApp1 Key = VK_LAUNCH_APP1
|
||||
KeyLaunchApp2 Key = VK_LAUNCH_APP2
|
||||
KeyOEM1 Key = VK_OEM_1
|
||||
KeyOEMPlus Key = VK_OEM_PLUS
|
||||
KeyOEMComma Key = VK_OEM_COMMA
|
||||
KeyOEMMinus Key = VK_OEM_MINUS
|
||||
KeyOEMPeriod Key = VK_OEM_PERIOD
|
||||
KeyOEM2 Key = VK_OEM_2
|
||||
KeyOEM3 Key = VK_OEM_3
|
||||
KeyOEM4 Key = VK_OEM_4
|
||||
KeyOEM5 Key = VK_OEM_5
|
||||
KeyOEM6 Key = VK_OEM_6
|
||||
KeyOEM7 Key = VK_OEM_7
|
||||
KeyOEM8 Key = VK_OEM_8
|
||||
KeyOEM102 Key = VK_OEM_102
|
||||
KeyProcessKey Key = VK_PROCESSKEY
|
||||
KeyPacket Key = VK_PACKET
|
||||
KeyAttn Key = VK_ATTN
|
||||
KeyCRSel Key = VK_CRSEL
|
||||
KeyEXSel Key = VK_EXSEL
|
||||
KeyErEOF Key = VK_EREOF
|
||||
KeyPlay Key = VK_PLAY
|
||||
KeyZoom Key = VK_ZOOM
|
||||
KeyNoName Key = VK_NONAME
|
||||
KeyPA1 Key = VK_PA1
|
||||
KeyOEMClear Key = VK_OEM_CLEAR
|
||||
)
|
||||
|
||||
var key2string = map[Key]string{
|
||||
KeyLButton: "LButton",
|
||||
KeyRButton: "RButton",
|
||||
KeyCancel: "Cancel",
|
||||
KeyMButton: "MButton",
|
||||
KeyXButton1: "XButton1",
|
||||
KeyXButton2: "XButton2",
|
||||
KeyBack: "Back",
|
||||
KeyTab: "Tab",
|
||||
KeyClear: "Clear",
|
||||
KeyReturn: "Return",
|
||||
KeyShift: "Shift",
|
||||
KeyControl: "Control",
|
||||
KeyAlt: "Alt / Menu",
|
||||
KeyPause: "Pause",
|
||||
KeyCapital: "Capital",
|
||||
KeyKana: "Kana / Hangul",
|
||||
KeyJunja: "Junja",
|
||||
KeyFinal: "Final",
|
||||
KeyHanja: "Hanja / Kanji",
|
||||
KeyEscape: "Escape",
|
||||
KeyConvert: "Convert",
|
||||
KeyNonconvert: "Nonconvert",
|
||||
KeyAccept: "Accept",
|
||||
KeyModeChange: "ModeChange",
|
||||
KeySpace: "Space",
|
||||
KeyPrior: "Prior",
|
||||
KeyNext: "Next",
|
||||
KeyEnd: "End",
|
||||
KeyHome: "Home",
|
||||
KeyLeft: "Left",
|
||||
KeyUp: "Up",
|
||||
KeyRight: "Right",
|
||||
KeyDown: "Down",
|
||||
KeySelect: "Select",
|
||||
KeyPrint: "Print",
|
||||
KeyExecute: "Execute",
|
||||
KeySnapshot: "Snapshot",
|
||||
KeyInsert: "Insert",
|
||||
KeyDelete: "Delete",
|
||||
KeyHelp: "Help",
|
||||
Key0: "0",
|
||||
Key1: "1",
|
||||
Key2: "2",
|
||||
Key3: "3",
|
||||
Key4: "4",
|
||||
Key5: "5",
|
||||
Key6: "6",
|
||||
Key7: "7",
|
||||
Key8: "8",
|
||||
Key9: "9",
|
||||
KeyA: "A",
|
||||
KeyB: "B",
|
||||
KeyC: "C",
|
||||
KeyD: "D",
|
||||
KeyE: "E",
|
||||
KeyF: "F",
|
||||
KeyG: "G",
|
||||
KeyH: "H",
|
||||
KeyI: "I",
|
||||
KeyJ: "J",
|
||||
KeyK: "K",
|
||||
KeyL: "L",
|
||||
KeyM: "M",
|
||||
KeyN: "N",
|
||||
KeyO: "O",
|
||||
KeyP: "P",
|
||||
KeyQ: "Q",
|
||||
KeyR: "R",
|
||||
KeyS: "S",
|
||||
KeyT: "T",
|
||||
KeyU: "U",
|
||||
KeyV: "V",
|
||||
KeyW: "W",
|
||||
KeyX: "X",
|
||||
KeyY: "Y",
|
||||
KeyZ: "Z",
|
||||
KeyLWIN: "LWIN",
|
||||
KeyRWIN: "RWIN",
|
||||
KeyApps: "Apps",
|
||||
KeySleep: "Sleep",
|
||||
KeyNumpad0: "Numpad0",
|
||||
KeyNumpad1: "Numpad1",
|
||||
KeyNumpad2: "Numpad2",
|
||||
KeyNumpad3: "Numpad3",
|
||||
KeyNumpad4: "Numpad4",
|
||||
KeyNumpad5: "Numpad5",
|
||||
KeyNumpad6: "Numpad6",
|
||||
KeyNumpad7: "Numpad7",
|
||||
KeyNumpad8: "Numpad8",
|
||||
KeyNumpad9: "Numpad9",
|
||||
KeyMultiply: "Multiply",
|
||||
KeyAdd: "Add",
|
||||
KeySeparator: "Separator",
|
||||
KeySubtract: "Subtract",
|
||||
KeyDecimal: "Decimal",
|
||||
KeyDivide: "Divide",
|
||||
KeyF1: "F1",
|
||||
KeyF2: "F2",
|
||||
KeyF3: "F3",
|
||||
KeyF4: "F4",
|
||||
KeyF5: "F5",
|
||||
KeyF6: "F6",
|
||||
KeyF7: "F7",
|
||||
KeyF8: "F8",
|
||||
KeyF9: "F9",
|
||||
KeyF10: "F10",
|
||||
KeyF11: "F11",
|
||||
KeyF12: "F12",
|
||||
KeyF13: "F13",
|
||||
KeyF14: "F14",
|
||||
KeyF15: "F15",
|
||||
KeyF16: "F16",
|
||||
KeyF17: "F17",
|
||||
KeyF18: "F18",
|
||||
KeyF19: "F19",
|
||||
KeyF20: "F20",
|
||||
KeyF21: "F21",
|
||||
KeyF22: "F22",
|
||||
KeyF23: "F23",
|
||||
KeyF24: "F24",
|
||||
KeyNumlock: "Numlock",
|
||||
KeyScroll: "Scroll",
|
||||
KeyLShift: "LShift",
|
||||
KeyRShift: "RShift",
|
||||
KeyLControl: "LControl",
|
||||
KeyRControl: "RControl",
|
||||
KeyLMenu: "LMenu",
|
||||
KeyRMenu: "RMenu",
|
||||
KeyBrowserBack: "BrowserBack",
|
||||
KeyBrowserForward: "BrowserForward",
|
||||
KeyBrowserRefresh: "BrowserRefresh",
|
||||
KeyBrowserStop: "BrowserStop",
|
||||
KeyBrowserSearch: "BrowserSearch",
|
||||
KeyBrowserFavorites: "BrowserFavorites",
|
||||
KeyBrowserHome: "BrowserHome",
|
||||
KeyVolumeMute: "VolumeMute",
|
||||
KeyVolumeDown: "VolumeDown",
|
||||
KeyVolumeUp: "VolumeUp",
|
||||
KeyMediaNextTrack: "MediaNextTrack",
|
||||
KeyMediaPrevTrack: "MediaPrevTrack",
|
||||
KeyMediaStop: "MediaStop",
|
||||
KeyMediaPlayPause: "MediaPlayPause",
|
||||
KeyLaunchMail: "LaunchMail",
|
||||
KeyLaunchMediaSelect: "LaunchMediaSelect",
|
||||
KeyLaunchApp1: "LaunchApp1",
|
||||
KeyLaunchApp2: "LaunchApp2",
|
||||
KeyOEM1: "OEM1",
|
||||
KeyOEMPlus: "OEMPlus",
|
||||
KeyOEMComma: "OEMComma",
|
||||
KeyOEMMinus: "OEMMinus",
|
||||
KeyOEMPeriod: "OEMPeriod",
|
||||
KeyOEM2: "OEM2",
|
||||
KeyOEM3: "OEM3",
|
||||
KeyOEM4: "OEM4",
|
||||
KeyOEM5: "OEM5",
|
||||
KeyOEM6: "OEM6",
|
||||
KeyOEM7: "OEM7",
|
||||
KeyOEM8: "OEM8",
|
||||
KeyOEM102: "OEM102",
|
||||
KeyProcessKey: "ProcessKey",
|
||||
KeyPacket: "Packet",
|
||||
KeyAttn: "Attn",
|
||||
KeyCRSel: "CRSel",
|
||||
KeyEXSel: "EXSel",
|
||||
KeyErEOF: "ErEOF",
|
||||
KeyPlay: "Play",
|
||||
KeyZoom: "Zoom",
|
||||
KeyNoName: "NoName",
|
||||
KeyPA1: "PA1",
|
||||
KeyOEMClear: "OEMClear",
|
||||
}
|
||||
|
||||
type Modifiers byte
|
||||
|
||||
func (m Modifiers) String() string {
|
||||
return modifiers2string[m]
|
||||
}
|
||||
|
||||
var modifiers2string = map[Modifiers]string{
|
||||
ModShift: "Shift",
|
||||
ModControl: "Ctrl",
|
||||
ModControl | ModShift: "Ctrl+Shift",
|
||||
ModAlt: "Alt",
|
||||
ModAlt | ModShift: "Alt+Shift",
|
||||
ModAlt | ModControl | ModShift: "Alt+Ctrl+Shift",
|
||||
}
|
||||
|
||||
const (
|
||||
ModShift Modifiers = 1 << iota
|
||||
ModControl
|
||||
ModAlt
|
||||
)
|
||||
|
||||
func ModifiersDown() Modifiers {
|
||||
var m Modifiers
|
||||
|
||||
if ShiftDown() {
|
||||
m |= ModShift
|
||||
}
|
||||
if ControlDown() {
|
||||
m |= ModControl
|
||||
}
|
||||
if AltDown() {
|
||||
m |= ModAlt
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
type Shortcut struct {
|
||||
Modifiers Modifiers
|
||||
Key Key
|
||||
}
|
||||
|
||||
func (s Shortcut) String() string {
|
||||
m := s.Modifiers.String()
|
||||
if m == "" {
|
||||
return s.Key.String()
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
b.WriteString(m)
|
||||
b.WriteRune('+')
|
||||
b.WriteString(s.Key.String())
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func GetKeyState(nVirtKey int32) int16 {
|
||||
ret, _, _ := procGetKeyState.Call(
|
||||
uintptr(nVirtKey),
|
||||
)
|
||||
|
||||
return int16(ret)
|
||||
}
|
||||
|
||||
func AltDown() bool {
|
||||
return GetKeyState(int32(KeyAlt))>>15 != 0
|
||||
}
|
||||
|
||||
func ControlDown() bool {
|
||||
return GetKeyState(int32(KeyControl))>>15 != 0
|
||||
}
|
||||
|
||||
func ShiftDown() bool {
|
||||
return GetKeyState(int32(KeyShift))>>15 != 0
|
||||
}
|
||||
|
||||
var ModifierMap = map[keys.Modifier]Modifiers{
|
||||
keys.ShiftKey: ModShift,
|
||||
keys.ControlKey: ModControl,
|
||||
keys.OptionOrAltKey: ModAlt,
|
||||
keys.CmdOrCtrlKey: ModControl,
|
||||
}
|
||||
|
||||
var NoShortcut = Shortcut{}
|
||||
|
||||
func AcceleratorToShortcut(accelerator *keys.Accelerator) Shortcut {
|
||||
|
||||
if accelerator == nil {
|
||||
return NoShortcut
|
||||
}
|
||||
inKey := strings.ToUpper(accelerator.Key)
|
||||
key, exists := KeyMap[inKey]
|
||||
if !exists {
|
||||
return NoShortcut
|
||||
}
|
||||
var modifiers Modifiers
|
||||
if _, exists := shiftMap[inKey]; exists {
|
||||
modifiers = ModShift
|
||||
}
|
||||
for _, mod := range accelerator.Modifiers {
|
||||
modifiers |= ModifierMap[mod]
|
||||
}
|
||||
return Shortcut{
|
||||
Modifiers: modifiers,
|
||||
Key: key,
|
||||
}
|
||||
}
|
||||
|
||||
var shiftMap = map[string]struct{}{
|
||||
"~": {},
|
||||
")": {},
|
||||
"!": {},
|
||||
"@": {},
|
||||
"#": {},
|
||||
"$": {},
|
||||
"%": {},
|
||||
"^": {},
|
||||
"&": {},
|
||||
"*": {},
|
||||
"(": {},
|
||||
"_": {},
|
||||
"PLUS": {},
|
||||
"<": {},
|
||||
">": {},
|
||||
"?": {},
|
||||
":": {},
|
||||
`"`: {},
|
||||
"{": {},
|
||||
"}": {},
|
||||
"|": {},
|
||||
}
|
||||
|
||||
var KeyMap = map[string]Key{
|
||||
"0": Key0,
|
||||
"1": Key1,
|
||||
"2": Key2,
|
||||
"3": Key3,
|
||||
"4": Key4,
|
||||
"5": Key5,
|
||||
"6": Key6,
|
||||
"7": Key7,
|
||||
"8": Key8,
|
||||
"9": Key9,
|
||||
"A": KeyA,
|
||||
"B": KeyB,
|
||||
"C": KeyC,
|
||||
"D": KeyD,
|
||||
"E": KeyE,
|
||||
"F": KeyF,
|
||||
"G": KeyG,
|
||||
"H": KeyH,
|
||||
"I": KeyI,
|
||||
"J": KeyJ,
|
||||
"K": KeyK,
|
||||
"L": KeyL,
|
||||
"M": KeyM,
|
||||
"N": KeyN,
|
||||
"O": KeyO,
|
||||
"P": KeyP,
|
||||
"Q": KeyQ,
|
||||
"R": KeyR,
|
||||
"S": KeyS,
|
||||
"T": KeyT,
|
||||
"U": KeyU,
|
||||
"V": KeyV,
|
||||
"W": KeyW,
|
||||
"X": KeyX,
|
||||
"Y": KeyY,
|
||||
"Z": KeyZ,
|
||||
"F1": KeyF1,
|
||||
"F2": KeyF2,
|
||||
"F3": KeyF3,
|
||||
"F4": KeyF4,
|
||||
"F5": KeyF5,
|
||||
"F6": KeyF6,
|
||||
"F7": KeyF7,
|
||||
"F8": KeyF8,
|
||||
"F9": KeyF9,
|
||||
"F10": KeyF10,
|
||||
"F11": KeyF11,
|
||||
"F12": KeyF12,
|
||||
"F13": KeyF13,
|
||||
"F14": KeyF14,
|
||||
"F15": KeyF15,
|
||||
"F16": KeyF16,
|
||||
"F17": KeyF17,
|
||||
"F18": KeyF18,
|
||||
"F19": KeyF19,
|
||||
"F20": KeyF20,
|
||||
"F21": KeyF21,
|
||||
"F22": KeyF22,
|
||||
"F23": KeyF23,
|
||||
"F24": KeyF24,
|
||||
|
||||
"`": KeyOEM3,
|
||||
",": KeyOEMComma,
|
||||
".": KeyOEMPeriod,
|
||||
"/": KeyOEM2,
|
||||
";": KeyOEM1,
|
||||
"'": KeyOEM7,
|
||||
"[": KeyOEM4,
|
||||
"]": KeyOEM6,
|
||||
`\`: KeyOEM5,
|
||||
"~": KeyOEM3,
|
||||
")": Key0,
|
||||
"!": Key1,
|
||||
"@": Key2,
|
||||
"#": Key3,
|
||||
"$": Key4,
|
||||
"%": Key5,
|
||||
"^": Key6,
|
||||
"&": Key7,
|
||||
"*": Key8,
|
||||
"(": Key9,
|
||||
"_": KeyOEMMinus,
|
||||
"PLUS": KeyOEMPlus,
|
||||
"<": KeyOEMComma,
|
||||
">": KeyOEMPeriod,
|
||||
"?": KeyOEM2,
|
||||
":": KeyOEM1,
|
||||
`"`: KeyOEM7,
|
||||
"{": KeyOEM4,
|
||||
"}": KeyOEM6,
|
||||
"|": KeyOEM5,
|
||||
|
||||
"SPACE": KeySpace,
|
||||
"TAB": KeyTab,
|
||||
"CAPSLOCK": KeyCapital,
|
||||
"NUMLOCK": KeyNumlock,
|
||||
"SCROLLLOCK": KeyScroll,
|
||||
"BACKSPACE": KeyBack,
|
||||
"DELETE": KeyDelete,
|
||||
"INSERT": KeyInsert,
|
||||
"RETURN": KeyReturn,
|
||||
"ENTER": KeyReturn,
|
||||
"UP": KeyUp,
|
||||
"DOWN": KeyDown,
|
||||
"LEFT": KeyLeft,
|
||||
"RIGHT": KeyRight,
|
||||
"HOME": KeyHome,
|
||||
"END": KeyEnd,
|
||||
"PAGEUP": KeyPrior,
|
||||
"PAGEDOWN": KeyNext,
|
||||
"ESCAPE": KeyEscape,
|
||||
"ESC": KeyEscape,
|
||||
"VOLUMEUP": KeyVolumeUp,
|
||||
"VOLUMEDOWN": KeyVolumeDown,
|
||||
"VOLUMEMUTE": KeyVolumeMute,
|
||||
"MEDIANEXTTRACK": KeyMediaNextTrack,
|
||||
"MEDIAPREVIOUSTRACK": KeyMediaPrevTrack,
|
||||
"MEDIASTOP": KeyMediaStop,
|
||||
"MEDIAPLAYPAUSE": KeyMediaPlayPause,
|
||||
"PRINTSCREEN": KeyPrint,
|
||||
"NUM0": KeyNumpad0,
|
||||
"NUM1": KeyNumpad1,
|
||||
"NUM2": KeyNumpad2,
|
||||
"NUM3": KeyNumpad3,
|
||||
"NUM4": KeyNumpad4,
|
||||
"NUM5": KeyNumpad5,
|
||||
"NUM6": KeyNumpad6,
|
||||
"NUM7": KeyNumpad7,
|
||||
"NUM8": KeyNumpad8,
|
||||
"NUM9": KeyNumpad9,
|
||||
"nummult": KeyMultiply,
|
||||
"numadd": KeyAdd,
|
||||
"numsub": KeySubtract,
|
||||
"numdec": KeyDecimal,
|
||||
"numdiv": KeyDivide,
|
||||
}
|
||||
|
||||
type Accelerator struct {
|
||||
Virtual byte
|
||||
Key uint16
|
||||
Cmd uint16
|
||||
}
|
||||
|
||||
func CreateAcceleratorTable(acc []Accelerator) uintptr {
|
||||
if len(acc) == 0 {
|
||||
return 0
|
||||
}
|
||||
ret, _, _ := procCreateAcceleratorTable.Call(
|
||||
uintptr(unsafe.Pointer(&acc[0])),
|
||||
uintptr(len(acc)),
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
func TranslateAccelerator(hwnd HWND, hAccTable uintptr, lpMsg *MSG) bool {
|
||||
ret, _, _ := procTranslateAccelerator.Call(
|
||||
uintptr(hwnd),
|
||||
hAccTable,
|
||||
uintptr(unsafe.Pointer(lpMsg)),
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue