github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/internal/platform/win32/keyboard.go (about)

     1  //go:build windows
     2  
     3  /*
     4   * Copyright (C) 2019 The Winc Authors. All Rights Reserved.
     5   * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved.
     6   */
     7  
     8  package win32
     9  
    10  import (
    11  	"bytes"
    12  	"github.com/AlpineAIO/wails/v2/pkg/menu/keys"
    13  	"strings"
    14  	"unsafe"
    15  )
    16  
    17  type Key uint16
    18  
    19  func (k Key) String() string {
    20  	return key2string[k]
    21  }
    22  
    23  // Virtual key codes
    24  const (
    25  	VK_LBUTTON             = 1
    26  	VK_RBUTTON             = 2
    27  	VK_CANCEL              = 3
    28  	VK_MBUTTON             = 4
    29  	VK_XBUTTON1            = 5
    30  	VK_XBUTTON2            = 6
    31  	VK_BACK                = 8
    32  	VK_TAB                 = 9
    33  	VK_CLEAR               = 12
    34  	VK_RETURN              = 13
    35  	VK_SHIFT               = 16
    36  	VK_CONTROL             = 17
    37  	VK_MENU                = 18
    38  	VK_PAUSE               = 19
    39  	VK_CAPITAL             = 20
    40  	VK_KANA                = 0x15
    41  	VK_HANGEUL             = 0x15
    42  	VK_HANGUL              = 0x15
    43  	VK_JUNJA               = 0x17
    44  	VK_FINAL               = 0x18
    45  	VK_HANJA               = 0x19
    46  	VK_KANJI               = 0x19
    47  	VK_ESCAPE              = 0x1B
    48  	VK_CONVERT             = 0x1C
    49  	VK_NONCONVERT          = 0x1D
    50  	VK_ACCEPT              = 0x1E
    51  	VK_MODECHANGE          = 0x1F
    52  	VK_SPACE               = 32
    53  	VK_PRIOR               = 33
    54  	VK_NEXT                = 34
    55  	VK_END                 = 35
    56  	VK_HOME                = 36
    57  	VK_LEFT                = 37
    58  	VK_UP                  = 38
    59  	VK_RIGHT               = 39
    60  	VK_DOWN                = 40
    61  	VK_SELECT              = 41
    62  	VK_PRINT               = 42
    63  	VK_EXECUTE             = 43
    64  	VK_SNAPSHOT            = 44
    65  	VK_INSERT              = 45
    66  	VK_DELETE              = 46
    67  	VK_HELP                = 47
    68  	VK_LWIN                = 0x5B
    69  	VK_RWIN                = 0x5C
    70  	VK_APPS                = 0x5D
    71  	VK_SLEEP               = 0x5F
    72  	VK_NUMPAD0             = 0x60
    73  	VK_NUMPAD1             = 0x61
    74  	VK_NUMPAD2             = 0x62
    75  	VK_NUMPAD3             = 0x63
    76  	VK_NUMPAD4             = 0x64
    77  	VK_NUMPAD5             = 0x65
    78  	VK_NUMPAD6             = 0x66
    79  	VK_NUMPAD7             = 0x67
    80  	VK_NUMPAD8             = 0x68
    81  	VK_NUMPAD9             = 0x69
    82  	VK_MULTIPLY            = 0x6A
    83  	VK_ADD                 = 0x6B
    84  	VK_SEPARATOR           = 0x6C
    85  	VK_SUBTRACT            = 0x6D
    86  	VK_DECIMAL             = 0x6E
    87  	VK_DIVIDE              = 0x6F
    88  	VK_F1                  = 0x70
    89  	VK_F2                  = 0x71
    90  	VK_F3                  = 0x72
    91  	VK_F4                  = 0x73
    92  	VK_F5                  = 0x74
    93  	VK_F6                  = 0x75
    94  	VK_F7                  = 0x76
    95  	VK_F8                  = 0x77
    96  	VK_F9                  = 0x78
    97  	VK_F10                 = 0x79
    98  	VK_F11                 = 0x7A
    99  	VK_F12                 = 0x7B
   100  	VK_F13                 = 0x7C
   101  	VK_F14                 = 0x7D
   102  	VK_F15                 = 0x7E
   103  	VK_F16                 = 0x7F
   104  	VK_F17                 = 0x80
   105  	VK_F18                 = 0x81
   106  	VK_F19                 = 0x82
   107  	VK_F20                 = 0x83
   108  	VK_F21                 = 0x84
   109  	VK_F22                 = 0x85
   110  	VK_F23                 = 0x86
   111  	VK_F24                 = 0x87
   112  	VK_NUMLOCK             = 0x90
   113  	VK_SCROLL              = 0x91
   114  	VK_LSHIFT              = 0xA0
   115  	VK_RSHIFT              = 0xA1
   116  	VK_LCONTROL            = 0xA2
   117  	VK_RCONTROL            = 0xA3
   118  	VK_LMENU               = 0xA4
   119  	VK_RMENU               = 0xA5
   120  	VK_BROWSER_BACK        = 0xA6
   121  	VK_BROWSER_FORWARD     = 0xA7
   122  	VK_BROWSER_REFRESH     = 0xA8
   123  	VK_BROWSER_STOP        = 0xA9
   124  	VK_BROWSER_SEARCH      = 0xAA
   125  	VK_BROWSER_FAVORITES   = 0xAB
   126  	VK_BROWSER_HOME        = 0xAC
   127  	VK_VOLUME_MUTE         = 0xAD
   128  	VK_VOLUME_DOWN         = 0xAE
   129  	VK_VOLUME_UP           = 0xAF
   130  	VK_MEDIA_NEXT_TRACK    = 0xB0
   131  	VK_MEDIA_PREV_TRACK    = 0xB1
   132  	VK_MEDIA_STOP          = 0xB2
   133  	VK_MEDIA_PLAY_PAUSE    = 0xB3
   134  	VK_LAUNCH_MAIL         = 0xB4
   135  	VK_LAUNCH_MEDIA_SELECT = 0xB5
   136  	VK_LAUNCH_APP1         = 0xB6
   137  	VK_LAUNCH_APP2         = 0xB7
   138  	VK_OEM_1               = 0xBA
   139  	VK_OEM_PLUS            = 0xBB
   140  	VK_OEM_COMMA           = 0xBC
   141  	VK_OEM_MINUS           = 0xBD
   142  	VK_OEM_PERIOD          = 0xBE
   143  	VK_OEM_2               = 0xBF
   144  	VK_OEM_3               = 0xC0
   145  	VK_OEM_4               = 0xDB
   146  	VK_OEM_5               = 0xDC
   147  	VK_OEM_6               = 0xDD
   148  	VK_OEM_7               = 0xDE
   149  	VK_OEM_8               = 0xDF
   150  	VK_OEM_102             = 0xE2
   151  	VK_PROCESSKEY          = 0xE5
   152  	VK_PACKET              = 0xE7
   153  	VK_ATTN                = 0xF6
   154  	VK_CRSEL               = 0xF7
   155  	VK_EXSEL               = 0xF8
   156  	VK_EREOF               = 0xF9
   157  	VK_PLAY                = 0xFA
   158  	VK_ZOOM                = 0xFB
   159  	VK_NONAME              = 0xFC
   160  	VK_PA1                 = 0xFD
   161  	VK_OEM_CLEAR           = 0xFE
   162  )
   163  
   164  const (
   165  	KeyLButton           Key = VK_LBUTTON
   166  	KeyRButton           Key = VK_RBUTTON
   167  	KeyCancel            Key = VK_CANCEL
   168  	KeyMButton           Key = VK_MBUTTON
   169  	KeyXButton1          Key = VK_XBUTTON1
   170  	KeyXButton2          Key = VK_XBUTTON2
   171  	KeyBack              Key = VK_BACK
   172  	KeyTab               Key = VK_TAB
   173  	KeyClear             Key = VK_CLEAR
   174  	KeyReturn            Key = VK_RETURN
   175  	KeyShift             Key = VK_SHIFT
   176  	KeyControl           Key = VK_CONTROL
   177  	KeyAlt               Key = VK_MENU
   178  	KeyMenu              Key = VK_MENU
   179  	KeyPause             Key = VK_PAUSE
   180  	KeyCapital           Key = VK_CAPITAL
   181  	KeyKana              Key = VK_KANA
   182  	KeyHangul            Key = VK_HANGUL
   183  	KeyJunja             Key = VK_JUNJA
   184  	KeyFinal             Key = VK_FINAL
   185  	KeyHanja             Key = VK_HANJA
   186  	KeyKanji             Key = VK_KANJI
   187  	KeyEscape            Key = VK_ESCAPE
   188  	KeyConvert           Key = VK_CONVERT
   189  	KeyNonconvert        Key = VK_NONCONVERT
   190  	KeyAccept            Key = VK_ACCEPT
   191  	KeyModeChange        Key = VK_MODECHANGE
   192  	KeySpace             Key = VK_SPACE
   193  	KeyPrior             Key = VK_PRIOR
   194  	KeyNext              Key = VK_NEXT
   195  	KeyEnd               Key = VK_END
   196  	KeyHome              Key = VK_HOME
   197  	KeyLeft              Key = VK_LEFT
   198  	KeyUp                Key = VK_UP
   199  	KeyRight             Key = VK_RIGHT
   200  	KeyDown              Key = VK_DOWN
   201  	KeySelect            Key = VK_SELECT
   202  	KeyPrint             Key = VK_PRINT
   203  	KeyExecute           Key = VK_EXECUTE
   204  	KeySnapshot          Key = VK_SNAPSHOT
   205  	KeyInsert            Key = VK_INSERT
   206  	KeyDelete            Key = VK_DELETE
   207  	KeyHelp              Key = VK_HELP
   208  	Key0                 Key = 0x30
   209  	Key1                 Key = 0x31
   210  	Key2                 Key = 0x32
   211  	Key3                 Key = 0x33
   212  	Key4                 Key = 0x34
   213  	Key5                 Key = 0x35
   214  	Key6                 Key = 0x36
   215  	Key7                 Key = 0x37
   216  	Key8                 Key = 0x38
   217  	Key9                 Key = 0x39
   218  	KeyA                 Key = 0x41
   219  	KeyB                 Key = 0x42
   220  	KeyC                 Key = 0x43
   221  	KeyD                 Key = 0x44
   222  	KeyE                 Key = 0x45
   223  	KeyF                 Key = 0x46
   224  	KeyG                 Key = 0x47
   225  	KeyH                 Key = 0x48
   226  	KeyI                 Key = 0x49
   227  	KeyJ                 Key = 0x4A
   228  	KeyK                 Key = 0x4B
   229  	KeyL                 Key = 0x4C
   230  	KeyM                 Key = 0x4D
   231  	KeyN                 Key = 0x4E
   232  	KeyO                 Key = 0x4F
   233  	KeyP                 Key = 0x50
   234  	KeyQ                 Key = 0x51
   235  	KeyR                 Key = 0x52
   236  	KeyS                 Key = 0x53
   237  	KeyT                 Key = 0x54
   238  	KeyU                 Key = 0x55
   239  	KeyV                 Key = 0x56
   240  	KeyW                 Key = 0x57
   241  	KeyX                 Key = 0x58
   242  	KeyY                 Key = 0x59
   243  	KeyZ                 Key = 0x5A
   244  	KeyLWIN              Key = VK_LWIN
   245  	KeyRWIN              Key = VK_RWIN
   246  	KeyApps              Key = VK_APPS
   247  	KeySleep             Key = VK_SLEEP
   248  	KeyNumpad0           Key = VK_NUMPAD0
   249  	KeyNumpad1           Key = VK_NUMPAD1
   250  	KeyNumpad2           Key = VK_NUMPAD2
   251  	KeyNumpad3           Key = VK_NUMPAD3
   252  	KeyNumpad4           Key = VK_NUMPAD4
   253  	KeyNumpad5           Key = VK_NUMPAD5
   254  	KeyNumpad6           Key = VK_NUMPAD6
   255  	KeyNumpad7           Key = VK_NUMPAD7
   256  	KeyNumpad8           Key = VK_NUMPAD8
   257  	KeyNumpad9           Key = VK_NUMPAD9
   258  	KeyMultiply          Key = VK_MULTIPLY
   259  	KeyAdd               Key = VK_ADD
   260  	KeySeparator         Key = VK_SEPARATOR
   261  	KeySubtract          Key = VK_SUBTRACT
   262  	KeyDecimal           Key = VK_DECIMAL
   263  	KeyDivide            Key = VK_DIVIDE
   264  	KeyF1                Key = VK_F1
   265  	KeyF2                Key = VK_F2
   266  	KeyF3                Key = VK_F3
   267  	KeyF4                Key = VK_F4
   268  	KeyF5                Key = VK_F5
   269  	KeyF6                Key = VK_F6
   270  	KeyF7                Key = VK_F7
   271  	KeyF8                Key = VK_F8
   272  	KeyF9                Key = VK_F9
   273  	KeyF10               Key = VK_F10
   274  	KeyF11               Key = VK_F11
   275  	KeyF12               Key = VK_F12
   276  	KeyF13               Key = VK_F13
   277  	KeyF14               Key = VK_F14
   278  	KeyF15               Key = VK_F15
   279  	KeyF16               Key = VK_F16
   280  	KeyF17               Key = VK_F17
   281  	KeyF18               Key = VK_F18
   282  	KeyF19               Key = VK_F19
   283  	KeyF20               Key = VK_F20
   284  	KeyF21               Key = VK_F21
   285  	KeyF22               Key = VK_F22
   286  	KeyF23               Key = VK_F23
   287  	KeyF24               Key = VK_F24
   288  	KeyNumlock           Key = VK_NUMLOCK
   289  	KeyScroll            Key = VK_SCROLL
   290  	KeyLShift            Key = VK_LSHIFT
   291  	KeyRShift            Key = VK_RSHIFT
   292  	KeyLControl          Key = VK_LCONTROL
   293  	KeyRControl          Key = VK_RCONTROL
   294  	KeyLAlt              Key = VK_LMENU
   295  	KeyLMenu             Key = VK_LMENU
   296  	KeyRAlt              Key = VK_RMENU
   297  	KeyRMenu             Key = VK_RMENU
   298  	KeyBrowserBack       Key = VK_BROWSER_BACK
   299  	KeyBrowserForward    Key = VK_BROWSER_FORWARD
   300  	KeyBrowserRefresh    Key = VK_BROWSER_REFRESH
   301  	KeyBrowserStop       Key = VK_BROWSER_STOP
   302  	KeyBrowserSearch     Key = VK_BROWSER_SEARCH
   303  	KeyBrowserFavorites  Key = VK_BROWSER_FAVORITES
   304  	KeyBrowserHome       Key = VK_BROWSER_HOME
   305  	KeyVolumeMute        Key = VK_VOLUME_MUTE
   306  	KeyVolumeDown        Key = VK_VOLUME_DOWN
   307  	KeyVolumeUp          Key = VK_VOLUME_UP
   308  	KeyMediaNextTrack    Key = VK_MEDIA_NEXT_TRACK
   309  	KeyMediaPrevTrack    Key = VK_MEDIA_PREV_TRACK
   310  	KeyMediaStop         Key = VK_MEDIA_STOP
   311  	KeyMediaPlayPause    Key = VK_MEDIA_PLAY_PAUSE
   312  	KeyLaunchMail        Key = VK_LAUNCH_MAIL
   313  	KeyLaunchMediaSelect Key = VK_LAUNCH_MEDIA_SELECT
   314  	KeyLaunchApp1        Key = VK_LAUNCH_APP1
   315  	KeyLaunchApp2        Key = VK_LAUNCH_APP2
   316  	KeyOEM1              Key = VK_OEM_1
   317  	KeyOEMPlus           Key = VK_OEM_PLUS
   318  	KeyOEMComma          Key = VK_OEM_COMMA
   319  	KeyOEMMinus          Key = VK_OEM_MINUS
   320  	KeyOEMPeriod         Key = VK_OEM_PERIOD
   321  	KeyOEM2              Key = VK_OEM_2
   322  	KeyOEM3              Key = VK_OEM_3
   323  	KeyOEM4              Key = VK_OEM_4
   324  	KeyOEM5              Key = VK_OEM_5
   325  	KeyOEM6              Key = VK_OEM_6
   326  	KeyOEM7              Key = VK_OEM_7
   327  	KeyOEM8              Key = VK_OEM_8
   328  	KeyOEM102            Key = VK_OEM_102
   329  	KeyProcessKey        Key = VK_PROCESSKEY
   330  	KeyPacket            Key = VK_PACKET
   331  	KeyAttn              Key = VK_ATTN
   332  	KeyCRSel             Key = VK_CRSEL
   333  	KeyEXSel             Key = VK_EXSEL
   334  	KeyErEOF             Key = VK_EREOF
   335  	KeyPlay              Key = VK_PLAY
   336  	KeyZoom              Key = VK_ZOOM
   337  	KeyNoName            Key = VK_NONAME
   338  	KeyPA1               Key = VK_PA1
   339  	KeyOEMClear          Key = VK_OEM_CLEAR
   340  )
   341  
   342  var key2string = map[Key]string{
   343  	KeyLButton:           "LButton",
   344  	KeyRButton:           "RButton",
   345  	KeyCancel:            "Cancel",
   346  	KeyMButton:           "MButton",
   347  	KeyXButton1:          "XButton1",
   348  	KeyXButton2:          "XButton2",
   349  	KeyBack:              "Back",
   350  	KeyTab:               "Tab",
   351  	KeyClear:             "Clear",
   352  	KeyReturn:            "Return",
   353  	KeyShift:             "Shift",
   354  	KeyControl:           "Control",
   355  	KeyAlt:               "Alt / Menu",
   356  	KeyPause:             "Pause",
   357  	KeyCapital:           "Capital",
   358  	KeyKana:              "Kana / Hangul",
   359  	KeyJunja:             "Junja",
   360  	KeyFinal:             "Final",
   361  	KeyHanja:             "Hanja / Kanji",
   362  	KeyEscape:            "Escape",
   363  	KeyConvert:           "Convert",
   364  	KeyNonconvert:        "Nonconvert",
   365  	KeyAccept:            "Accept",
   366  	KeyModeChange:        "ModeChange",
   367  	KeySpace:             "Space",
   368  	KeyPrior:             "Prior",
   369  	KeyNext:              "Next",
   370  	KeyEnd:               "End",
   371  	KeyHome:              "Home",
   372  	KeyLeft:              "Left",
   373  	KeyUp:                "Up",
   374  	KeyRight:             "Right",
   375  	KeyDown:              "Down",
   376  	KeySelect:            "Select",
   377  	KeyPrint:             "Print",
   378  	KeyExecute:           "Execute",
   379  	KeySnapshot:          "Snapshot",
   380  	KeyInsert:            "Insert",
   381  	KeyDelete:            "Delete",
   382  	KeyHelp:              "Help",
   383  	Key0:                 "0",
   384  	Key1:                 "1",
   385  	Key2:                 "2",
   386  	Key3:                 "3",
   387  	Key4:                 "4",
   388  	Key5:                 "5",
   389  	Key6:                 "6",
   390  	Key7:                 "7",
   391  	Key8:                 "8",
   392  	Key9:                 "9",
   393  	KeyA:                 "A",
   394  	KeyB:                 "B",
   395  	KeyC:                 "C",
   396  	KeyD:                 "D",
   397  	KeyE:                 "E",
   398  	KeyF:                 "F",
   399  	KeyG:                 "G",
   400  	KeyH:                 "H",
   401  	KeyI:                 "I",
   402  	KeyJ:                 "J",
   403  	KeyK:                 "K",
   404  	KeyL:                 "L",
   405  	KeyM:                 "M",
   406  	KeyN:                 "N",
   407  	KeyO:                 "O",
   408  	KeyP:                 "P",
   409  	KeyQ:                 "Q",
   410  	KeyR:                 "R",
   411  	KeyS:                 "S",
   412  	KeyT:                 "T",
   413  	KeyU:                 "U",
   414  	KeyV:                 "V",
   415  	KeyW:                 "W",
   416  	KeyX:                 "X",
   417  	KeyY:                 "Y",
   418  	KeyZ:                 "Z",
   419  	KeyLWIN:              "LWIN",
   420  	KeyRWIN:              "RWIN",
   421  	KeyApps:              "Apps",
   422  	KeySleep:             "Sleep",
   423  	KeyNumpad0:           "Numpad0",
   424  	KeyNumpad1:           "Numpad1",
   425  	KeyNumpad2:           "Numpad2",
   426  	KeyNumpad3:           "Numpad3",
   427  	KeyNumpad4:           "Numpad4",
   428  	KeyNumpad5:           "Numpad5",
   429  	KeyNumpad6:           "Numpad6",
   430  	KeyNumpad7:           "Numpad7",
   431  	KeyNumpad8:           "Numpad8",
   432  	KeyNumpad9:           "Numpad9",
   433  	KeyMultiply:          "Multiply",
   434  	KeyAdd:               "Add",
   435  	KeySeparator:         "Separator",
   436  	KeySubtract:          "Subtract",
   437  	KeyDecimal:           "Decimal",
   438  	KeyDivide:            "Divide",
   439  	KeyF1:                "F1",
   440  	KeyF2:                "F2",
   441  	KeyF3:                "F3",
   442  	KeyF4:                "F4",
   443  	KeyF5:                "F5",
   444  	KeyF6:                "F6",
   445  	KeyF7:                "F7",
   446  	KeyF8:                "F8",
   447  	KeyF9:                "F9",
   448  	KeyF10:               "F10",
   449  	KeyF11:               "F11",
   450  	KeyF12:               "F12",
   451  	KeyF13:               "F13",
   452  	KeyF14:               "F14",
   453  	KeyF15:               "F15",
   454  	KeyF16:               "F16",
   455  	KeyF17:               "F17",
   456  	KeyF18:               "F18",
   457  	KeyF19:               "F19",
   458  	KeyF20:               "F20",
   459  	KeyF21:               "F21",
   460  	KeyF22:               "F22",
   461  	KeyF23:               "F23",
   462  	KeyF24:               "F24",
   463  	KeyNumlock:           "Numlock",
   464  	KeyScroll:            "Scroll",
   465  	KeyLShift:            "LShift",
   466  	KeyRShift:            "RShift",
   467  	KeyLControl:          "LControl",
   468  	KeyRControl:          "RControl",
   469  	KeyLMenu:             "LMenu",
   470  	KeyRMenu:             "RMenu",
   471  	KeyBrowserBack:       "BrowserBack",
   472  	KeyBrowserForward:    "BrowserForward",
   473  	KeyBrowserRefresh:    "BrowserRefresh",
   474  	KeyBrowserStop:       "BrowserStop",
   475  	KeyBrowserSearch:     "BrowserSearch",
   476  	KeyBrowserFavorites:  "BrowserFavorites",
   477  	KeyBrowserHome:       "BrowserHome",
   478  	KeyVolumeMute:        "VolumeMute",
   479  	KeyVolumeDown:        "VolumeDown",
   480  	KeyVolumeUp:          "VolumeUp",
   481  	KeyMediaNextTrack:    "MediaNextTrack",
   482  	KeyMediaPrevTrack:    "MediaPrevTrack",
   483  	KeyMediaStop:         "MediaStop",
   484  	KeyMediaPlayPause:    "MediaPlayPause",
   485  	KeyLaunchMail:        "LaunchMail",
   486  	KeyLaunchMediaSelect: "LaunchMediaSelect",
   487  	KeyLaunchApp1:        "LaunchApp1",
   488  	KeyLaunchApp2:        "LaunchApp2",
   489  	KeyOEM1:              "OEM1",
   490  	KeyOEMPlus:           "OEMPlus",
   491  	KeyOEMComma:          "OEMComma",
   492  	KeyOEMMinus:          "OEMMinus",
   493  	KeyOEMPeriod:         "OEMPeriod",
   494  	KeyOEM2:              "OEM2",
   495  	KeyOEM3:              "OEM3",
   496  	KeyOEM4:              "OEM4",
   497  	KeyOEM5:              "OEM5",
   498  	KeyOEM6:              "OEM6",
   499  	KeyOEM7:              "OEM7",
   500  	KeyOEM8:              "OEM8",
   501  	KeyOEM102:            "OEM102",
   502  	KeyProcessKey:        "ProcessKey",
   503  	KeyPacket:            "Packet",
   504  	KeyAttn:              "Attn",
   505  	KeyCRSel:             "CRSel",
   506  	KeyEXSel:             "EXSel",
   507  	KeyErEOF:             "ErEOF",
   508  	KeyPlay:              "Play",
   509  	KeyZoom:              "Zoom",
   510  	KeyNoName:            "NoName",
   511  	KeyPA1:               "PA1",
   512  	KeyOEMClear:          "OEMClear",
   513  }
   514  
   515  type Modifiers byte
   516  
   517  func (m Modifiers) String() string {
   518  	return modifiers2string[m]
   519  }
   520  
   521  var modifiers2string = map[Modifiers]string{
   522  	ModShift:                       "Shift",
   523  	ModControl:                     "Ctrl",
   524  	ModControl | ModShift:          "Ctrl+Shift",
   525  	ModAlt:                         "Alt",
   526  	ModAlt | ModShift:              "Alt+Shift",
   527  	ModAlt | ModControl | ModShift: "Alt+Ctrl+Shift",
   528  }
   529  
   530  const (
   531  	ModShift Modifiers = 1 << iota
   532  	ModControl
   533  	ModAlt
   534  )
   535  
   536  func ModifiersDown() Modifiers {
   537  	var m Modifiers
   538  
   539  	if ShiftDown() {
   540  		m |= ModShift
   541  	}
   542  	if ControlDown() {
   543  		m |= ModControl
   544  	}
   545  	if AltDown() {
   546  		m |= ModAlt
   547  	}
   548  
   549  	return m
   550  }
   551  
   552  type Shortcut struct {
   553  	Modifiers Modifiers
   554  	Key       Key
   555  }
   556  
   557  func (s Shortcut) String() string {
   558  	m := s.Modifiers.String()
   559  	if m == "" {
   560  		return s.Key.String()
   561  	}
   562  
   563  	b := new(bytes.Buffer)
   564  
   565  	b.WriteString(m)
   566  	b.WriteRune('+')
   567  	b.WriteString(s.Key.String())
   568  
   569  	return b.String()
   570  }
   571  
   572  func GetKeyState(nVirtKey int32) int16 {
   573  	ret, _, _ := procGetKeyState.Call(
   574  		uintptr(nVirtKey),
   575  	)
   576  
   577  	return int16(ret)
   578  }
   579  
   580  func AltDown() bool {
   581  	return GetKeyState(int32(KeyAlt))>>15 != 0
   582  }
   583  
   584  func ControlDown() bool {
   585  	return GetKeyState(int32(KeyControl))>>15 != 0
   586  }
   587  
   588  func ShiftDown() bool {
   589  	return GetKeyState(int32(KeyShift))>>15 != 0
   590  }
   591  
   592  var ModifierMap = map[keys.Modifier]Modifiers{
   593  	keys.ShiftKey:       ModShift,
   594  	keys.ControlKey:     ModControl,
   595  	keys.OptionOrAltKey: ModAlt,
   596  	keys.CmdOrCtrlKey:   ModControl,
   597  }
   598  
   599  var NoShortcut = Shortcut{}
   600  
   601  func AcceleratorToShortcut(accelerator *keys.Accelerator) Shortcut {
   602  
   603  	if accelerator == nil {
   604  		return NoShortcut
   605  	}
   606  	inKey := strings.ToUpper(accelerator.Key)
   607  	key, exists := KeyMap[inKey]
   608  	if !exists {
   609  		return NoShortcut
   610  	}
   611  	var modifiers Modifiers
   612  	if _, exists := shiftMap[inKey]; exists {
   613  		modifiers = ModShift
   614  	}
   615  	for _, mod := range accelerator.Modifiers {
   616  		modifiers |= ModifierMap[mod]
   617  	}
   618  	return Shortcut{
   619  		Modifiers: modifiers,
   620  		Key:       key,
   621  	}
   622  }
   623  
   624  var shiftMap = map[string]struct{}{
   625  	"~":    {},
   626  	")":    {},
   627  	"!":    {},
   628  	"@":    {},
   629  	"#":    {},
   630  	"$":    {},
   631  	"%":    {},
   632  	"^":    {},
   633  	"&":    {},
   634  	"*":    {},
   635  	"(":    {},
   636  	"_":    {},
   637  	"PLUS": {},
   638  	"<":    {},
   639  	">":    {},
   640  	"?":    {},
   641  	":":    {},
   642  	`"`:    {},
   643  	"{":    {},
   644  	"}":    {},
   645  	"|":    {},
   646  }
   647  
   648  var KeyMap = map[string]Key{
   649  	"0":   Key0,
   650  	"1":   Key1,
   651  	"2":   Key2,
   652  	"3":   Key3,
   653  	"4":   Key4,
   654  	"5":   Key5,
   655  	"6":   Key6,
   656  	"7":   Key7,
   657  	"8":   Key8,
   658  	"9":   Key9,
   659  	"A":   KeyA,
   660  	"B":   KeyB,
   661  	"C":   KeyC,
   662  	"D":   KeyD,
   663  	"E":   KeyE,
   664  	"F":   KeyF,
   665  	"G":   KeyG,
   666  	"H":   KeyH,
   667  	"I":   KeyI,
   668  	"J":   KeyJ,
   669  	"K":   KeyK,
   670  	"L":   KeyL,
   671  	"M":   KeyM,
   672  	"N":   KeyN,
   673  	"O":   KeyO,
   674  	"P":   KeyP,
   675  	"Q":   KeyQ,
   676  	"R":   KeyR,
   677  	"S":   KeyS,
   678  	"T":   KeyT,
   679  	"U":   KeyU,
   680  	"V":   KeyV,
   681  	"W":   KeyW,
   682  	"X":   KeyX,
   683  	"Y":   KeyY,
   684  	"Z":   KeyZ,
   685  	"F1":  KeyF1,
   686  	"F2":  KeyF2,
   687  	"F3":  KeyF3,
   688  	"F4":  KeyF4,
   689  	"F5":  KeyF5,
   690  	"F6":  KeyF6,
   691  	"F7":  KeyF7,
   692  	"F8":  KeyF8,
   693  	"F9":  KeyF9,
   694  	"F10": KeyF10,
   695  	"F11": KeyF11,
   696  	"F12": KeyF12,
   697  	"F13": KeyF13,
   698  	"F14": KeyF14,
   699  	"F15": KeyF15,
   700  	"F16": KeyF16,
   701  	"F17": KeyF17,
   702  	"F18": KeyF18,
   703  	"F19": KeyF19,
   704  	"F20": KeyF20,
   705  	"F21": KeyF21,
   706  	"F22": KeyF22,
   707  	"F23": KeyF23,
   708  	"F24": KeyF24,
   709  
   710  	"`":    KeyOEM3,
   711  	",":    KeyOEMComma,
   712  	".":    KeyOEMPeriod,
   713  	"/":    KeyOEM2,
   714  	";":    KeyOEM1,
   715  	"'":    KeyOEM7,
   716  	"[":    KeyOEM4,
   717  	"]":    KeyOEM6,
   718  	`\`:    KeyOEM5,
   719  	"~":    KeyOEM3,
   720  	")":    Key0,
   721  	"!":    Key1,
   722  	"@":    Key2,
   723  	"#":    Key3,
   724  	"$":    Key4,
   725  	"%":    Key5,
   726  	"^":    Key6,
   727  	"&":    Key7,
   728  	"*":    Key8,
   729  	"(":    Key9,
   730  	"_":    KeyOEMMinus,
   731  	"PLUS": KeyOEMPlus,
   732  	"<":    KeyOEMComma,
   733  	">":    KeyOEMPeriod,
   734  	"?":    KeyOEM2,
   735  	":":    KeyOEM1,
   736  	`"`:    KeyOEM7,
   737  	"{":    KeyOEM4,
   738  	"}":    KeyOEM6,
   739  	"|":    KeyOEM5,
   740  
   741  	"SPACE":              KeySpace,
   742  	"TAB":                KeyTab,
   743  	"CAPSLOCK":           KeyCapital,
   744  	"NUMLOCK":            KeyNumlock,
   745  	"SCROLLLOCK":         KeyScroll,
   746  	"BACKSPACE":          KeyBack,
   747  	"DELETE":             KeyDelete,
   748  	"INSERT":             KeyInsert,
   749  	"RETURN":             KeyReturn,
   750  	"ENTER":              KeyReturn,
   751  	"UP":                 KeyUp,
   752  	"DOWN":               KeyDown,
   753  	"LEFT":               KeyLeft,
   754  	"RIGHT":              KeyRight,
   755  	"HOME":               KeyHome,
   756  	"END":                KeyEnd,
   757  	"PAGEUP":             KeyPrior,
   758  	"PAGEDOWN":           KeyNext,
   759  	"ESCAPE":             KeyEscape,
   760  	"ESC":                KeyEscape,
   761  	"VOLUMEUP":           KeyVolumeUp,
   762  	"VOLUMEDOWN":         KeyVolumeDown,
   763  	"VOLUMEMUTE":         KeyVolumeMute,
   764  	"MEDIANEXTTRACK":     KeyMediaNextTrack,
   765  	"MEDIAPREVIOUSTRACK": KeyMediaPrevTrack,
   766  	"MEDIASTOP":          KeyMediaStop,
   767  	"MEDIAPLAYPAUSE":     KeyMediaPlayPause,
   768  	"PRINTSCREEN":        KeyPrint,
   769  	"NUM0":               KeyNumpad0,
   770  	"NUM1":               KeyNumpad1,
   771  	"NUM2":               KeyNumpad2,
   772  	"NUM3":               KeyNumpad3,
   773  	"NUM4":               KeyNumpad4,
   774  	"NUM5":               KeyNumpad5,
   775  	"NUM6":               KeyNumpad6,
   776  	"NUM7":               KeyNumpad7,
   777  	"NUM8":               KeyNumpad8,
   778  	"NUM9":               KeyNumpad9,
   779  	"nummult":            KeyMultiply,
   780  	"numadd":             KeyAdd,
   781  	"numsub":             KeySubtract,
   782  	"numdec":             KeyDecimal,
   783  	"numdiv":             KeyDivide,
   784  }
   785  
   786  type Accelerator struct {
   787  	Virtual byte
   788  	Key     uint16
   789  	Cmd     uint16
   790  }
   791  
   792  func CreateAcceleratorTable(acc []Accelerator) uintptr {
   793  	if len(acc) == 0 {
   794  		return 0
   795  	}
   796  	ret, _, _ := procCreateAcceleratorTable.Call(
   797  		uintptr(unsafe.Pointer(&acc[0])),
   798  		uintptr(len(acc)),
   799  	)
   800  	return ret
   801  }
   802  
   803  func TranslateAccelerator(hwnd HWND, hAccTable uintptr, lpMsg *MSG) bool {
   804  	ret, _, _ := procTranslateAccelerator.Call(
   805  		uintptr(hwnd),
   806  		hAccTable,
   807  		uintptr(unsafe.Pointer(lpMsg)),
   808  	)
   809  	return ret != 0
   810  }