@ -17,13 +17,14 @@ The purpose of this class is to encapsulate the logic required to deal with this
* /
namespace AutoHotInterception.Helpers
{
class TranslatedKey
public class TranslatedKey
{
public ushort AhkCode { get ; set ; }
//public List<KeyStroke> Strokes { get; set; }
public KeyStroke FirstStroke { get ; }
public KeyStroke SecondStroke { get ; set ; }
public bool IsExtended { get ; }
public int State { get ; set ; }
public TranslatedKey ( KeyStroke stroke , bool isExtended )
{
@ -32,13 +33,64 @@ namespace AutoHotInterception.Helpers
}
}
public static class SpecialKeys
{
public static SpecialKey NumpadEnter { get ; set ; } = new SpecialKey ( "Numpad Enter" , 28 , ExtMode . E0 , CodeType . High , Order . Normal ) ;
public static SpecialKey RightControl { get ; } = new SpecialKey ( "Right Control" , 29 , ExtMode . E1 , CodeType . High , Order . Normal ) ;
public static SpecialKey NumpadDiv { get ; } = new SpecialKey ( "Numpad Div" , 53 , ExtMode . E1 , CodeType . High , Order . Normal ) ;
public static SpecialKey RightShift { get ; set ; } = new SpecialKey ( "Right Shift" , 54 , ExtMode . E0 , CodeType . High , Order . Normal ) ;
public static SpecialKey Pause { get ; set ; } = new SpecialKey ( "Pause" , 69 , ExtMode . E0 , CodeType . Low , Order . Prefixed ) ;
public static SpecialKey Home { get ; set ; } = new SpecialKey ( "Home" , 71 , ExtMode . E1 , CodeType . High , Order . Wrapped ) ;
public static List < SpecialKey > List { get ; set ; } = new List < SpecialKey > ( )
{
NumpadEnter , RightControl , NumpadDiv , Pause , Home
} ;
}
// Whether the AHK ScanCode is Low (same as Interception) or Hight (Interception + 256)
public enum CodeType { Low , High } ;
// Whether Press/Release states are 0/1 (E0), 2/3 (E1) or 4/5 (E2)
public enum ExtMode { E0 , E1 , E2 } ;
// Order of the strokes received
public enum Order { Normal /* Stroke order is Key press, Key release (No Extended Modifier) */
, Wrapped /* Stroke order is Ext Modifier press, Key press, Key release, Ext Modifier Release */
, Prefixed /* Stroke order is Ext Modifier press, Key press, Ext Modifier release, Key release */ } ;
public class SpecialKey
{
public string Name { get ; }
public ushort Code { get ; }
public ExtMode ExtendedMode { get ; }
public CodeType CodeType { get ; }
public Order StrokeOrder { get ; }
public SpecialKey ( string name , ushort code , ExtMode extendedMode , CodeType codeType , Order strokeOrderW )
{
// The name of the key
Name = name ;
// The code that identifies this key
Code = code ;
// What values will be reported for press/release states for this key
ExtendedMode = extendedMode ;
// Whether AHK uses a High (+256) or Low code for this key
CodeType = codeType ;
}
}
class ScanCodeHelper
public class ScanCodeHelper
{
//private KeyStroke? _extendedBuffer;
private TranslatedKey _translatedKey ;
// Converts Interception state to AHK state
private static List < ushort > _stateConverter = new List < ushort > ( ) { 1 , 0 , 1 , 0 , 1 , 0 } ;
// Converts state to extended mode
private static List < ushort > _stateToExtendedMode = new List < ushort > ( ) { 0 , 0 , 1 , 1 , 2 , 2 } ;
// Keys which AHK assigns a
/ *
// Keys which AHK assigns a high code to, even though state is 0/1
// These keys also do not generate extended key codes
private Dictionary < ushort , string > _highCodes = new Dictionary < ushort , string > ( )
{
{ 28 , "Nummpad Enter" } ,
@ -47,9 +99,43 @@ namespace AutoHotInterception.Helpers
} ;
// Keys which have an extended state, but extended modifiers are not sent
private Dictionary < ushort , string > _noExtendedModifier = new Dictionary < ushort , string > ( )
{
{ 29 , "Right Control" } ,
{ 53 , "Numpad Div" } ,
{ 56 , "Right Alt" } ,
{ 91 , "Left Windows" } ,
{ 92 , "Right Windows" } ,
{ 93 , "Apps" }
} ;
* /
public ScanCodeHelper ( )
{
for ( int i = 0 ; i < SpecialKeys . List . Count ; i + + )
{
var specialKey = SpecialKeys . List [ i ] ;
var dict = specialKey . CodeType = = CodeType . Low ? _lowCodes : _highCodes ;
dict . Add ( specialKey . Code , specialKey . Name ) ;
if ( specialKey . ExtendedMode ! = ExtMode . E0 & & specialKey . StrokeOrder = = Order . Normal )
{
_noExtendedModifier . Add ( specialKey . Code , specialKey . Name ) ;
}
}
}
private Dictionary < ushort , string > _highCodes = new Dictionary < ushort , string > ( ) ;
private Dictionary < ushort , string > _lowCodes = new Dictionary < ushort , string > ( ) ;
// Keys which have E1 or E2 state, but do not send extended modifier
private Dictionary < ushort , string > _noExtendedModifier = new Dictionary < ushort , string > ( ) ;
public TranslatedKey TranslateScanCode ( KeyStroke stroke )
{
if ( stroke . state > 1 )
//if(stroke.state > 1 && !_noExtendedModifier.ContainsKey(stroke.code))
//if (stroke.state > 1 || stroke.code == SpecialKeys.Pause.Code )
if ( stroke . state > 1 & & ! _noExtendedModifier . ContainsKey ( stroke . code ) )
{
// Stroke is part of Extended key sequence of 2 keys
if ( _translatedKey = = null )
@ -67,13 +153,15 @@ namespace AutoHotInterception.Helpers
}
else
{
// Regular key
// Stroke is a single key sequence
_translatedKey = new TranslatedKey ( stroke , false ) ;
var code = stroke . code ;
if ( _highCodes . ContainsKey ( code ) )
{
code + = 256 ;
}
_translatedKey . AhkCode = code ;
_translatedKey . State = _stateConverter [ stroke . state ] ;
}
var returnValue = _translatedKey ;
if ( ! _translatedKey . IsExtended )