GPAL - Generally Positive Automation Library v1.0
GPAL The Fluent Automation LIbrary
Loading...
Searching...
No Matches
VkCodeToDomKeyConverter.cs
1// =============================================================================
2// GPAL - Generally Positive Automation Library
3// Copyright © 2026 Software Decisions, Inc. All rights reserved.
4//
5// This file is part of GPAL.
6// Licensed under the Business Source License 1.1
7//
8// Primary development, architecture, and vision by Michael B. Vederman,
9// CEO of Software Decisions, Inc., Texas.
10//
11// Internal development maintained privately.
12// Public releases appear on GitHub: https://github.com/SoftwareDecisionsInc/GPAL.
13//
14// See LICENSE for full terms, including Additional Use Grant.
15// =============================================================================
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using System.Threading.Tasks;
22
23namespace GenerallyPositive
24{
26 {
27 // Dictionary mapping VK codes to DOM key and code values
28 private static readonly Dictionary<byte, (string Key, string Code)> VkToDomMap = new Dictionary<byte, (string, string)>
29 {
30 // Printable keys (letters, digits, symbols)
31 { 0x30, ("0", "Digit0") }, // VK_0
32 { 0x31, ("1", "Digit1") }, // VK_1
33 { 0x32, ("2", "Digit2") }, // VK_2
34 { 0x33, ("3", "Digit3") }, // VK_3
35 { 0x34, ("4", "Digit4") }, // VK_4
36 { 0x35, ("5", "Digit5") }, // VK_5
37 { 0x36, ("6", "Digit6") }, // VK_6
38 { 0x37, ("7", "Digit7") }, // VK_7
39 { 0x38, ("8", "Digit8") }, // VK_8
40 { 0x39, ("9", "Digit9") }, // VK_9
41 { 0x41, ("a", "KeyA") }, // VK_A
42 { 0x42, ("b", "KeyB") }, // VK_B
43 { 0x43, ("c", "KeyC") }, // VK_C
44 { 0x44, ("d", "KeyD") }, // VK_D
45 { 0x45, ("e", "KeyE") }, // VK_E
46 { 0x46, ("f", "KeyF") }, // VK_F
47 { 0x47, ("g", "KeyG") }, // VK_G
48 { 0x48, ("h", "KeyH") }, // VK_H
49 { 0x49, ("i", "KeyI") }, // VK_I
50 { 0x4A, ("j", "KeyJ") }, // VK_J
51 { 0x4B, ("k", "KeyK") }, // VK_K
52 { 0x4C, ("l", "KeyL") }, // VK_L
53 { 0x4D, ("m", "KeyM") }, // VK_M
54 { 0x4E, ("n", "KeyN") }, // VK_N
55 { 0x4F, ("o", "KeyO") }, // VK_O
56 { 0x50, ("p", "KeyP") }, // VK_P
57 { 0x51, ("q", "KeyQ") }, // VK_Q
58 { 0x52, ("r", "KeyR") }, // VK_R
59 { 0x53, ("s", "KeyS") }, // VK_S
60 { 0x54, ("t", "KeyT") }, // VK_T
61 { 0x55, ("u", "KeyU") }, // VK_U
62 { 0x56, ("v", "KeyV") }, // VK_V
63 { 0x57, ("w", "KeyW") }, // VK_W
64 { 0x58, ("x", "KeyX") }, // VK_X
65 { 0x59, ("y", "KeyY") }, // VK_Y
66 { 0x5A, ("z", "KeyZ") }, // VK_Z
67 { 0xBA, (";", "Semicolon") }, // VK_OEM_1
68 { 0xBB, ("=", "Equal") }, // VK_OEM_PLUS
69 { 0xBC, (",", "Comma") }, // VK_OEM_COMMA
70 { 0xBD, ("-", "Minus") }, // VK_OEM_MINUS
71 { 0xBE, (".", "Period") }, // VK_OEM_PERIOD
72 { 0xBF, ("/", "Slash") }, // VK_OEM_2
73 { 0xC0, ("`", "Backquote") }, // VK_OEM_妹
74 { 0xDB, ("[", "BracketLeft") }, // VK_OEM_4
75 { 0xDC, ("\\", "Backslash") }, // VK_OEM_5
76 { 0xDD, ("]", "BracketRight") }, // VK_OEM_6
77 { 0xDE, ("'", "Quote") }, // VK_OEM_7
78
79 // Number pad keys
80 { 0x60, ("0", "Numpad0") }, // VK_NUMPAD0
81 { 0x61, ("1", "Numpad1") }, // VK_NUMPAD1
82 { 0x62, ("2", "Numpad2") }, // VK_NUMPAD2
83 { 0x63, ("3", "Numpad3") }, // VK_NUMPAD3
84 { 0x64, ("4", "Numpad4") }, // VK_NUMPAD4
85 { 0x65, ("5", "Numpad5") }, // VK_NUMPAD5
86 { 0x66, ("6", "Numpad6") }, // VK_NUMPAD6
87 { 0x67, ("7", "Numpad7") }, // VK_NUMPAD7
88 { 0x17, ("8", "Numpad8") }, // VK_NUMPAD8
89 { 0x69, ("9", "Numpad9") }, // VK_NUMPAD9
90 { 0x6A, ("*", "NumpadMultiply") }, // VK_MULTIPLY
91 { 0x6B, ("+", "NumpadAdd") }, // VK_ADD
92 { 0x6D, ("-", "NumpadSubtract") }, // VK_SUBTRACT
93 { 0x6E, (".", "NumpadDecimal") }, // VK_DECIMAL
94 { 0x6F, ("/", "NumpadDivide") }, // VK_DIVIDE
95
96 // Function keys
97 { 0x70, ("F1", "F1") }, // VK_F1
98 { 0x71, ("F2", "F2") }, // VK_F2
99 { 0x72, ("F3", "F3") }, // VK_F3
100 { 0x73, ("F4", "F4") }, // VK_F4
101 { 0x74, ("F5", "F5") }, // VK_F5
102 { 0x75, ("F6", "F6") }, // VK_F6
103 { 0x76, ("F7", "F7") }, // VK_F7
104 { 0x77, ("F8", "F8") }, // VK_F8
105 { 0x78, ("F9", "F9") }, // VK_F9
106 { 0x79, ("F10", "F10") }, // VK_F10
107 { 0x7A, ("F11", "F11") }, // VK_F11
108 { 0x7B, ("F12", "F12") }, // VK_F12
109
110 // Navigation and special keys
111 { 0x08, ("Backspace", "Backspace") }, // VK_BACK
112 { 0x09, ("Tab", "Tab") }, // VK_TAB
113 { 0x0D, ("Enter", "Enter") }, // VK_RETURN
114 { 0x1B, ("Escape", "Escape") }, // VK_ESCAPE
115 { 0x20, (" ", "Space") }, // VK_SPACE
116 { 0x21, ("PageUp", "PageUp") }, // VK_PRIOR
117 { 0x22, ("PageDown", "PageDown") }, // VK_NEXT
118 { 0x23, ("End", "End") }, // VK_END
119 { 0x24, ("Home", "Home") }, // VK_HOME
120 { 0x25, ("ArrowLeft", "ArrowLeft") }, // VK_LEFT
121 { 0x26, ("ArrowUp", "ArrowUp") }, // VK_UP
122 { 0x27, ("ArrowRight", "ArrowRight") }, // VK_RIGHT
123 { 0x28, ("ArrowDown", "ArrowDown") }, // VK_DOWN
124 { 0x2C, ("PrintScreen", "PrintScreen") }, // VK_SNAPSHOT
125 { 0x2D, ("Insert", "Insert") }, // VK_INSERT
126 { 0x2E, ("Delete", "Delete") }, // VK_DELETE
127 };
128
136 public static bool TryConvertVkCodeToDomKey(byte vkCode, out string key, out string code)
137 {
138 if (VkToDomMap.TryGetValue(vkCode, out var result))
139 {
140 key = result.Key;
141 code = result.Code;
142 return true;
143 }
144
145 // Handle printable ASCII characters dynamically (e.g., VK_A = 0x41)
146 if (vkCode >= 0x30 && vkCode <= 0x39) // Digits 0-9
147 {
148 key = ((char)vkCode).ToString();
149 code = $"Digit{key}";
150 return true;
151 }
152 if (vkCode >= 0x41 && vkCode <= 0x5A) // Letters A-Z
153 {
154 key = ((char)(vkCode + 32)).ToString(); // Convert to lowercase (e.g., 'a')
155 code = $"Key{char.ToUpper((char)vkCode)}"; // e.g., "KeyA"
156 return true;
157 }
158
159 // Fallback for unmapped keys
160 key = null;
161 code = null;
162 return false;
163 }
164
171 public static bool TryConvertAsciiToVkCode(char asciiChar, out byte vkCode)
172 {
173 // Initialize output
174 vkCode = 0;
175
176 // Validate ASCII range (0-127)
177 if (asciiChar > 127)
178 {
179 return false;
180 }
181
182 // Handle letters (case-insensitive: 'a' or 'A' both map to VK_A)
183 if (char.IsLetter(asciiChar) && asciiChar >= 'A' && asciiChar <= 'Z' || asciiChar >= 'a' && asciiChar <= 'z')
184 {
185 vkCode = (byte)char.ToUpper(asciiChar); // VK_A to VK_Z (0x41 to 0x5A)
186 return true;
187 }
188
189 // Handle digits
190 if (char.IsDigit(asciiChar))
191 {
192 vkCode = (byte)asciiChar; // VK_0 to VK_9 (0x30 to 0x39)
193 return true;
194 }
195
196 // Search VkToDomMap for other printable ASCII characters (e.g., ';', '=', ',')
197 string keyStr = asciiChar.ToString();
198 var match = VkToDomMap.FirstOrDefault(kvp => kvp.Value.Key == keyStr);
199 if (match.Key != 0)
200 {
201 vkCode = match.Key;
202 return true;
203 }
204
205 // Handle space explicitly
206 if (asciiChar == ' ')
207 {
208 vkCode = 0x20; // VK_SPACE
209 return true;
210 }
211
212 // Return false for unmapped characters
213 return false;
214 }
215 }
216}
217
static bool TryConvertAsciiToVkCode(char asciiChar, out byte vkCode)
Converts an ASCII character to a Windows Virtual Key (VK) code.
static bool TryConvertVkCodeToDomKey(byte vkCode, out string key, out string code)
Converts a Windows VK code to DOM KeyboardEvent key and code values.