@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Generic ;
using System.Text ;
using Avalonia.Input ;
using Avalonia.Win32.Interop ;
@ -364,33 +363,80 @@ namespace Avalonia.Win32.Input
{ 2 5 4 , Key . OemClear } ,
} ;
public static Key KeyFromVirtualKey ( int virtualKey , int flags )
/// <summary>
/// Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys.
/// According to https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown.
/// </summary>
private static bool IsExtended ( int keyData )
{
s_keyFromVirtualKey . TryGetValue ( virtualKey , out var result ) ;
// Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys.
// According to https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown.
const int extendedMask = 1 < < 2 4 ;
bool isExtended = ( flags & extendedMask ) ! = 0 ;
if ( isExtended )
return ( keyData & extendedMask ) ! = 0 ;
}
private static int GetVirtualKey ( int virtualKey , int keyData )
{
// Adapted from https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndKeyboardInputProvider.cs.
if ( virtualKey = = ( int ) UnmanagedMethods . VirtualKeyStates . VK_SHIFT )
{
return result switch
// Bits from 16 to 23 represent scan code.
const int scanCodeMask = 0xFF0000 ;
var scanCode = ( keyData & scanCodeMask ) > > 1 6 ;
virtualKey = ( int ) UnmanagedMethods . MapVirtualKey ( ( uint ) scanCode , ( uint ) UnmanagedMethods . MapVirtualKeyMapTypes . MAPVK_VSC_TO_VK_EX ) ;
if ( virtualKey = = 0 )
{
Key . LeftAlt = > Key . RightAlt ,
Key . LeftCtrl = > Key . RightCtrl ,
Key . LeftShift = > Key . RightShift ,
_ = > result
} ;
virtualKey = ( int ) UnmanagedMethods . VirtualKeyStates . VK_LSHIFT ;
}
}
if ( virtualKey = = ( int ) UnmanagedMethods . VirtualKeyStates . VK_MENU )
{
bool isRight = IsExtended ( keyData ) ;
if ( isRight )
{
virtualKey = ( int ) UnmanagedMethods . VirtualKeyStates . VK_RMENU ;
}
else
{
virtualKey = ( int ) UnmanagedMethods . VirtualKeyStates . VK_LMENU ;
}
}
if ( virtualKey = = ( int ) UnmanagedMethods . VirtualKeyStates . VK_CONTROL )
{
bool isRight = IsExtended ( keyData ) ;
if ( isRight )
{
virtualKey = ( int ) UnmanagedMethods . VirtualKeyStates . VK_RCONTROL ;
}
else
{
virtualKey = ( int ) UnmanagedMethods . VirtualKeyStates . VK_LCONTROL ;
}
}
return virtualKey ;
}
public static Key KeyFromVirtualKey ( int virtualKey , int keyData )
{
virtualKey = GetVirtualKey ( virtualKey , keyData ) ;
s_keyFromVirtualKey . TryGetValue ( virtualKey , out var result ) ;
return result ;
}
public static int VirtualKeyFromKey ( Key key )
{
int result ;
s_virtualKeyFromKey . TryGetValue ( key , out result ) ;
s_virtualKeyFromKey . TryGetValue ( key , out var result ) ;
return result ;
}
}