pub(crate) fn key_to_vk(key: &KbKey) -> Option<i32> {
    Some(match key {
        KbKey::Character(s) => {
            if let Some(code_point) = s.chars().next() {
                if let Ok(wchar) = (code_point as u32).try_into() {
                    unsafe { VkKeyScanW(wchar) as i32 }
                } else {
                    return None;
                }
            } else {
                return None;
            }
        }
        KbKey::Cancel => VK_CANCEL,
        KbKey::Backspace => VK_BACK,
        KbKey::Tab => VK_TAB,
        KbKey::Clear => VK_CLEAR,
        KbKey::Enter => VK_RETURN,
        KbKey::Shift => VK_SHIFT,
        KbKey::Control => VK_CONTROL,
        KbKey::Alt => VK_MENU,
        KbKey::Pause => VK_PAUSE,
        KbKey::CapsLock => VK_CAPITAL,
        // TODO: disambiguate kana and hangul? same vk
        KbKey::KanaMode => VK_KANA,
        KbKey::JunjaMode => VK_JUNJA,
        KbKey::FinalMode => VK_FINAL,
        KbKey::KanjiMode => VK_KANJI,
        KbKey::Escape => VK_ESCAPE,
        KbKey::NonConvert => VK_NONCONVERT,
        KbKey::Accept => VK_ACCEPT,
        KbKey::PageUp => VK_PRIOR,
        KbKey::PageDown => VK_NEXT,
        KbKey::End => VK_END,
        KbKey::Home => VK_HOME,
        KbKey::ArrowLeft => VK_LEFT,
        KbKey::ArrowUp => VK_UP,
        KbKey::ArrowRight => VK_RIGHT,
        KbKey::ArrowDown => VK_DOWN,
        KbKey::Select => VK_SELECT,
        KbKey::Print => VK_PRINT,
        KbKey::Execute => VK_EXECUTE,
        KbKey::PrintScreen => VK_SNAPSHOT,
        KbKey::Insert => VK_INSERT,
        KbKey::Delete => VK_DELETE,
        KbKey::Help => VK_HELP,
        KbKey::Meta => VK_LWIN,
        KbKey::ContextMenu => VK_APPS,
        KbKey::Standby => VK_SLEEP,
        KbKey::F1 => VK_F1,
        KbKey::F2 => VK_F2,
        KbKey::F3 => VK_F3,
        KbKey::F4 => VK_F4,
        KbKey::F5 => VK_F5,
        KbKey::F6 => VK_F6,
        KbKey::F7 => VK_F7,
        KbKey::F8 => VK_F8,
        KbKey::F9 => VK_F9,
        KbKey::F10 => VK_F10,
        KbKey::F11 => VK_F11,
        KbKey::F12 => VK_F12,
        KbKey::F13 => VK_F13,
        KbKey::F14 => VK_F14,
        KbKey::F15 => VK_F15,
        KbKey::F16 => VK_F16,
        KbKey::F17 => VK_F17,
        KbKey::F18 => VK_F18,
        KbKey::F19 => VK_F19,
        KbKey::F20 => VK_F20,
        KbKey::F21 => VK_F21,
        KbKey::F22 => VK_F22,
        KbKey::F23 => VK_F23,
        KbKey::F24 => VK_F24,
        KbKey::NumLock => VK_NUMLOCK,
        KbKey::ScrollLock => VK_SCROLL,
        KbKey::BrowserBack => VK_BROWSER_BACK,
        KbKey::BrowserForward => VK_BROWSER_FORWARD,
        KbKey::BrowserRefresh => VK_BROWSER_REFRESH,
        KbKey::BrowserStop => VK_BROWSER_STOP,
        KbKey::BrowserSearch => VK_BROWSER_SEARCH,
        KbKey::BrowserFavorites => VK_BROWSER_FAVORITES,
        KbKey::BrowserHome => VK_BROWSER_HOME,
        KbKey::AudioVolumeMute => VK_VOLUME_MUTE,
        KbKey::AudioVolumeDown => VK_VOLUME_DOWN,
        KbKey::AudioVolumeUp => VK_VOLUME_UP,
        KbKey::MediaTrackNext => VK_MEDIA_NEXT_TRACK,
        KbKey::MediaTrackPrevious => VK_MEDIA_PREV_TRACK,
        KbKey::MediaStop => VK_MEDIA_STOP,
        KbKey::MediaPlayPause => VK_MEDIA_PLAY_PAUSE,
        KbKey::LaunchMail => VK_LAUNCH_MAIL,
        KbKey::LaunchMediaPlayer => VK_LAUNCH_MEDIA_SELECT,
        KbKey::LaunchApplication1 => VK_LAUNCH_APP1,
        KbKey::LaunchApplication2 => VK_LAUNCH_APP2,
        KbKey::Alphanumeric => VK_OEM_ATTN,
        KbKey::Convert => VK_CONVERT,
        KbKey::ModeChange => VK_MODECHANGE,
        KbKey::Process => VK_PROCESSKEY,
        KbKey::Attn => VK_ATTN,
        KbKey::CrSel => VK_CRSEL,
        KbKey::ExSel => VK_EXSEL,
        KbKey::EraseEof => VK_EREOF,
        KbKey::Play => VK_PLAY,
        KbKey::ZoomToggle => VK_ZOOM,
        _ => return None,
    })
}
/// Convert a key to a virtual key code.
///
/// The virtual key code is needed in various winapi interfaces, including
/// accelerators. This provides the virtual key code in the current keyboard
/// map.
///
/// The virtual key code can have modifiers in the higher order byte when the
/// argument is a `Character` variant. See [VkKeyScanW][].
///
/// [VkKeyScanW]: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-vkkeyscanw
Convert a key to a virtual key code.
The virtual key code is needed in various winapi interfaces, including
accelerators. This provides the virtual key code in the current keyboard
map.

