1use crate::error::WHKError;
2use std::hash::Hash;
3
4#[derive(Debug, Clone, Copy)]
10pub enum VKey {
11 Back,
12 Tab,
13 Clear,
14 Return,
15 Shift,
16 Control,
17 Menu,
18 Pause,
19 Capital,
20 Escape,
21 Space,
22 Prior,
23 Next,
24 End,
25 Home,
26 Left,
27 Up,
28 Right,
29 Down,
30 Select,
31 Print,
32 Execute,
33 Snapshot,
34 Insert,
35 Delete,
36 Help,
37 LWin,
38 RWin,
39 Apps,
40 Sleep,
41 Numpad0,
42 Numpad1,
43 Numpad2,
44 Numpad3,
45 Numpad4,
46 Numpad5,
47 Numpad6,
48 Numpad7,
49 Numpad8,
50 Numpad9,
51 Multiply,
52 Add,
53 Separator,
54 Subtract,
55 Decimal,
56 Divide,
57 F1,
58 F2,
59 F3,
60 F4,
61 F5,
62 F6,
63 F7,
64 F8,
65 F9,
66 F10,
67 F11,
68 F12,
69 F13,
70 F14,
71 F15,
72 F16,
73 F17,
74 F18,
75 F19,
76 F20,
77 F21,
78 F22,
79 F23,
80 F24,
81 Numlock,
82 Scroll,
83 LShift,
84 RShift,
85 LControl,
86 RControl,
87 LMenu,
88 RMenu,
89 BrowserBack,
90 BrowserForward,
91 BrowserRefresh,
92 BrowserStop,
93 BrowserSearch,
94 BrowserFavorites,
95 BrowserHome,
96 VolumeMute,
97 VolumeDown,
98 VolumeUp,
99 MediaNextTrack,
100 MediaPrevTrack,
101 MediaStop,
102 MediaPlayPause,
103 LaunchMail,
104 LaunchMediaSelect,
105 LaunchApp1,
106 LaunchApp2,
107 Oem1,
108 OemPlus,
109 OemComma,
110 OemMinus,
111 OemPeriod,
112 Oem2,
113 Oem3,
114 Oem4,
115 Oem5,
116 Oem6,
117 Oem7,
118 Oem8,
119 Oem102,
120 Attn,
121 Crsel,
122 Exsel,
123 Play,
124 Zoom,
125 Pa1,
126 OemClear,
127 Vk0,
128 Vk1,
129 Vk2,
130 Vk3,
131 Vk4,
132 Vk5,
133 Vk6,
134 Vk7,
135 Vk8,
136 Vk9,
137 A,
138 B,
139 C,
140 D,
141 E,
142 F,
143 G,
144 H,
145 I,
146 J,
147 K,
148 L,
149 M,
150 N,
151 O,
152 P,
153 Q,
154 R,
155 S,
156 T,
157 U,
158 V,
159 W,
160 X,
161 Y,
162 Z,
163 CustomKeyCode(u16),
164}
165
166impl VKey {
167 pub const fn to_vk_code(&self) -> u16 {
173 use windows::Win32::UI::Input::KeyboardAndMouse::*;
174 match self {
175 VKey::Back => VK_BACK.0,
176 VKey::Tab => VK_TAB.0,
177 VKey::Clear => VK_CLEAR.0,
178 VKey::Return => VK_RETURN.0,
179 VKey::Shift => VK_SHIFT.0,
180 VKey::Control => VK_CONTROL.0,
181 VKey::Menu => VK_MENU.0,
182 VKey::Pause => VK_PAUSE.0,
183 VKey::Capital => VK_CAPITAL.0,
184 VKey::Escape => VK_ESCAPE.0,
185 VKey::Space => VK_SPACE.0,
186 VKey::Prior => VK_PRIOR.0,
187 VKey::Next => VK_NEXT.0,
188 VKey::End => VK_END.0,
189 VKey::Home => VK_HOME.0,
190 VKey::Left => VK_LEFT.0,
191 VKey::Up => VK_UP.0,
192 VKey::Right => VK_RIGHT.0,
193 VKey::Down => VK_DOWN.0,
194 VKey::Select => VK_SELECT.0,
195 VKey::Print => VK_PRINT.0,
196 VKey::Execute => VK_EXECUTE.0,
197 VKey::Snapshot => VK_SNAPSHOT.0,
198 VKey::Insert => VK_INSERT.0,
199 VKey::Delete => VK_DELETE.0,
200 VKey::Help => VK_HELP.0,
201 VKey::LWin => VK_LWIN.0,
202 VKey::RWin => VK_RWIN.0,
203 VKey::Apps => VK_APPS.0,
204 VKey::Sleep => VK_SLEEP.0,
205 VKey::Numpad0 => VK_NUMPAD0.0,
206 VKey::Numpad1 => VK_NUMPAD1.0,
207 VKey::Numpad2 => VK_NUMPAD2.0,
208 VKey::Numpad3 => VK_NUMPAD3.0,
209 VKey::Numpad4 => VK_NUMPAD4.0,
210 VKey::Numpad5 => VK_NUMPAD5.0,
211 VKey::Numpad6 => VK_NUMPAD6.0,
212 VKey::Numpad7 => VK_NUMPAD7.0,
213 VKey::Numpad8 => VK_NUMPAD8.0,
214 VKey::Numpad9 => VK_NUMPAD9.0,
215 VKey::Multiply => VK_MULTIPLY.0,
216 VKey::Add => VK_ADD.0,
217 VKey::Separator => VK_SEPARATOR.0,
218 VKey::Subtract => VK_SUBTRACT.0,
219 VKey::Decimal => VK_DECIMAL.0,
220 VKey::Divide => VK_DIVIDE.0,
221 VKey::F1 => VK_F1.0,
222 VKey::F2 => VK_F2.0,
223 VKey::F3 => VK_F3.0,
224 VKey::F4 => VK_F4.0,
225 VKey::F5 => VK_F5.0,
226 VKey::F6 => VK_F6.0,
227 VKey::F7 => VK_F7.0,
228 VKey::F8 => VK_F8.0,
229 VKey::F9 => VK_F9.0,
230 VKey::F10 => VK_F10.0,
231 VKey::F11 => VK_F11.0,
232 VKey::F12 => VK_F12.0,
233 VKey::F13 => VK_F13.0,
234 VKey::F14 => VK_F14.0,
235 VKey::F15 => VK_F15.0,
236 VKey::F16 => VK_F16.0,
237 VKey::F17 => VK_F17.0,
238 VKey::F18 => VK_F18.0,
239 VKey::F19 => VK_F19.0,
240 VKey::F20 => VK_F20.0,
241 VKey::F21 => VK_F21.0,
242 VKey::F22 => VK_F22.0,
243 VKey::F23 => VK_F23.0,
244 VKey::F24 => VK_F24.0,
245 VKey::Numlock => VK_NUMLOCK.0,
246 VKey::Scroll => VK_SCROLL.0,
247 VKey::LShift => VK_LSHIFT.0,
248 VKey::RShift => VK_RSHIFT.0,
249 VKey::LControl => VK_LCONTROL.0,
250 VKey::RControl => VK_RCONTROL.0,
251 VKey::LMenu => VK_LMENU.0,
252 VKey::RMenu => VK_RMENU.0,
253 VKey::BrowserBack => VK_BROWSER_BACK.0,
254 VKey::BrowserForward => VK_BROWSER_FORWARD.0,
255 VKey::BrowserRefresh => VK_BROWSER_REFRESH.0,
256 VKey::BrowserStop => VK_BROWSER_STOP.0,
257 VKey::BrowserSearch => VK_BROWSER_SEARCH.0,
258 VKey::BrowserFavorites => VK_BROWSER_FAVORITES.0,
259 VKey::BrowserHome => VK_BROWSER_HOME.0,
260 VKey::VolumeMute => VK_VOLUME_MUTE.0,
261 VKey::VolumeDown => VK_VOLUME_DOWN.0,
262 VKey::VolumeUp => VK_VOLUME_UP.0,
263 VKey::MediaNextTrack => VK_MEDIA_NEXT_TRACK.0,
264 VKey::MediaPrevTrack => VK_MEDIA_PREV_TRACK.0,
265 VKey::MediaStop => VK_MEDIA_STOP.0,
266 VKey::MediaPlayPause => VK_MEDIA_PLAY_PAUSE.0,
267 VKey::LaunchMail => VK_LAUNCH_MAIL.0,
268 VKey::LaunchMediaSelect => VK_LAUNCH_MEDIA_SELECT.0,
269 VKey::LaunchApp1 => VK_LAUNCH_APP1.0,
270 VKey::LaunchApp2 => VK_LAUNCH_APP2.0,
271 VKey::Oem1 => VK_OEM_1.0,
272 VKey::OemPlus => VK_OEM_PLUS.0,
273 VKey::OemComma => VK_OEM_COMMA.0,
274 VKey::OemMinus => VK_OEM_MINUS.0,
275 VKey::OemPeriod => VK_OEM_PERIOD.0,
276 VKey::Oem2 => VK_OEM_2.0,
277 VKey::Oem3 => VK_OEM_3.0,
278 VKey::Oem4 => VK_OEM_4.0,
279 VKey::Oem5 => VK_OEM_5.0,
280 VKey::Oem6 => VK_OEM_6.0,
281 VKey::Oem7 => VK_OEM_7.0,
282 VKey::Oem8 => VK_OEM_8.0,
283 VKey::Oem102 => VK_OEM_102.0,
284 VKey::Attn => VK_ATTN.0,
285 VKey::Crsel => VK_CRSEL.0,
286 VKey::Exsel => VK_EXSEL.0,
287 VKey::Play => VK_PLAY.0,
288 VKey::Zoom => VK_ZOOM.0,
289 VKey::Pa1 => VK_PA1.0,
290 VKey::OemClear => VK_OEM_CLEAR.0,
291 VKey::Vk0 => VK_0.0,
292 VKey::Vk1 => VK_1.0,
293 VKey::Vk2 => VK_2.0,
294 VKey::Vk3 => VK_3.0,
295 VKey::Vk4 => VK_4.0,
296 VKey::Vk5 => VK_5.0,
297 VKey::Vk6 => VK_6.0,
298 VKey::Vk7 => VK_7.0,
299 VKey::Vk8 => VK_8.0,
300 VKey::Vk9 => VK_9.0,
301 VKey::A => VK_A.0,
302 VKey::B => VK_B.0,
303 VKey::C => VK_C.0,
304 VKey::D => VK_D.0,
305 VKey::E => VK_E.0,
306 VKey::F => VK_F.0,
307 VKey::G => VK_G.0,
308 VKey::H => VK_H.0,
309 VKey::I => VK_I.0,
310 VKey::J => VK_J.0,
311 VKey::K => VK_K.0,
312 VKey::L => VK_L.0,
313 VKey::M => VK_M.0,
314 VKey::N => VK_N.0,
315 VKey::O => VK_O.0,
316 VKey::P => VK_P.0,
317 VKey::Q => VK_Q.0,
318 VKey::R => VK_R.0,
319 VKey::S => VK_S.0,
320 VKey::T => VK_T.0,
321 VKey::U => VK_U.0,
322 VKey::V => VK_V.0,
323 VKey::W => VK_W.0,
324 VKey::X => VK_X.0,
325 VKey::Y => VK_Y.0,
326 VKey::Z => VK_Z.0,
327 VKey::CustomKeyCode(vk) => *vk,
328 }
329 }
330
331 pub const fn from_vk_code(vk_code: u16) -> VKey {
337 use windows::Win32::UI::Input::KeyboardAndMouse::*;
338 match vk_code {
339 _ if vk_code == VK_BACK.0 => VKey::Back,
340 _ if vk_code == VK_TAB.0 => VKey::Tab,
341 _ if vk_code == VK_CLEAR.0 => VKey::Clear,
342 _ if vk_code == VK_RETURN.0 => VKey::Return,
343 _ if vk_code == VK_SHIFT.0 => VKey::Shift,
344 _ if vk_code == VK_CONTROL.0 => VKey::Control,
345 _ if vk_code == VK_MENU.0 => VKey::Menu,
346 _ if vk_code == VK_PAUSE.0 => VKey::Pause,
347 _ if vk_code == VK_CAPITAL.0 => VKey::Capital,
348 _ if vk_code == VK_ESCAPE.0 => VKey::Escape,
349 _ if vk_code == VK_SPACE.0 => VKey::Space,
350 _ if vk_code == VK_PRIOR.0 => VKey::Prior,
351 _ if vk_code == VK_NEXT.0 => VKey::Next,
352 _ if vk_code == VK_END.0 => VKey::End,
353 _ if vk_code == VK_HOME.0 => VKey::Home,
354 _ if vk_code == VK_LEFT.0 => VKey::Left,
355 _ if vk_code == VK_UP.0 => VKey::Up,
356 _ if vk_code == VK_RIGHT.0 => VKey::Right,
357 _ if vk_code == VK_DOWN.0 => VKey::Down,
358 _ if vk_code == VK_SELECT.0 => VKey::Select,
359 _ if vk_code == VK_PRINT.0 => VKey::Print,
360 _ if vk_code == VK_EXECUTE.0 => VKey::Execute,
361 _ if vk_code == VK_SNAPSHOT.0 => VKey::Snapshot,
362 _ if vk_code == VK_INSERT.0 => VKey::Insert,
363 _ if vk_code == VK_DELETE.0 => VKey::Delete,
364 _ if vk_code == VK_HELP.0 => VKey::Help,
365 _ if vk_code == VK_LWIN.0 => VKey::LWin,
366 _ if vk_code == VK_RWIN.0 => VKey::RWin,
367 _ if vk_code == VK_APPS.0 => VKey::Apps,
368 _ if vk_code == VK_SLEEP.0 => VKey::Sleep,
369 _ if vk_code == VK_NUMPAD0.0 => VKey::Numpad0,
370 _ if vk_code == VK_NUMPAD1.0 => VKey::Numpad1,
371 _ if vk_code == VK_NUMPAD2.0 => VKey::Numpad2,
372 _ if vk_code == VK_NUMPAD3.0 => VKey::Numpad3,
373 _ if vk_code == VK_NUMPAD4.0 => VKey::Numpad4,
374 _ if vk_code == VK_NUMPAD5.0 => VKey::Numpad5,
375 _ if vk_code == VK_NUMPAD6.0 => VKey::Numpad6,
376 _ if vk_code == VK_NUMPAD7.0 => VKey::Numpad7,
377 _ if vk_code == VK_NUMPAD8.0 => VKey::Numpad8,
378 _ if vk_code == VK_NUMPAD9.0 => VKey::Numpad9,
379 _ if vk_code == VK_MULTIPLY.0 => VKey::Multiply,
380 _ if vk_code == VK_ADD.0 => VKey::Add,
381 _ if vk_code == VK_SEPARATOR.0 => VKey::Separator,
382 _ if vk_code == VK_SUBTRACT.0 => VKey::Subtract,
383 _ if vk_code == VK_DECIMAL.0 => VKey::Decimal,
384 _ if vk_code == VK_DIVIDE.0 => VKey::Divide,
385 _ if vk_code == VK_F1.0 => VKey::F1,
386 _ if vk_code == VK_F2.0 => VKey::F2,
387 _ if vk_code == VK_F3.0 => VKey::F3,
388 _ if vk_code == VK_F4.0 => VKey::F4,
389 _ if vk_code == VK_F5.0 => VKey::F5,
390 _ if vk_code == VK_F6.0 => VKey::F6,
391 _ if vk_code == VK_F7.0 => VKey::F7,
392 _ if vk_code == VK_F8.0 => VKey::F8,
393 _ if vk_code == VK_F9.0 => VKey::F9,
394 _ if vk_code == VK_F10.0 => VKey::F10,
395 _ if vk_code == VK_F11.0 => VKey::F11,
396 _ if vk_code == VK_F12.0 => VKey::F12,
397 _ if vk_code == VK_F13.0 => VKey::F13,
398 _ if vk_code == VK_F14.0 => VKey::F14,
399 _ if vk_code == VK_F15.0 => VKey::F15,
400 _ if vk_code == VK_F16.0 => VKey::F16,
401 _ if vk_code == VK_F17.0 => VKey::F17,
402 _ if vk_code == VK_F18.0 => VKey::F18,
403 _ if vk_code == VK_F19.0 => VKey::F19,
404 _ if vk_code == VK_F20.0 => VKey::F20,
405 _ if vk_code == VK_F21.0 => VKey::F21,
406 _ if vk_code == VK_F22.0 => VKey::F22,
407 _ if vk_code == VK_F23.0 => VKey::F23,
408 _ if vk_code == VK_F24.0 => VKey::F24,
409 _ if vk_code == VK_NUMLOCK.0 => VKey::Numlock,
410 _ if vk_code == VK_SCROLL.0 => VKey::Scroll,
411 _ if vk_code == VK_LSHIFT.0 => VKey::LShift,
412 _ if vk_code == VK_RSHIFT.0 => VKey::RShift,
413 _ if vk_code == VK_LCONTROL.0 => VKey::LControl,
414 _ if vk_code == VK_RCONTROL.0 => VKey::RControl,
415 _ if vk_code == VK_LMENU.0 => VKey::LMenu,
416 _ if vk_code == VK_RMENU.0 => VKey::RMenu,
417 _ if vk_code == VK_BROWSER_BACK.0 => VKey::BrowserBack,
418 _ if vk_code == VK_BROWSER_FORWARD.0 => VKey::BrowserForward,
419 _ if vk_code == VK_BROWSER_REFRESH.0 => VKey::BrowserRefresh,
420 _ if vk_code == VK_BROWSER_STOP.0 => VKey::BrowserStop,
421 _ if vk_code == VK_BROWSER_SEARCH.0 => VKey::BrowserSearch,
422 _ if vk_code == VK_BROWSER_FAVORITES.0 => VKey::BrowserFavorites,
423 _ if vk_code == VK_BROWSER_HOME.0 => VKey::BrowserHome,
424 _ if vk_code == VK_VOLUME_MUTE.0 => VKey::VolumeMute,
425 _ if vk_code == VK_VOLUME_DOWN.0 => VKey::VolumeDown,
426 _ if vk_code == VK_VOLUME_UP.0 => VKey::VolumeUp,
427 _ if vk_code == VK_MEDIA_NEXT_TRACK.0 => VKey::MediaNextTrack,
428 _ if vk_code == VK_MEDIA_PREV_TRACK.0 => VKey::MediaPrevTrack,
429 _ if vk_code == VK_MEDIA_STOP.0 => VKey::MediaStop,
430 _ if vk_code == VK_MEDIA_PLAY_PAUSE.0 => VKey::MediaPlayPause,
431 _ if vk_code == VK_LAUNCH_MAIL.0 => VKey::LaunchMail,
432 _ if vk_code == VK_LAUNCH_MEDIA_SELECT.0 => VKey::LaunchMediaSelect,
433 _ if vk_code == VK_LAUNCH_APP1.0 => VKey::LaunchApp1,
434 _ if vk_code == VK_LAUNCH_APP2.0 => VKey::LaunchApp2,
435 _ if vk_code == VK_OEM_1.0 => VKey::Oem1,
436 _ if vk_code == VK_OEM_PLUS.0 => VKey::OemPlus,
437 _ if vk_code == VK_OEM_COMMA.0 => VKey::OemComma,
438 _ if vk_code == VK_OEM_MINUS.0 => VKey::OemMinus,
439 _ if vk_code == VK_OEM_PERIOD.0 => VKey::OemPeriod,
440 _ if vk_code == VK_OEM_2.0 => VKey::Oem2,
441 _ if vk_code == VK_OEM_3.0 => VKey::Oem3,
442 _ if vk_code == VK_OEM_4.0 => VKey::Oem4,
443 _ if vk_code == VK_OEM_5.0 => VKey::Oem5,
444 _ if vk_code == VK_OEM_6.0 => VKey::Oem6,
445 _ if vk_code == VK_OEM_7.0 => VKey::Oem7,
446 _ if vk_code == VK_OEM_8.0 => VKey::Oem8,
447 _ if vk_code == VK_OEM_102.0 => VKey::Oem102,
448 _ if vk_code == VK_ATTN.0 => VKey::Attn,
449 _ if vk_code == VK_CRSEL.0 => VKey::Crsel,
450 _ if vk_code == VK_EXSEL.0 => VKey::Exsel,
451 _ if vk_code == VK_PLAY.0 => VKey::Play,
452 _ if vk_code == VK_ZOOM.0 => VKey::Zoom,
453 _ if vk_code == VK_PA1.0 => VKey::Pa1,
454 _ if vk_code == VK_OEM_CLEAR.0 => VKey::OemClear,
455 _ if vk_code == VK_0.0 => VKey::Vk0,
456 _ if vk_code == VK_1.0 => VKey::Vk1,
457 _ if vk_code == VK_2.0 => VKey::Vk2,
458 _ if vk_code == VK_3.0 => VKey::Vk3,
459 _ if vk_code == VK_4.0 => VKey::Vk4,
460 _ if vk_code == VK_5.0 => VKey::Vk5,
461 _ if vk_code == VK_6.0 => VKey::Vk6,
462 _ if vk_code == VK_7.0 => VKey::Vk7,
463 _ if vk_code == VK_8.0 => VKey::Vk8,
464 _ if vk_code == VK_9.0 => VKey::Vk9,
465 _ if vk_code == VK_A.0 => VKey::A,
466 _ if vk_code == VK_B.0 => VKey::B,
467 _ if vk_code == VK_C.0 => VKey::C,
468 _ if vk_code == VK_D.0 => VKey::D,
469 _ if vk_code == VK_E.0 => VKey::E,
470 _ if vk_code == VK_F.0 => VKey::F,
471 _ if vk_code == VK_G.0 => VKey::G,
472 _ if vk_code == VK_H.0 => VKey::H,
473 _ if vk_code == VK_I.0 => VKey::I,
474 _ if vk_code == VK_J.0 => VKey::J,
475 _ if vk_code == VK_K.0 => VKey::K,
476 _ if vk_code == VK_L.0 => VKey::L,
477 _ if vk_code == VK_M.0 => VKey::M,
478 _ if vk_code == VK_N.0 => VKey::N,
479 _ if vk_code == VK_O.0 => VKey::O,
480 _ if vk_code == VK_P.0 => VKey::P,
481 _ if vk_code == VK_Q.0 => VKey::Q,
482 _ if vk_code == VK_R.0 => VKey::R,
483 _ if vk_code == VK_S.0 => VKey::S,
484 _ if vk_code == VK_T.0 => VKey::T,
485 _ if vk_code == VK_U.0 => VKey::U,
486 _ if vk_code == VK_V.0 => VKey::V,
487 _ if vk_code == VK_W.0 => VKey::W,
488 _ if vk_code == VK_X.0 => VKey::X,
489 _ if vk_code == VK_Y.0 => VKey::Y,
490 _ if vk_code == VK_Z.0 => VKey::Z,
491 _ => VKey::CustomKeyCode(vk_code),
492 }
493 }
494
495 pub fn from_keyname(name: &str) -> Result<VKey, WHKError> {
507 let name = name.to_ascii_uppercase();
508
509 if name.len() >= 3 && name.len() <= 6 && name.starts_with("0x") || name.starts_with("0X") {
511 return if let Ok(val) = u16::from_str_radix(&name[2..], 16) {
512 Ok(Self::from_vk_code(val))
513 } else {
514 Err(WHKError::InvalidKey(name))
515 };
516 }
517
518 Ok(match name.trim_start_matches("VK_") {
519 "BACK" => VKey::Back,
520 "TAB" => VKey::Tab,
521 "CLEAR" => VKey::Clear,
522 "RETURN" => VKey::Return,
523 "SHIFT" => VKey::Shift,
524 "CTRL" => VKey::Control,
525 "CONTROL" => VKey::Control,
526 "ALT" => VKey::Menu,
527 "MENU" => VKey::Menu,
528 "PAUSE" => VKey::Pause,
529 "CAPITAL" => VKey::Capital,
530 "ESCAPE" => VKey::Escape,
531 "SPACE" => VKey::Space,
532 "PRIOR" => VKey::Prior,
533 "NEXT" => VKey::Next,
534 "END" => VKey::End,
535 "HOME" => VKey::Home,
536 "LEFT" => VKey::Left,
537 "UP" => VKey::Up,
538 "RIGHT" => VKey::Right,
539 "DOWN" => VKey::Down,
540 "SELECT" => VKey::Select,
541 "PRINT" => VKey::Print,
542 "EXECUTE" => VKey::Execute,
543 "SNAPSHOT" => VKey::Snapshot,
544 "INSERT" => VKey::Insert,
545 "DELETE" => VKey::Delete,
546 "HELP" => VKey::Help,
547 "WIN" => VKey::LWin,
548 "LWIN" => VKey::LWin,
549 "RWIN" => VKey::RWin,
550 "APPS" => VKey::Apps,
551 "SLEEP" => VKey::Sleep,
552 "NUMPAD0" => VKey::Numpad0,
553 "NUMPAD1" => VKey::Numpad1,
554 "NUMPAD2" => VKey::Numpad2,
555 "NUMPAD3" => VKey::Numpad3,
556 "NUMPAD4" => VKey::Numpad4,
557 "NUMPAD5" => VKey::Numpad5,
558 "NUMPAD6" => VKey::Numpad6,
559 "NUMPAD7" => VKey::Numpad7,
560 "NUMPAD8" => VKey::Numpad8,
561 "NUMPAD9" => VKey::Numpad9,
562 "MULTIPLY" => VKey::Multiply,
563 "ADD" => VKey::Add,
564 "SEPARATOR" => VKey::Separator,
565 "SUBTRACT" => VKey::Subtract,
566 "DECIMAL" => VKey::Decimal,
567 "DIVIDE" => VKey::Divide,
568 "F1" => VKey::F1,
569 "F2" => VKey::F2,
570 "F3" => VKey::F3,
571 "F4" => VKey::F4,
572 "F5" => VKey::F5,
573 "F6" => VKey::F6,
574 "F7" => VKey::F7,
575 "F8" => VKey::F8,
576 "F9" => VKey::F9,
577 "F10" => VKey::F10,
578 "F11" => VKey::F11,
579 "F12" => VKey::F12,
580 "F13" => VKey::F13,
581 "F14" => VKey::F14,
582 "F15" => VKey::F15,
583 "F16" => VKey::F16,
584 "F17" => VKey::F17,
585 "F18" => VKey::F18,
586 "F19" => VKey::F19,
587 "F20" => VKey::F20,
588 "F21" => VKey::F21,
589 "F22" => VKey::F22,
590 "F23" => VKey::F23,
591 "F24" => VKey::F24,
592 "NUMLOCK" => VKey::Numlock,
593 "SCROLL" => VKey::Scroll,
594 "LSHIFT" => VKey::LShift,
595 "RSHIFT" => VKey::RShift,
596 "LCTRL" => VKey::LControl,
597 "LCONTROL" => VKey::LControl,
598 "RCTRL" => VKey::RControl,
599 "RCONTROL" => VKey::RControl,
600 "LALT" => VKey::LMenu,
601 "LMENU" => VKey::LMenu,
602 "RALT" => VKey::RMenu,
603 "RMENU" => VKey::RMenu,
604 "BROWSER_BACK" => VKey::BrowserBack,
605 "BROWSER_FORWARD" => VKey::BrowserForward,
606 "BROWSER_REFRESH" => VKey::BrowserRefresh,
607 "BROWSER_STOP" => VKey::BrowserStop,
608 "BROWSER_SEARCH" => VKey::BrowserSearch,
609 "BROWSER_FAVORITES" => VKey::BrowserFavorites,
610 "BROWSER_HOME" => VKey::BrowserHome,
611 "VOLUME_MUTE" => VKey::VolumeMute,
612 "VOLUME_DOWN" => VKey::VolumeDown,
613 "VOLUME_UP" => VKey::VolumeUp,
614 "MEDIA_NEXT_TRACK" => VKey::MediaNextTrack,
615 "MEDIA_PREV_TRACK" => VKey::MediaPrevTrack,
616 "MEDIA_STOP" => VKey::MediaStop,
617 "MEDIA_PLAY_PAUSE" => VKey::MediaPlayPause,
618 "LAUNCH_MAIL" => VKey::LaunchMail,
619 "LAUNCH_MEDIA_SELECT" => VKey::LaunchMediaSelect,
620 "LAUNCH_APP1" => VKey::LaunchApp1,
621 "LAUNCH_APP2" => VKey::LaunchApp2,
622 "OEM_1" => VKey::Oem1,
623 "OEM_PLUS" => VKey::OemPlus,
624 "OEM_COMMA" => VKey::OemComma,
625 "OEM_MINUS" => VKey::OemMinus,
626 "OEM_PERIOD" => VKey::OemPeriod,
627 "OEM_2" => VKey::Oem2,
628 "OEM_3" => VKey::Oem3,
629 "OEM_4" => VKey::Oem4,
630 "OEM_5" => VKey::Oem5,
631 "OEM_6" => VKey::Oem6,
632 "OEM_7" => VKey::Oem7,
633 "OEM_8" => VKey::Oem8,
634 "OEM_102" => VKey::Oem102,
635 "ATTN" => VKey::Attn,
636 "CRSEL" => VKey::Crsel,
637 "EXSEL" => VKey::Exsel,
638 "PLAY" => VKey::Play,
639 "ZOOM" => VKey::Zoom,
640 "PA1" => VKey::Pa1,
641 "OEM_CLEAR" => VKey::OemClear,
642 "0" => VKey::Vk0,
643 "1" => VKey::Vk1,
644 "2" => VKey::Vk2,
645 "3" => VKey::Vk3,
646 "4" => VKey::Vk4,
647 "5" => VKey::Vk5,
648 "6" => VKey::Vk6,
649 "7" => VKey::Vk7,
650 "8" => VKey::Vk8,
651 "9" => VKey::Vk9,
652 "A" => VKey::A,
653 "B" => VKey::B,
654 "C" => VKey::C,
655 "D" => VKey::D,
656 "E" => VKey::E,
657 "F" => VKey::F,
658 "G" => VKey::G,
659 "H" => VKey::H,
660 "I" => VKey::I,
661 "J" => VKey::J,
662 "K" => VKey::K,
663 "L" => VKey::L,
664 "M" => VKey::M,
665 "N" => VKey::N,
666 "O" => VKey::O,
667 "P" => VKey::P,
668 "Q" => VKey::Q,
669 "R" => VKey::R,
670 "S" => VKey::S,
671 "T" => VKey::T,
672 "U" => VKey::U,
673 "V" => VKey::V,
674 "W" => VKey::W,
675 "X" => VKey::X,
676 "Y" => VKey::Y,
677 "Z" => VKey::Z,
678 _ => return Err(WHKError::InvalidKey(name)),
679 })
680 }
681}
682
683impl std::fmt::Display for VKey {
684 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
685 let name = match self {
686 VKey::Back => "VK_BACK",
687 VKey::Tab => "VK_TAB",
688 VKey::Clear => "VK_CLEAR",
689 VKey::Return => "VK_RETURN",
690 VKey::Shift => "VK_SHIFT",
691 VKey::Control => "VK_CONTROL",
692 VKey::Menu => "VK_MENU",
693 VKey::Pause => "VK_PAUSE",
694 VKey::Capital => "VK_CAPITAL",
695 VKey::Escape => "VK_ESCAPE",
696 VKey::Space => "VK_SPACE",
697 VKey::Prior => "VK_PRIOR",
698 VKey::Next => "VK_NEXT",
699 VKey::End => "VK_END",
700 VKey::Home => "VK_HOME",
701 VKey::Left => "VK_LEFT",
702 VKey::Up => "VK_UP",
703 VKey::Right => "VK_RIGHT",
704 VKey::Down => "VK_DOWN",
705 VKey::Select => "VK_SELECT",
706 VKey::Print => "VK_PRINT",
707 VKey::Execute => "VK_EXECUTE",
708 VKey::Snapshot => "VK_SNAPSHOT",
709 VKey::Insert => "VK_INSERT",
710 VKey::Delete => "VK_DELETE",
711 VKey::Help => "VK_HELP",
712 VKey::LWin => "VK_LWIN",
713 VKey::RWin => "VK_RWIN",
714 VKey::Apps => "VK_APPS",
715 VKey::Sleep => "VK_SLEEP",
716 VKey::Numpad0 => "VK_NUMPAD0",
717 VKey::Numpad1 => "VK_NUMPAD1",
718 VKey::Numpad2 => "VK_NUMPAD2",
719 VKey::Numpad3 => "VK_NUMPAD3",
720 VKey::Numpad4 => "VK_NUMPAD4",
721 VKey::Numpad5 => "VK_NUMPAD5",
722 VKey::Numpad6 => "VK_NUMPAD6",
723 VKey::Numpad7 => "VK_NUMPAD7",
724 VKey::Numpad8 => "VK_NUMPAD8",
725 VKey::Numpad9 => "VK_NUMPAD9",
726 VKey::Multiply => "VK_MULTIPLY",
727 VKey::Add => "VK_ADD",
728 VKey::Separator => "VK_SEPARATOR",
729 VKey::Subtract => "VK_SUBTRACT",
730 VKey::Decimal => "VK_DECIMAL",
731 VKey::Divide => "VK_DIVIDE",
732 VKey::F1 => "VK_F1",
733 VKey::F2 => "VK_F2",
734 VKey::F3 => "VK_F3",
735 VKey::F4 => "VK_F4",
736 VKey::F5 => "VK_F5",
737 VKey::F6 => "VK_F6",
738 VKey::F7 => "VK_F7",
739 VKey::F8 => "VK_F8",
740 VKey::F9 => "VK_F9",
741 VKey::F10 => "VK_F10",
742 VKey::F11 => "VK_F11",
743 VKey::F12 => "VK_F12",
744 VKey::F13 => "VK_F13",
745 VKey::F14 => "VK_F14",
746 VKey::F15 => "VK_F15",
747 VKey::F16 => "VK_F16",
748 VKey::F17 => "VK_F17",
749 VKey::F18 => "VK_F18",
750 VKey::F19 => "VK_F19",
751 VKey::F20 => "VK_F20",
752 VKey::F21 => "VK_F21",
753 VKey::F22 => "VK_F22",
754 VKey::F23 => "VK_F23",
755 VKey::F24 => "VK_F24",
756 VKey::Numlock => "VK_NUMLOCK",
757 VKey::Scroll => "VK_SCROLL",
758 VKey::LShift => "VK_LSHIFT",
759 VKey::RShift => "VK_RSHIFT",
760 VKey::LControl => "VK_LCONTROL",
761 VKey::RControl => "VK_RCONTROL",
762 VKey::LMenu => "VK_LMENU",
763 VKey::RMenu => "VK_RMENU",
764 VKey::BrowserBack => "VK_BROWSER_BACK",
765 VKey::BrowserForward => "VK_BROWSER_FORWARD",
766 VKey::BrowserRefresh => "VK_BROWSER_REFRESH",
767 VKey::BrowserStop => "VK_BROWSER_STOP",
768 VKey::BrowserSearch => "VK_BROWSER_SEARCH",
769 VKey::BrowserFavorites => "VK_BROWSER_FAVORITES",
770 VKey::BrowserHome => "VK_BROWSER_HOME",
771 VKey::VolumeMute => "VK_VOLUME_MUTE",
772 VKey::VolumeDown => "VK_VOLUME_DOWN",
773 VKey::VolumeUp => "VK_VOLUME_UP",
774 VKey::MediaNextTrack => "VK_MEDIA_NEXT_TRACK",
775 VKey::MediaPrevTrack => "VK_MEDIA_PREV_TRACK",
776 VKey::MediaStop => "VK_MEDIA_STOP",
777 VKey::MediaPlayPause => "VK_MEDIA_PLAY_PAUSE",
778 VKey::LaunchMail => "VK_LAUNCH_MAIL",
779 VKey::LaunchMediaSelect => "VK_LAUNCH_MEDIA_SELECT",
780 VKey::LaunchApp1 => "VK_LAUNCH_APP1",
781 VKey::LaunchApp2 => "VK_LAUNCH_APP2",
782 VKey::Oem1 => "VK_OEM_1",
783 VKey::OemPlus => "VK_OEM_PLUS",
784 VKey::OemComma => "VK_OEM_COMMA",
785 VKey::OemMinus => "VK_OEM_MINUS",
786 VKey::OemPeriod => "VK_OEM_PERIOD",
787 VKey::Oem2 => "VK_OEM_2",
788 VKey::Oem3 => "VK_OEM_3",
789 VKey::Oem4 => "VK_OEM_4",
790 VKey::Oem5 => "VK_OEM_5",
791 VKey::Oem6 => "VK_OEM_6",
792 VKey::Oem7 => "VK_OEM_7",
793 VKey::Oem8 => "VK_OEM_8",
794 VKey::Oem102 => "VK_OEM_102",
795 VKey::Attn => "VK_ATTN",
796 VKey::Crsel => "VK_CRSEL",
797 VKey::Exsel => "VK_EXSEL",
798 VKey::Play => "VK_PLAY",
799 VKey::Zoom => "VK_ZOOM",
800 VKey::Pa1 => "VK_PA1",
801 VKey::OemClear => "VK_OEM_CLEAR",
802 VKey::Vk0 => "VK_0",
803 VKey::Vk1 => "VK_1",
804 VKey::Vk2 => "VK_2",
805 VKey::Vk3 => "VK_3",
806 VKey::Vk4 => "VK_4",
807 VKey::Vk5 => "VK_5",
808 VKey::Vk6 => "VK_6",
809 VKey::Vk7 => "VK_7",
810 VKey::Vk8 => "VK_8",
811 VKey::Vk9 => "VK_9",
812 VKey::A => "VK_A",
813 VKey::B => "VK_B",
814 VKey::C => "VK_C",
815 VKey::D => "VK_D",
816 VKey::E => "VK_E",
817 VKey::F => "VK_F",
818 VKey::G => "VK_G",
819 VKey::H => "VK_H",
820 VKey::I => "VK_I",
821 VKey::J => "VK_J",
822 VKey::K => "VK_K",
823 VKey::L => "VK_L",
824 VKey::M => "VK_M",
825 VKey::N => "VK_N",
826 VKey::O => "VK_O",
827 VKey::P => "VK_P",
828 VKey::Q => "VK_Q",
829 VKey::R => "VK_R",
830 VKey::S => "VK_S",
831 VKey::T => "VK_T",
832 VKey::U => "VK_U",
833 VKey::V => "VK_V",
834 VKey::W => "VK_W",
835 VKey::X => "VK_X",
836 VKey::Y => "VK_Y",
837 VKey::Z => "VK_Z",
838 VKey::CustomKeyCode(vk) => return write!(f, "Custom({})", vk),
839 };
840 write!(f, "{}", name)
841 }
842}
843
844impl std::str::FromStr for VKey {
845 type Err = WHKError;
846 fn from_str(s: &str) -> Result<Self, Self::Err> {
847 VKey::from_keyname(s)
848 }
849}
850
851impl PartialEq<VKey> for VKey {
852 fn eq(&self, other: &VKey) -> bool {
853 self.to_vk_code() == other.to_vk_code()
854 }
855}
856
857impl Eq for VKey {}
858
859impl Hash for VKey {
860 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
861 self.to_vk_code().hash(state);
862 }
863}
864
865#[cfg(test)]
866mod tests {
867 use super::*;
868
869 #[test]
870 fn test_to_vk_code() {
871 assert_eq!(VKey::Back.to_vk_code(), 0x08); assert_eq!(VKey::Return.to_vk_code(), 0x0D); assert_eq!(VKey::Space.to_vk_code(), 0x20); assert_eq!(VKey::F12.to_vk_code(), 0x7B); assert_eq!(VKey::CustomKeyCode(1234).to_vk_code(), 1234); }
877
878 #[test]
879 fn test_from_keyname() {
880 assert_eq!(VKey::from_keyname("BACK").unwrap(), VKey::Back);
881 assert_eq!(VKey::from_keyname("VK_BACK").unwrap(), VKey::Back);
882 assert_eq!(VKey::from_keyname("RETURN").unwrap(), VKey::Return);
883 assert_eq!(
884 VKey::from_keyname("0x29").unwrap(),
885 VKey::CustomKeyCode(0x29)
886 );
887 assert!(VKey::from_keyname("INVALID_KEY").is_err());
888 }
889
890 #[test]
891 fn test_display() {
892 assert_eq!(format!("{}", VKey::Back), "VK_BACK");
893 assert_eq!(format!("{}", VKey::Return), "VK_RETURN");
894 assert_eq!(format!("{}", VKey::CustomKeyCode(1234)), "Custom(1234)");
895 }
896
897 #[test]
898 fn test_from_str() {
899 use std::str::FromStr;
900 assert_eq!(VKey::from_str("BACK").unwrap(), VKey::Back);
901 assert_eq!(VKey::from_str("VK_BACK").unwrap(), VKey::Back);
902 assert_eq!(VKey::from_str("INVALID_KEY").is_err(), true);
903 }
904
905 #[test]
906 fn test_partial_eq() {
907 assert_eq!(VKey::Back, VKey::Back); assert_eq!(VKey::CustomKeyCode(1234), VKey::CustomKeyCode(1234)); assert_ne!(VKey::CustomKeyCode(1234), VKey::CustomKeyCode(5678)); }
911
912 #[test]
913 fn test_custom_keycode_range() {
914 assert_eq!(VKey::CustomKeyCode(0).to_vk_code(), 0);
915 assert_eq!(VKey::CustomKeyCode(65535).to_vk_code(), 65535); }
917}