Add ScanCodeTester

pull/63/head
Clive Galway 5 years ago
parent 3a390d46c9
commit 4a27101b29

@ -43,6 +43,7 @@
<Compile Include="Helpers\HelperFunctions.cs" />
<Compile Include="Helpers\ManagedWrapper.cs" />
<Compile Include="Helpers\MultimediaTimer.cs" />
<Compile Include="ScanCodeChecker.cs" />
<Compile Include="Manager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AutoHotInterception.Helpers;
namespace AutoHotInterception
{
/*
* Tool to check Scan Codes and Press / Release states
*/
public class ScanCodeChecker
{
private MultimediaTimer _timer;
private readonly IntPtr _deviceContext;
private int _filteredDevice;
private dynamic _callback;
public ScanCodeChecker()
{
_deviceContext = ManagedWrapper.CreateContext();
}
public void Subscribe(int vid, int pid, dynamic callback)
{
_callback = callback;
_filteredDevice = HelperFunctions.GetDeviceId(_deviceContext, false, vid, pid, 1);
if (_filteredDevice == 0)
{
throw new Exception($"Could not find device with VID {vid}, PID {pid}");
}
ManagedWrapper.SetFilter(_deviceContext, IsMonitoredDevice, ManagedWrapper.Filter.All);
_timer = new MultimediaTimer() { Interval = 10 };
_timer.Elapsed += DoPoll;
_timer.Start();
}
public string OkCheck()
{
return "OK";
}
private int IsMonitoredDevice(int device)
{
return Convert.ToInt32(_filteredDevice == device);
}
public void DoPoll(object sender, EventArgs e)
{
var stroke = new ManagedWrapper.Stroke();
var keyEvents = new List<KeyEvent>();
while (ManagedWrapper.Receive(_deviceContext, _filteredDevice, ref stroke, 1) > 0)
{
keyEvents.Add(new KeyEvent{Code = stroke.key.code, State = stroke.key.state});
ManagedWrapper.Send(_deviceContext, _filteredDevice, ref stroke, 1);
}
if (keyEvents.Count > 0)
{
_callback(keyEvents.ToArray());
}
}
}
public class KeyEvent
{
public ushort Code { get; set; }
public ushort State { get; set; }
}
}