The virtual key code can have modifiers in the higher order byte when the
argument is a `Character` variant.


Convert a key to a virtual key code . The virtual key code is needed in various winapi interfaces including accelerators . This provides the virtual key code in the current keyboard map . The virtual key code can have modifiers in the higher order byte when the argument is a ` Character ` variant .
pub(crate) fn key_to_vk(key: &KbKey) -> Option<i32> {
    Some(match key {
        KbKey::Character(s) => {
            if let Some(code_point) = s.chars().next() {
                if let Ok(wchar) = (code_point as u32).try_into() {
                    unsafe { VkKeyScanW(wchar) as i32 }
                } else {
                    return None;
                }
            } else {
                return None;
            }
        }
        KbKey::Cancel => VK_CANCEL,
        KbKey::Backspace => VK_BACK,
        KbKey::Tab => VK_TAB,
        KbKey::Clear => VK_CLEAR,
        KbKey::Enter => VK_RETURN,
        KbKey::Shift => VK_SHIFT,
        KbKey::Control => VK_CONTROL,
        KbKey::Alt => VK_MENU,
        KbKey::Pause => VK_PAUSE,
        KbKey::CapsLock => VK_CAPITAL,
        // TODO: disambiguate kana and hangul? same vk
        KbKey::KanaMode => VK_KANA,
        KbKey::JunjaMode => VK_JUNJA,
        KbKey::FinalMode => VK_FINAL,
        KbKey::KanjiMode => VK_KANJI,
        KbKey::Escape => VK_ESCAPE,
        KbKey::NonConvert => VK_NONCONVERT,
        KbKey::Accept => VK_ACCEPT,
        KbKey::PageUp => VK_PRIOR,
        KbKey::PageDown => VK_NEXT,
        KbKey::End => VK_END,
        KbKey::Home => VK_HOME,
        KbKey::ArrowLeft => VK_LEFT,
        KbKey::ArrowUp => VK_UP,
        KbKey::ArrowRight => VK_RIGHT,
        KbKey::ArrowDown => VK_DOWN,
        KbKey::Select => VK_SELECT,
        KbKey::Print => VK_PRINT,
        KbKey::Execute => VK_EXECUTE,
        KbKey::PrintScreen => VK_SNAPSHOT,
        KbKey::Insert => VK_INSERT,
        KbKey::Delete => VK_DELETE,
        KbKey::Help => VK_HELP,
        KbKey::Meta => VK_LWIN,
        KbKey::ContextMenu => VK_APPS,
        KbKey::Standby => VK_SLEEP,
        KbKey::F1 => VK_F1,
        KbKey::F2 => VK_F2,
        KbKey::F3 => VK_F3,
        KbKey::F4 => VK_F4,
        KbKey::F5 => VK_F5,
        KbKey::F6 => VK_F6,
        KbKey::F7 => VK_F7,
        KbKey::F8 => VK_F8,
        KbKey::F9 => VK_F9,
        KbKey::F10 => VK_F10,
        KbKey::F11 => VK_F11,
        KbKey::F12 => VK_F12,
        KbKey::F13 => VK_F13,
        KbKey::F14 => VK_F14,
        KbKey::F15 => VK_F15,
        KbKey::F16 => VK_F16,
        KbKey::F17 => VK_F17,
        KbKey::F18 => VK_F18,
        KbKey::F19 => VK_F19,
        KbKey::F20 => VK_F20,
        KbKey::F21 => VK_F21,
        KbKey::F22 => VK_F22,
        KbKey::F23 => VK_F23,
        KbKey::F24 => VK_F24,
        KbKey::NumLock => VK_NUMLOCK,
        KbKey::ScrollLock => VK_SCROLL,
        KbKey::BrowserBack => VK_BROWSER_BACK,
        KbKey::BrowserForward => VK_BROWSER_FORWARD,
        KbKey::BrowserRefresh => VK_BROWSER_REFRESH,
        KbKey::BrowserStop => VK_BROWSER_STOP,
        KbKey::BrowserSearch => VK_BROWSER_SEARCH,
        KbKey::BrowserFavorites => VK_BROWSER_FAVORITES,
        KbKey::BrowserHome => VK_BROWSER_HOME,
        KbKey::AudioVolumeMute => VK_VOLUME_MUTE,
        KbKey::AudioVolumeDown => VK_VOLUME_DOWN,
        KbKey::AudioVolumeUp => VK_VOLUME_UP,
        KbKey::MediaTrackNext => VK_MEDIA_NEXT_TRACK,
        KbKey::MediaTrackPrevious => VK_MEDIA_PREV_TRACK,
        KbKey::MediaStop => VK_MEDIA_STOP,
        KbKey::MediaPlayPause => VK_MEDIA_PLAY_PAUSE,
        KbKey::LaunchMail => VK_LAUNCH_MAIL,
        KbKey::LaunchMediaPlayer => VK_LAUNCH_MEDIA_SELECT,
        KbKey::LaunchApplication1 => VK_LAUNCH_APP1,
        KbKey::LaunchApplication2 => VK_LAUNCH_APP2,
        KbKey::Alphanumeric => VK_OEM_ATTN,
        KbKey::Convert => VK_CONVERT,
        KbKey::ModeChange => VK_MODECHANGE,
        KbKey::Process => VK_PROCESSKEY,
        KbKey::Attn => VK_ATTN,
        KbKey::CrSel => VK_CRSEL,
        KbKey::ExSel => VK_EXSEL,
        KbKey::EraseEof => VK_EREOF,
        KbKey::Play => VK_PLAY,
        KbKey::ZoomToggle => VK_ZOOM,
        _ => return None,
    })
}
pub ( crate ) fn key_to_vk ( key : & KbKey ) -> Option < i32 > { Some ( match key { KbKey :: Character ( s ) => { if let Some ( code_point ) = s . chars ( ) . next ( ) { if let Ok ( wchar ) = ( code_point as u32 ) . try_into ( ) { unsafe { VkKeyScanW ( wchar ) as i32 } } else { return None ; } } else { return None ; } } KbKey :: Cancel => VK_CANCEL , KbKey :: Backspace => VK_BACK , KbKey :: Tab => VK_TAB , KbKey :: Clear => VK_CLEAR , KbKey :: Enter => VK_RETURN , KbKey :: Shift => VK_SHIFT , KbKey :: Control => VK_CONTROL , KbKey :: Alt => VK_MENU , KbKey :: Pause => VK_PAUSE , KbKey :: CapsLock => VK_CAPITAL , // TODO: disambiguate kana and hangul? same vk KbKey :: KanaMode => VK_KANA , KbKey :: JunjaMode => VK_JUNJA , KbKey :: FinalMode => VK_FINAL , KbKey :: KanjiMode => VK_KANJI , KbKey :: Escape => VK_ESCAPE , KbKey :: NonConvert => VK_NONCONVERT , KbKey :: Accept => VK_ACCEPT , KbKey :: PageUp => VK_PRIOR , KbKey :: PageDown => VK_NEXT , KbKey :: End => VK_END , KbKey :: Home => VK_HOME , KbKey :: ArrowLeft => VK_LEFT , KbKey :: ArrowUp => VK_UP , KbKey :: ArrowRight => VK_RIGHT , KbKey :: ArrowDown => VK_DOWN , KbKey :: Select => VK_SELECT , KbKey :: Print => VK_PRINT , KbKey :: Execute => VK_EXECUTE , KbKey :: PrintScreen => VK_SNAPSHOT , KbKey :: Insert => VK_INSERT , KbKey :: Delete => VK_DELETE , KbKey :: Help => VK_HELP , KbKey :: Meta => VK_LWIN , KbKey :: ContextMenu => VK_APPS , KbKey :: Standby => VK_SLEEP , KbKey :: F1 => VK_F1 , KbKey :: F2 => VK_F2 , KbKey :: F3 => VK_F3 , KbKey :: F4 => VK_F4 , KbKey :: F5 => VK_F5 , KbKey :: F6 => VK_F6 , KbKey :: F7 => VK_F7 , KbKey :: F8 => VK_F8 , KbKey :: F9 => VK_F9 , KbKey :: F10 => VK_F10 , KbKey :: F11 => VK_F11 , KbKey :: F12 => VK_F12 , KbKey :: F13 => VK_F13 , KbKey :: F14 => VK_F14 , KbKey :: F15 => VK_F15 , KbKey :: F16 => VK_F16 , KbKey :: F17 => VK_F17 , KbKey :: F18 => VK_F18 , KbKey :: F19 => VK_F19 , KbKey :: F20 => VK_F20 , KbKey :: F21 => VK_F21 , KbKey :: F22 => VK_F22 , KbKey :: F23 => VK_F23 , KbKey :: F24 => VK_F24 , KbKey :: NumLock => VK_NUMLOCK , KbKey :: ScrollLock => VK_SCROLL , KbKey :: BrowserBack => VK_BROWSER_BACK , KbKey :: BrowserForward => VK_BROWSER_FORWARD , KbKey :: BrowserRefresh => VK_BROWSER_REFRESH , KbKey :: BrowserStop => VK_BROWSER_STOP , KbKey :: BrowserSearch => VK_BROWSER_SEARCH , KbKey :: BrowserFavorites => VK_BROWSER_FAVORITES , KbKey :: BrowserHome => VK_BROWSER_HOME , KbKey :: AudioVolumeMute => VK_VOLUME_MUTE , KbKey :: AudioVolumeDown => VK_VOLUME_DOWN , KbKey :: AudioVolumeUp => VK_VOLUME_UP , KbKey :: MediaTrackNext => VK_MEDIA_NEXT_TRACK , KbKey :: MediaTrackPrevious => VK_MEDIA_PREV_TRACK , KbKey :: MediaStop => VK_MEDIA_STOP , KbKey :: MediaPlayPause => VK_MEDIA_PLAY_PAUSE , KbKey :: LaunchMail => VK_LAUNCH_MAIL , KbKey :: LaunchMediaPlayer => VK_LAUNCH_MEDIA_SELECT , KbKey :: LaunchApplication1 => VK_LAUNCH_APP1 , KbKey :: LaunchApplication2 => VK_LAUNCH_APP2 , KbKey :: Alphanumeric => VK_OEM_ATTN , KbKey :: Convert => VK_CONVERT , KbKey :: ModeChange => VK_MODECHANGE , KbKey :: Process => VK_PROCESSKEY , KbKey :: Attn => VK_ATTN , KbKey :: CrSel => VK_CRSEL , KbKey :: ExSel => VK_EXSEL , KbKey :: EraseEof => VK_EREOF , KbKey :: Play => VK_PLAY , KbKey :: ZoomToggle => VK_ZOOM , _ => return None , } ) }
Convert a key to a virtual key code.
Convert a key to a virtual key code .
key
&KbKey
key
&KbKey