1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 
  9 namespace System.Windows
 10 {
 11     public const byte VK_LBUTTON = 1u;
 12     public const byte VK_RBUTTON = 2u;
 13     public const byte VK_CANCEL = 3u;
 14     public const byte VK_MBUTTON = 4u;
 15     public const byte VK_XBUTTON1 = 5u;
 16     public const byte VK_XBUTTON2 = 6u;
 17     public const byte VK_BACK = 8u;
 18     public const byte VK_TAB = 9u;
 19     public const byte VK_CLEAR = 12u;
 20     public const byte VK_RETURN = 13u;
 21     public const byte VK_SHIFT = 16u;
 22     public const byte VK_CONTROL = 17u;
 23     public const byte VK_MENU = 18u;
 24     public const byte VK_PAUSE = 19u;
 25     public const byte VK_CAPITAL = 20u;
 26     public const byte VK_KANA = 21u;
 27     public const byte VK_HANGUEL = 21u;
 28     public const byte VK_HANGUL = 21u;
 29     public const byte VK_IME_ON = 22u;
 30     public const byte VK_JUNJA = 23u;
 31     public const byte VK_FINAL = 24u;
 32     public const byte VK_HANJA = 25u;
 33     public const byte VK_KANJI = 25u;
 34     public const byte VK_IME_OFF = 26u;
 35     public const byte VK_ESCAPE = 27u;
 36     public const byte VK_CONVERT = 28u;
 37     public const byte VK_NONCONVERT = 29u;
 38     public const byte VK_ACCEPT = 30u;
 39     public const byte VK_MODECHANGE = 31u;
 40     public const byte VK_SPACE = 32u;
 41     public const byte VK_PRIOR = 33u;
 42     public const byte VK_NEXT = 34u;
 43     public const byte VK_END = 35u;
 44     public const byte VK_HOME = 36u;
 45     public const byte VK_LEFT = 37u;
 46     public const byte VK_UP = 38u;
 47     public const byte VK_RIGHT = 39u;
 48     public const byte VK_DOWN = 40u;
 49     public const byte VK_SELECT = 41u;
 50     public const byte VK_PRINT = 42u;
 51     public const byte VK_EXECUTE = 43u;
 52     public const byte VK_SNAPSHOT = 44u;
 53     public const byte VK_INSERT = 45u;
 54     public const byte VK_DELETE = 46u;
 55     public const byte VK_HELP = 47u;
 56     public const byte VK_0 = 48u;
 57     public const byte VK_1 = 49u;
 58     public const byte VK_2 = 50u;
 59     public const byte VK_3 = 51u;
 60     public const byte VK_4 = 52u;
 61     public const byte VK_5 = 53u;
 62     public const byte VK_6 = 54u;
 63     public const byte VK_7 = 55u;
 64     public const byte VK_8 = 56u;
 65     public const byte VK_9 = 57u;
 66     public const byte VK_A = 65u;
 67     public const byte VK_B = 66u;
 68     public const byte VK_C = 67u;
 69     public const byte VK_D = 68u;
 70     public const byte VK_E = 69u;
 71     public const byte VK_F = 70u;
 72     public const byte VK_G = 71u;
 73     public const byte VK_H = 72u;
 74     public const byte VK_I = 73u;
 75     public const byte VK_J = 74u;
 76     public const byte VK_K = 75u;
 77     public const byte VK_L = 76u;
 78     public const byte VK_M = 77u;
 79     public const byte VK_N = 78u;
 80     public const byte VK_O = 79u;
 81     public const byte VK_P = 80u;
 82     public const byte VK_Q = 81u;
 83     public const byte VK_R = 82u;
 84     public const byte VK_S = 83u;
 85     public const byte VK_T = 84u;
 86     public const byte VK_U = 85u;
 87     public const byte VK_V = 86u;
 88     public const byte VK_W = 87u;
 89     public const byte VK_X = 88u;
 90     public const byte VK_Y = 89u;
 91     public const byte VK_Z = 90u;
 92     public const byte VK_LWIN = 91u;
 93     public const byte VK_RWIN = 92u;
 94     public const byte VK_APPS = 93u;
 95     public const byte VK_SLEEP = 95u;
 96     public const byte VK_NUMPAD0 = 96u;
 97     public const byte VK_NUMPAD1 = 97u;
 98     public const byte VK_NUMPAD2 = 98u;
 99     public const byte VK_NUMPAD3 = 99u;
100     public const byte VK_NUMPAD4 = 100u;
101     public const byte VK_NUMPAD5 = 101u;
102     public const byte VK_NUMPAD6 = 102u;
103     public const byte VK_NUMPAD7 = 103u;
104     public const byte VK_NUMPAD8 = 104u;
105     public const byte VK_NUMPAD9 = 105u;
106     public const byte VK_MULTIPLY = 106u;
107     public const byte VK_ADD = 107u;
108     public const byte VK_SEPARATOR = 108u;
109     public const byte VK_SUBTRACT = 109u;
110     public const byte VK_DECIMAL = 110u;
111     public const byte VK_DIVIDE = 111u;
112     public const byte VK_F1 = 112u;
113     public const byte VK_F2 = 113u;
114     public const byte VK_F3 = 114u;
115     public const byte VK_F4 = 115u;
116     public const byte VK_F5 = 116u;
117     public const byte VK_F6 = 117u;
118     public const byte VK_F7 = 118u;
119     public const byte VK_F8 = 119u;
120     public const byte VK_F9 = 120u;
121     public const byte VK_F10 = 121u;
122     public const byte VK_F11 = 122u;
123     public const byte VK_F12 = 123u;
124     public const byte VK_F13 = 124u;
125     public const byte VK_F14 = 125u;
126     public const byte VK_F15 = 126u;
127     public const byte VK_F16 = 127u;
128     public const byte VK_F17 = 128u;
129     public const byte VK_F18 = 129u;
130     public const byte VK_F19 = 130u;
131     public const byte VK_F20 = 131u;
132     public const byte VK_F21 = 132u;
133     public const byte VK_F22 = 133u;
134     public const byte VK_F23 = 134u;
135     public const byte VK_F24 = 135u;
136     public const byte VK_NUMLOCK = 144u;
137     public const byte VK_SCROLL = 145u;
138     public const byte VK_LSHIFT = 160u;
139     public const byte VK_RSHIFT = 161u;
140     public const byte VK_LCONTROL = 162u;
141     public const byte VK_RCONTROL = 163u;
142     public const byte VK_LMENU = 164u;
143     public const byte VK_RMENU = 165u;
144     public const byte VK_BROWSER_BACK = 166u;
145     public const byte VK_BROWSER_FORWARD = 167u;
146     public const byte VK_BROWSER_REFRESH = 168u;
147     public const byte VK_BROWSER_STOP = 169u;
148     public const byte VK_BROWSER_SEARCH = 170u;
149     public const byte VK_BROWSER_FAVORITES = 171u;
150     public const byte VK_BROWSER_HOME = 172u;
151     public const byte VK_VOLUME_MUTE = 173u;
152     public const byte VK_VOLUME_DOWN = 174u;
153     public const byte VK_VOLUME_UP = 175u;
154     public const byte VK_MEDIA_NEXT_TRACK = 176u;
155     public const byte VK_MEDIA_PREV_TRACK = 177u;
156     public const byte VK_MEDIA_STOP = 178u;
157     public const byte VK_MEDIA_PLAY_PAUSE = 179u;
158     public const byte VK_LAUNCH_MAIL = 180u;
159     public const byte VK_LAUNCH_MEDIA_SELECT = 181u;
160     public const byte VK_LAUNCH_APP1 = 182u;
161     public const byte VK_LAUNCH_APP2 = 183u;
162     public const byte VK_OEM_1 = 186u;
163     public const byte VK_OEM_PLUS = 187u;
164     public const byte VK_OEM_COMMA = 188u;
165     public const byte VK_OEM_MINUS = 189u;
166     public const byte VK_OEM_PEDIOD = 190u;
167     public const byte VK_OEM_2 = 191u;
168     public const byte VK_OEM_3 = 192u;
169     public const byte VK_OEM_4 = 219u;
170     public const byte VK_OEM_5 = 220u;
171     public const byte VK_OEM_6 = 221u;
172     public const byte VK_OEM_7 = 222u;
173     public const byte VK_OEM_8 = 223u;
174     public const byte VK_OEM_102 = 226u;
175     public const byte VK_PROCESSKEY = 229u;
176     public const byte VK_PACKET = 231u;
177     public const byte VK_ATTN = 246u;
178     public const byte VK_CRSEL = 247u;
179     public const byte VK_EXSEL = 248u;
180     public const byte VK_PLAY = 250u;
181     public const byte VK_ZOOM = 251u;
182     public const byte VK_PA1 = 253u;
183     public const byte VK_OEM_CLEAR = 254u;
184 
185     public enum Keys : int
186     {
187         a = 65
188         add = 107
189         altModifier = 262144
190         apps = 93
191         attn = 246u
192         b = 66
193         back = 8
194         browserBack = 166u
195         browserFavorites = 171u
196         browserForward = 167u
197         browserHome = 172u
198         browserRefresh = 168u
199         browserSearch = 170u
200         browserStop = 169u
201         c = 67
202         cancel = 3
203         capital = 20
204         capsLock = 20
205         clear = 12
206         controlModifier = 131072
207         controlKey = 17
208         crsel = 247u
209         d = 68
210         d0 = 48
211         d1 = 49
212         d2 = 50
213         d3 = 51
214         d4 = 52
215         d5 = 53
216         d6 = 54
217         d7 = 55
218         d8 = 56
219         d9 = 57
220         decimal = 110
221         delete_ = 46
222         divide = 111
223         down = 40
224         e = 69
225         end = 35
226         enter = 13
227         eraseEof = 249u
228         escape = 27
229         execute = 43
230         exsel = 248u
231         f = 70
232         f1 = 112
233         f10 = 121
234         f11 = 122
235         f12 = 123
236         f13 = 124
237         f14 = 125
238         f15 = 126
239         f16 = 127
240         f17 = 128u
241         f18 = 129u
242         f19 = 130u
243         f2 = 113
244         f20 = 131u
245         f21 = 132u
246         f22 = 133u
247         f23 = 134u
248         f24 = 135u
249         f3 = 114
250         f4 = 115
251         f5 = 116
252         f6 = 117
253         f7 = 118
254         f8 = 119
255         f9 = 120
256         finalMode = 24
257         g = 71
258         h = 72
259         hanguelMode = 21
260         hangulMode = 21
261         hanjaMode = 25
262         help = 47
263         home = 36
264         i = 73
265         imeAccept = 30
266         imeConvert = 28
267         imeModeChange = 31
268         imeNonconvert = 29
269         insert = 45
270         j = 74
271         junjaMode = 23
272         k = 75
273         kanaMode = 21
274         kanjiMode = 25
275         keyCode = 65535u
276         l = 75
277         launchApplication1 = 182u
278         launchApplication2 = 183u
279         launchMail = 180u
280         lButton = 1
281         lControlKey = 162u
282         left = 37
283         lineFeed = 10
284         lMenu = 164u
285         lShiftKey = 160u
286         lWin = 91
287         m = 77
288         mButton = 4
289         mediaNextTrack = 176u
290         mediaPlayPause = 179u
291         mediaPreviousTrack = 177u
292         mediaStop = 178u
293         menu = 18
294         modifiers = -65536
295         multiply = 106
296         n = 78
297         next = 34
298         noName = 252u
299         none = 0
300         numLock = 144u
301         numPad0 = 96
302         numPad1 = 97
303         numPad2 = 98
304         numPad3 = 99
305         numPad4 = 100
306         numPad5 = 101
307         numPad6 = 102
308         numPad7 = 103
309         numPad8 = 104
310         numPad9 = 105
311         o = 79
312         oem1 = 186u
313         oem102 = 226u
314         oem2 = 191u
315         oem3 = 192u
316         oem4 = 219u
317         oem5 = 220u
318         oem6 = 221u
319         oem7 = 222u
320         oem8 = 223u
321         oemBackslash = 226u
322         oemClear = 254u
323         oemCloseBrackets = 221u
324         oemComma = 188u
325         oemMinus = 189u
326         oemOpenBrackets = 219u
327         oemPediod = 190u
328         oemPipe = 220u
329         oemPlus = 187u
330         oemQuestion = 191u
331         oemQuotes = 222u
332         oemSemicolon = 186u
333         oemTilde = 192u
334         p = 80
335         pa1 = 253u
336         packet = 231u
337         pageDown = 34
338         pageUp = 33
339         pause = 19
340         play = 250u
341         print = 42
342         printScreen = 44
343         prior = 33
344         processKey = 229u
345         q = 81
346         r = 82
347         rButton = 2
348         rControlKey = 163u
349         return_ = 13
350         right = 39
351         rMenu = 165u
352         rShiftKey = 161u
353         rWin = 92
354         s = 83
355         scroll = 145u
356         select = 41
357         selectMedia = 181u
358         separator = 108
359         shiftModifier = 65536
360         shiftKey = 16
361         sleep = 95
362         snapshot = 44
363         space = 32
364         subtract = 109
365         t = 84
366         tab = 9
367         u = 85
368         up = 38
369         v = 86
370         volumeDown = 174u
371         volumeMute = 173u
372         volumeUp = 175u
373         w = 87
374         x = 88
375         xButton1 = 5
376         xButton2 = 6
377         y = 89
378         z = 90
379         zoom = 251u
380     }
381 
382     public ulong GetHashCode(Keys keys)
383     {
384         return cast<ulong>(cast<int>(keys));
385     }
386 
387     public class KeyCodeStrings
388     {
389         static KeyCodeStrings() : instance(new KeyCodeStrings())
390         {
391         }
392         public static KeyCodeStrings& Instance()
393         {
394             return *instance;
395         }
396         public const string& GetKeyCodeString(Keys key) const
397         {
398             return keyCodeStrings[cast<int>(key)];
399         }
400         private KeyCodeStrings()
401         {
402             keyCodeStrings.Add("None");
403             keyCodeStrings.Add("LButton");
404             keyCodeStrings.Add("RButton");
405             keyCodeStrings.Add("Cancel");
406             keyCodeStrings.Add("MButton");
407             keyCodeStrings.Add("XBUtton1");
408             keyCodeStrings.Add("XButton2");
409             keyCodeStrings.Add("");
410             keyCodeStrings.Add("Backspace");
411             keyCodeStrings.Add("Tab");
412             keyCodeStrings.Add("");
413             keyCodeStrings.Add("");
414             keyCodeStrings.Add("Clear");
415             keyCodeStrings.Add("Enter");
416             keyCodeStrings.Add("");
417             keyCodeStrings.Add("");
418             keyCodeStrings.Add("Shift");
419             keyCodeStrings.Add("Control");
420             keyCodeStrings.Add("Alt");
421             keyCodeStrings.Add("Pause");
422             keyCodeStrings.Add("Caps Lock");
423             keyCodeStrings.Add("Kana");
424             keyCodeStrings.Add("IME On");
425             keyCodeStrings.Add("Junja");
426             keyCodeStrings.Add("Final");
427             keyCodeStrings.Add("Hanja");
428             keyCodeStrings.Add("IME Off");
429             keyCodeStrings.Add("Escape");
430             keyCodeStrings.Add("Convert");
431             keyCodeStrings.Add("Nonconvert");
432             keyCodeStrings.Add("Accept");
433             keyCodeStrings.Add("Mode change");
434             keyCodeStrings.Add("Space");
435             keyCodeStrings.Add("Page up");
436             keyCodeStrings.Add("Page down");
437             keyCodeStrings.Add("End");
438             keyCodeStrings.Add("Home");
439             keyCodeStrings.Add("Left");
440             keyCodeStrings.Add("Up");
441             keyCodeStrings.Add("Right");
442             keyCodeStrings.Add("Down");
443             keyCodeStrings.Add("Select");
444             keyCodeStrings.Add("Print");
445             keyCodeStrings.Add("Execute");
446             keyCodeStrings.Add("Snapshot");
447             keyCodeStrings.Add("Insert");
448             keyCodeStrings.Add("Delete");
449             keyCodeStrings.Add("Help");
450             keyCodeStrings.Add("0");
451             keyCodeStrings.Add("1");
452             keyCodeStrings.Add("2");
453             keyCodeStrings.Add("3");
454             keyCodeStrings.Add("4");
455             keyCodeStrings.Add("5");
456             keyCodeStrings.Add("6");
457             keyCodeStrings.Add("7");
458             keyCodeStrings.Add("8");
459             keyCodeStrings.Add("9");
460             keyCodeStrings.Add("");
461             keyCodeStrings.Add("");
462             keyCodeStrings.Add("");
463             keyCodeStrings.Add("");
464             keyCodeStrings.Add("");
465             keyCodeStrings.Add("");
466             keyCodeStrings.Add("");
467             keyCodeStrings.Add("A");
468             keyCodeStrings.Add("B");
469             keyCodeStrings.Add("C");
470             keyCodeStrings.Add("D");
471             keyCodeStrings.Add("E");
472             keyCodeStrings.Add("F");
473             keyCodeStrings.Add("G");
474             keyCodeStrings.Add("H");
475             keyCodeStrings.Add("I");
476             keyCodeStrings.Add("J");
477             keyCodeStrings.Add("K");
478             keyCodeStrings.Add("L");
479             keyCodeStrings.Add("M");
480             keyCodeStrings.Add("N");
481             keyCodeStrings.Add("O");
482             keyCodeStrings.Add("P");
483             keyCodeStrings.Add("Q");
484             keyCodeStrings.Add("R");
485             keyCodeStrings.Add("S");
486             keyCodeStrings.Add("T");
487             keyCodeStrings.Add("U");
488             keyCodeStrings.Add("V");
489             keyCodeStrings.Add("W");
490             keyCodeStrings.Add("X");
491             keyCodeStrings.Add("Y");
492             keyCodeStrings.Add("Z");
493             keyCodeStrings.Add("Left Windows");
494             keyCodeStrings.Add("Right Windows");
495             keyCodeStrings.Add("Apps");
496             keyCodeStrings.Add("");
497             keyCodeStrings.Add("Sleep");
498             keyCodeStrings.Add("Num pad 0");
499             keyCodeStrings.Add("Num pad 1");
500             keyCodeStrings.Add("Num pad 2");
501             keyCodeStrings.Add("Num pad 3");
502             keyCodeStrings.Add("Num pad 4");
503             keyCodeStrings.Add("Num pad 5");
504             keyCodeStrings.Add("Num pad 6");
505             keyCodeStrings.Add("Num pad 7");
506             keyCodeStrings.Add("Num pad 8");
507             keyCodeStrings.Add("Num pad 9");
508             keyCodeStrings.Add("Multiply");
509             keyCodeStrings.Add("Add");
510             keyCodeStrings.Add("Separator");
511             keyCodeStrings.Add("Subtract");
512             keyCodeStrings.Add("Decimal");
513             keyCodeStrings.Add("Divide");
514             keyCodeStrings.Add("F1");
515             keyCodeStrings.Add("F2");
516             keyCodeStrings.Add("F3");
517             keyCodeStrings.Add("F4");
518             keyCodeStrings.Add("F5");
519             keyCodeStrings.Add("F6");
520             keyCodeStrings.Add("F7");
521             keyCodeStrings.Add("F8");
522             keyCodeStrings.Add("F9");
523             keyCodeStrings.Add("F10");
524             keyCodeStrings.Add("F11");
525             keyCodeStrings.Add("F12");
526             keyCodeStrings.Add("F13");
527             keyCodeStrings.Add("F14");
528             keyCodeStrings.Add("F15");
529             keyCodeStrings.Add("F16");
530             keyCodeStrings.Add("F17");
531             keyCodeStrings.Add("F18");
532             keyCodeStrings.Add("F19");
533             keyCodeStrings.Add("F20");
534             keyCodeStrings.Add("F21");
535             keyCodeStrings.Add("F22");
536             keyCodeStrings.Add("F23");
537             keyCodeStrings.Add("F24");
538             keyCodeStrings.Add("");
539             keyCodeStrings.Add("");
540             keyCodeStrings.Add("");
541             keyCodeStrings.Add("");
542             keyCodeStrings.Add("");
543             keyCodeStrings.Add("");
544             keyCodeStrings.Add("");
545             keyCodeStrings.Add("");
546             keyCodeStrings.Add("Num Lock");
547             keyCodeStrings.Add("Scroll Lock");
548             keyCodeStrings.Add("");
549             keyCodeStrings.Add("");
550             keyCodeStrings.Add("");
551             keyCodeStrings.Add("");
552             keyCodeStrings.Add("");
553             keyCodeStrings.Add("");
554             keyCodeStrings.Add("");
555             keyCodeStrings.Add("");
556             keyCodeStrings.Add("");
557             keyCodeStrings.Add("");
558             keyCodeStrings.Add("");
559             keyCodeStrings.Add("");
560             keyCodeStrings.Add("");
561             keyCodeStrings.Add("");
562             keyCodeStrings.Add("Left Shift");
563             keyCodeStrings.Add("Right Shift");
564             keyCodeStrings.Add("Left Control");
565             keyCodeStrings.Add("Right Control");
566             keyCodeStrings.Add("Left Alt");
567             keyCodeStrings.Add("Right Alt");
568             keyCodeStrings.Add("Browser Back");
569             keyCodeStrings.Add("Browser Forward");
570             keyCodeStrings.Add("Browser Refresh");
571             keyCodeStrings.Add("Browser Stop");
572             keyCodeStrings.Add("Browser Search");
573             keyCodeStrings.Add("Browser Favorites");
574             keyCodeStrings.Add("Browser Home");
575             keyCodeStrings.Add("Volume Mute");
576             keyCodeStrings.Add("Volume Down");
577             keyCodeStrings.Add("Volume Up");
578             keyCodeStrings.Add("Media Next Track");
579             keyCodeStrings.Add("Media Prev Track");
580             keyCodeStrings.Add("Media Stop");
581             keyCodeStrings.Add("Media Play Pause");
582             keyCodeStrings.Add("Launch Mail");
583             keyCodeStrings.Add("Launch Media Select");
584             keyCodeStrings.Add("Launch Application 1");
585             keyCodeStrings.Add("Launch Application 2");
586             keyCodeStrings.Add("");
587             keyCodeStrings.Add("");
588             keyCodeStrings.Add("OEM 1");
589             keyCodeStrings.Add("OEM Plus");
590             keyCodeStrings.Add("OEM Comma");
591             keyCodeStrings.Add("OEM Minus");
592             keyCodeStrings.Add("OEM Period");
593             keyCodeStrings.Add("OEM 2");
594             keyCodeStrings.Add("OEM 3");
595             keyCodeStrings.Add("");
596             keyCodeStrings.Add("");
597             keyCodeStrings.Add("");
598             keyCodeStrings.Add("");
599             keyCodeStrings.Add("");
600             keyCodeStrings.Add("");
601             keyCodeStrings.Add("");
602             keyCodeStrings.Add("");
603             keyCodeStrings.Add("");
604             keyCodeStrings.Add("");
605             keyCodeStrings.Add("");
606             keyCodeStrings.Add("");
607             keyCodeStrings.Add("");
608             keyCodeStrings.Add("");
609             keyCodeStrings.Add("");
610             keyCodeStrings.Add("");
611             keyCodeStrings.Add("");
612             keyCodeStrings.Add("");
613             keyCodeStrings.Add("");
614             keyCodeStrings.Add("");
615             keyCodeStrings.Add("");
616             keyCodeStrings.Add("");
617             keyCodeStrings.Add("");
618             keyCodeStrings.Add("");
619             keyCodeStrings.Add("");
620             keyCodeStrings.Add("OEM 4");
621             keyCodeStrings.Add("OEM 5");
622             keyCodeStrings.Add("OEM 6");
623             keyCodeStrings.Add("OEM 7");
624             keyCodeStrings.Add("OEM 8");
625             keyCodeStrings.Add("");
626             keyCodeStrings.Add("");
627             keyCodeStrings.Add("OEM 102");
628             keyCodeStrings.Add("");
629             keyCodeStrings.Add("");
630             keyCodeStrings.Add("Process Key");
631             keyCodeStrings.Add("");
632             keyCodeStrings.Add("Packet");
633             keyCodeStrings.Add("");
634             keyCodeStrings.Add("");
635             keyCodeStrings.Add("");
636             keyCodeStrings.Add("");
637             keyCodeStrings.Add("");
638             keyCodeStrings.Add("");
639             keyCodeStrings.Add("");
640             keyCodeStrings.Add("");
641             keyCodeStrings.Add("");
642             keyCodeStrings.Add("");
643             keyCodeStrings.Add("");
644             keyCodeStrings.Add("");
645             keyCodeStrings.Add("");
646             keyCodeStrings.Add("Attention");
647             keyCodeStrings.Add("CR Select");
648             keyCodeStrings.Add("EX Select");
649             keyCodeStrings.Add("");
650             keyCodeStrings.Add("Play");
651             keyCodeStrings.Add("Zoom");
652             keyCodeStrings.Add("");
653             keyCodeStrings.Add("PA1");
654             keyCodeStrings.Add("OEM Clear");
655         }
656         private static UniquePtr<KeyCodeStrings> instance;
657         private List<string> keyCodeStrings;
658     }
659 
660     public string ToString(Keys keys)
661     {
662         string s;
663         if ((keys & Keys.controlModifier) != 0)
664         {
665             s.Append("Ctrl+");
666         }
667         if ((keys & Keys.altModifier) != 0)
668         {
669             s.Append("Alt+");
670         }
671         if ((keys & Keys.shiftModifier) != 0)
672         {
673             s.Append("Shift+");
674         }
675         Keys keyCode = cast<Keys>(keys & ~Keys.modifiers);
676         s.Append(KeyCodeStrings.Instance().GetKeyCodeString(keyCode));
677         return s;
678     }