@ -8,10 +8,12 @@ namespace TestApp
private static void Main()
{
//var mt = new MouseTester();
var mbt = new MouseButtonsTester();
//var mbt = new MouseButtonsTester();
//var kt = new KeyboardTester();
//var kkt = new KeyboardKeyTester();
//var tt = new TabletTester();
var sct = new ScanCodeTester();
Console.ReadLine();
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoHotInterception;
using AutoHotInterception.Helpers;
namespace TestApp
{
public class ScanCodeTester
{
public ScanCodeTester()
{
var scc = new ScanCodeChecker();
scc.Subscribe(0x04F2, 0x0112, new Action<KeyEvent[]>(OnKeyEvent));
}
public void OnKeyEvent(KeyEvent[] keyEvents)
{
var str = "";
foreach (var keyEvent in keyEvents)
{
str += $"Code: {keyEvent.Code}, State: {keyEvent.State} | ";
}
Debug.WriteLine(str);
}
}
}

@ -48,6 +48,7 @@
<Compile Include="MouseTester.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScanCodeTester.cs" />
<Compile Include="TabletTester.cs" />
</ItemGroup>
<ItemGroup>

@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## [Unreleased]
### Added
- SubscribeKeyboard and SubscribeMouseButtons can now be used to subscribe to all keys / buttons on a device
- Added ScanCodeTester Development Tool to investigate differences in AHI / AHK ScanCodes
### Changed
- Monitor.ahk now uses SubscribeKeyboard and SubscribeMouseButtons
### Deprecated

@ -0,0 +1,105 @@
#SingleInstance force
#Include ..\Lib\CLR.ahk
; REQUIRES AHK >= 1.1.32
/*
The purpose of this tool is to compare the keyboard events that AHK sees to the keyboard events that AHI sees
To use it, set the vid and pid variables below to the VID and PID of a keyboard...
... then run this script and press keys ONLY ON THAT KEYBOARD
Pressing keys on another keyboard will break the script!
The ListView in the GUI will then be updated to show the events seen by AHK and AHI
Note that for some keys (eg Pause), AHI will see TWO key events for that key, hence the "AHI SC #1" and "AHI SC #2" columns
All ScanCodes are in Decimal
*/
vid := 0x04F2, pid := 0x0112 ; Wyse Keyboard
OutputDebug, DBGVIEWCLEAR
AhkKeyBuffer := []
asm := CLR_LoadLibrary("..\Lib\AutoHotInterception.dll")
sct := asm.CreateInstance("AutoHotInterception.ScanCodeChecker")
sct.Subscribe(vid, pid, Func("AhiKeyEvent"))
ih := InputHook()
ih.KeyOpt("{All}", "SN")
ih.OnKeyDown := Func("AhkKeyEvent").Bind(1)
ih.OnKeyUp := Func("AhkKeyEvent").Bind(0)
ih.Start()
Gui, Add, ListView, w600 h500, Key Name|AHK SC|AHK State|AHI SC #1|AHI State #1|AHI SC #2|AHI State #2
LV_ModifyCol(1, 100)
LV_ModifyCol(2, 80)
LV_ModifyCol(3, 80)
LV_ModifyCol(4, 80)
LV_ModifyCol(5, 80)
LV_ModifyCol(6, 80)
LV_ModifyCol(7, 80)
Gui, Add, Button, xm w600 gClear Centered, Clear
Gui, Show,, AHI ScanCode tester
return
Clear:
LV_Delete()
return
AhiKeyEvent(keyEvents){
global AhkKeyBuffer
ahkKeyEvent := AhkKeyBuffer[1]
; Fix for NumLock InputHook issue: https://www.autohotkey.com/boards/viewtopic.php?f=14&t=70769
if (ahkKeyEvent.Code == 325 && ahkKeyEvent.State == 1 && AhkKeyBuffer.Length() > 1){
AhkKeyBuffer := [AhkKeyBuffer[1]]
}
; End fix
if (AhkKeyBuffer.Length() != 1){
msgbox % "Expecting exactly 1 event in AHK Key Buffer, found " AhkKeyBuffer.Length()
ExitApp
}
numEvents := keyEvents.MaxIndex() + 1
if (numEvents > 2){
msgbox % "Expecting 1 or 2 AHI key events, but got " numEvents
ExitApp
}
; Note that keyEvents is a ZERO-BASED array!
ahiSc1 := keyEvents[0].Code
ahiState1 := keyEvents[0].state
if (numEvents == 2){
ahiSc2 := keyEvents[1].Code
ahiState2 := keyEvents[1].state
}
ahkSc1 := ahkKeyEvent.Code
if (ahkSc1 > 256){
ahkSc1 .= " (Ext " ahkSc1 - 256 ")"
}
ahkState1 := ahkKeyEvent.State
row := LV_Add(, GetKeyName("SC" DecToHex(ahkKeyEvent.Code)), ahkSc1, ahkState1, ahiSc1, ahiState1, ahiSc2, ahiState2)
LV_Modify(row, "Vis")
AhkKeyBuffer := []
}
AhkKeyEvent(state, ih, vk, sc){
global AhkKeyBuffer
AhkKeyBuffer.Push({Code: sc, State: state})
}
Debug(str){
OutputDebug % "AHK| " str
}
DecToHex(val){
return Format("{:X}", val)
}
^Esc::
GuiClose:
ExitApp

@ -0,0 +1,31 @@
#SingleInstance force
/*
Tool for checking what InputHook reports in AHK
*/
Sleep 100 ; When hitting F5 to run script in SciTE, release of F5 appears in list. Suppress
ih := InputHook()
ih.KeyOpt("{All}", "SN")
ih.OnKeyDown := Func("AhkKeyEvent").Bind(1)
ih.OnKeyUp := Func("AhkKeyEvent").Bind(0)
ih.Start()
Gui, Add, ListView, h200, Key Name|SC|State
LV_ModifyCol(1, 100)
LV_ModifyCol(2, 50)
LV_ModifyCol(3, 50)
Gui, Show,, AHK ScanCode tester
return
AhkKeyEvent(state, ih, vk, sc){
row := LV_Add(, GetKeyName("SC" DecToHex(sc)), sc, state)
LV_Modify(row, "Vis")
}
DecToHex(val){
return Format("{:X}", val)
}
GuiClose:
ExitApp
Loading…
Cancel
Save