evilc / autohotinterception Goto Github PK
View Code? Open in Web Editor NEWAn AutoHotkey wrapper for the Interception driver
License: MIT License
An AutoHotkey wrapper for the Interception driver
License: MIT License
Reported here
I had an external USB and Bluetooth mouse and both stopped working. Since this happened within the timeframe I assume it's because of AHI, or rather the Inception driver.
I tried to fix it with the usual approach: on/off, reboot, unplug, uninstall. No luck so far.
When I turn the mice on/off they popup in Device Manager as HID-compliant mouse, but don't work, and are not shown in Monitor.ahk.
I have remapped all modifier keys with AHI, for instance Alt is Ctrl now. But too often I get stuck keys, pressumably when pressing multiple modifier keys at the same time.
Could it be that AHI's ability to block inputs is causing this? E.g. when a key is physically released while the input is blocked.
When I try to remap one key to another (for example X::A) it works without problems. If I try to remap a key to something different (a MsgBox, a Tooltip,...) it doesn't works. For example, in this code:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
#Persistent
#include <AutoHotInterception>
AHI := new AutoHotInterception()
keyboardId := AHI.GetKeyboardId(0x1B4F, 0x9203)
cm1 := AHI.CreateContextManager(keyboardId)
#if cm1.IsActive ; Start the #if block
X::
MsgBox, Hi
#if
A message box should appear when i press "X" but nothing happens. If I try using Subscription:
#SingleInstance force
#Persistent
#include <AutoHotInterception>
AHI := new AutoHotInterception()
keyboardId := AHI.GetKeyboardId(0x1B4F, 0x9203)
AHI.SubscribeKey(keyboardId, GetKeySC("X"), true, Func("KeyEvent"))
return
KeyEvent(state){
MsgBox, Hi
}
^Esc::
ExitApp
Everything works as expected. I don't know what could be the problem...
Reported here
Some of the macros I make are to create shortcuts to special characters such as ✔. (Don't know the technical term for them)
But currently those characters don't seem to send correctly from within a callback. For example that tick comes out as ✔
when using any of the sending options available in AHK.
I don't really know enough about character formatting and inputs to guess why it'd be happening, but here's a script I made to reproduce it.
#SingleInstance, Force
#Persistent
#Include Lib\AutoHotInterception.ahk
AHI := new AutoHotInterception()
; Use your keyboard's handle
AHI.SubscribeKey(AHI.GetKeyboardIdFromHandle("HID\VID_03F0&PID_0024&REV_0130"), GetKeySC("F1"), true, Func("CallbackFunction"))
CallbackFunction(state) {
If !state
Return
SendInput, ✔
}
I'd be interested in any workaround if you know of one.
Hi, sorry if I'm being ignorant but I'm only learning all these things. I'm trying to use AutoHotInterception and UCR to fully emulate the DualShock 4 controller in order to play games on the PS Now, which only supports official PS4 controller. My only problem is that when I use DeltaToAxis plugin with mouse as an input and DS4 right stick as output, the mouse is still visible and moves around the screen even though the controls work. It shows up the PS Now overlay, and simply hiding the mouse or trapping it in the middle of the screen doesn't solve the problem. So I was trying to disable the cursor completely and do something to catch the low-level mouse delta only. What must I do ?
Thanks,
pressButtons(sKey, sflag) {
keys := StrSplit(sKey, "")
if (sflag == "Up") {
keys := ReverseArray(keys)
}
for i, k in keys {
key := k
if (key == "^") {
StringReplace, key, key, ^, Ctrl
}
if (key == "!") {
StringReplace, key, key, !, Alt
}
if (key == "+") {
StringReplace, key, key, +, Shift
}
if (key == "#") {
StringReplace, key, key, #, Win
}
if (key == A_Space) {
StringReplace, key, key, %A_Space%, Space
}
AHI.SendKeyEvent(KEYBOARD, GetKeySC(key), sflag == "Down" ? 1 : 2)
}
}
sKey = "+a"
sflag = "Down""Up"
I catch a bug in press Shift(press) -> a(press) -> a(release) -> Shift(release)
Shift button Stucked after
Why?
An advantage worth mentioning is that it can trick UAC; the windows admin security check. There are many more advantages, that aren't obvious. Should add those in the description/doc.
I am pretty new to AHK script. I very appreciate the wonderful work you did.
I try to record the sequence of certain keys entered from a specific keyboard, and block them at the same time using the following code
#SingleInstance force
#Persistent
#include Lib\AutoHotInterception.ahk
global AHI := new AutoHotInterception()
keyboardId := AHI.GetKeyboardId(0x5131, 0x2007)
str := ""
keys := ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Enter", "?", ";"]
Loop 13 {
name := keys[A_Index]
AHI.SubscribeKey(keyboardId, GetKeySC(name), true, Func("KeyEvent").Bind(name))
}
KeyEvent(name, state){
global str
if(state == 1){
return
}
if(name != "Enter"){
str .= name
} else {
xx := str
str := ""
MsgBox % xx
}
}
^Esc::
ExitApp
Most time I got the right sequence, but sometime the "Enter" key won't be blocked.
Sometime I got the wrong sequence, like I enter 123456, it shows me like 213456.
That means the KeyEvent not firing in order.
I don't know what to do now, or maybe you have a better idea to implement the purpose mentioned at the beginning.
Thanks a lot
If running x64 version of AHK it will fail.
"You should extract both x86 and x64 folders from the library folder in interception.zip into AHI's lib folder."
There is no x64 folder in the zip file, only an x86 one so either need to change how interception searches for dlls or the folder needs to be created (and a 64bit dll placed in it).
There is an "interception.dll" in the base Lib folder inside the zip, unfortunately it also is x86. So there are no x64 dlls included in the current release,
Mouse button state is encoded in bitwise flags, and if really close together, multiple, button events can happen in one update
LMB press = 1
LMB release = 2
RMB press = 4
RMB release = 8
LMB released and RMB released = 10 - in this instance, only RMB release fires
Merge in the code from IOWrapper
I'm sorry to bother you again.
How to change the below context script to subscription script?
(Only subscription,not combined.Thanks)
#SingleInstance force
#Persistent
#include C:\AutoHotInterception\Lib\AutoHotInterception.ahk
AHI := new AutoHotInterception()
id1 := AHI.GetKeyboardId(0x1C4F, 0x0002, 1)
cm1 := AHI.CreateContextManager(id1)
id2 := AHI.GetKeyboardId(0x258A,0x001F, 1)
cm2 := AHI.CreateContextManager(id2)
return
#if cm1.IsActive
z::
send A
return
#if
#if cm2.IsActive
z::
send O
return
#if
For Mouse Wheel events, the parameter will be 1 for Wheel Up / Right and -1 for Wheel Down / Left
Wheel Up and Wheel Right is working fine, however Wheel Down And Wheel Left are behaving like up and right.
the problem is with states, they are only 0 and 1 for both.i had to write another functionfor the states.
getButtonState(KEY, STATE) {
if(KEY = WheelDown OR KEY = WheelLeft) {
if(STATE = 0)
return 0
else
return -1
}
}
It seems maybe devices get a new ID after the PC comes out of sleep / hibernate?
https://www.autohotkey.com/boards/viewtopic.php?p=260917&sid=fd0c2ccd278326e967e6329896bb7ad8#p260917
I'm curious if this will be updated to be compatible with AHK v2, which is drawing ever closer to being the primary version.
It is actually possible to be compatible with both v1.1 and v2 if you make sure to use syntax and commands that work with both versions, as seen here: https://github.com/mmikeww/AHKv2-Gdip
Lexikos mentioned here that Thread.Sleep(0)
does not do the same as AHK's Sleep 0
, to try DllCall("Sleep", "int", 0)
instead.
If move and click happen at same time, the move is ignored as the click is checked first and else if
is used
There is only one block
variable, causing the whole stroke to either be blocked or not.
A stroke can contain one or more of mouse button events, relative movement or absolute movement, but an if/else
is used, so only one type of input will be processed per stroke
This causes the following issues:
Each stroke needs to be split up into multiple strokes, and the if/else changed to multiple unrelated if
s
Reviewing the code, it just seems to do moveRemoved = true;
to set the removed flag, but not actually remove it
Sometimes,it can't blocked.
For example,I give "z" a function,then I test it in Word.However,sometimes it still send "z".
My script and screenshot ↓↓↓
#SingleInstance force
#Persistent
#include C:\AutoHotInterception\Lib\AutoHotInterception.ahk
AHI := new AutoHotInterception()
id1 := AHI.GetKeyboardId(0x258A, 0x001F, 1)
cm1 := AHI.CreateContextManager(id1)
return
#if cm1.IsActive
z::
send O
return
#if
Allow subscriptions to be removed in Subscription Mode
Reported in UCR thread by malcev
The following code in SendKeyEvent seems to be breaking sending of Up Arrow:
if (code > 255)
{
code -= 256;
state += 2;
}
Commenting it out resolves, but I think this is needed to allow sending eg of Right Alt.
Hello
I have a XP Pen Artist 15.6 Pro. My tablet is detected under keyboard in AutoHotInterception Monitor as HID\VID_28BD&PID_090D&REV_0000&MI_00&Col03 and also in mices but keys and mouse clicks are not detected even if I check everything.
It will negatively affect update rate, but is it needed?
Purpose of it was to try and not use too much CPU
Looks like the function checks whether the specified id is a keyboard instead of the mouse. The following change needs to be made in Manager.cs:
IsValidDeviceId(false, id);
needs to be
IsValidDeviceId(true, id);
Pause seems to send two codes, and is not handled correctly
In an effort to retain performance for gaming, I've decided on using key subscriptions to avoid possible delays Contextual Hotkeys may cause on my main keyboard. But the key up being fired has created a bit of a roadblock for me.
Currently, it seems like I will have to add a check inside every single key's callback to suppress the key up event, since, for most hotkeys, I only want them firing once when tapped.
Obviously, that is pretty cumbersome and messy looking, which is why I would like to ask; Is there something I can do that I'm missing, or is it just something that hasn't been added?
Of course, I might not actually be avoiding possible delays in the first place, and in which case, I could probably just use contextual binds. I just prefer the way functions look/behave in most cases.
If the user does not place interception.dll in the lib folder, they get an error message "Could not load AutoHotInterception.dll", which is not very helpful.
Add a check for the file in the wrapper
Not really a problem at the moment as we only have add subscription, but in order to remove subscriptions, we will need to move to the thread-safe ConcurrectDictionary class, as used in the IOWrapper DirectInput / XInput providers, else we could remove a dictionary while the PollThread is iterating the dictionary.
Both button and move data can be present in mouse updates, especially in Absolute mode.
At the moment, when a click happens, the coordinates of that click are never passed back via a callback, because State is first checked, and if non-zero, movement is never processed.
Two solutions seem possible:
I've encountered an issue where "UnsubscribeMouseMove" disables mouse input when I suppose its intended behaviour is just to "unsubscribe" the callback?
class Example {
static device := {}
__New(keyboardHandle, mouseHandle) {
this.AHI := new AutoHotInterception()
this.device.keyboardId := this.AHI.GetKeyboardIdFromHandle(keyboardHandle)
this.device.mouseId := this.AHI.GetMouseIdFromHandle(mouseHandle)
}
blockMouseInput(block := false) {
this.AHI.SubscribeMouseMove(this.device.mouseId, block, ObjBindMethod(this, "__eventCallback", block))
return this
}
unsubMouseInput() {
this.AHI.UnsubscribeMouseMove(this.device.mouseId)
return this
}
__eventCallback(block, x, y) {
; ... empty fn
}
...
}
Example.blockMouseInput(true) ; this would subscribe to mouse movement and block at the same time -> works as intended
Example.blockMouseInput(false) ; this would subscribe to mouse movement, but NOT BLOCK the mouse input -> works as intended
Example.unsubMouseInput() ; THIS IS SUPPOSED TO "Unsubscribe" from mouse movement and remove any block associated with it, YET it disables mouse movements completely (i.e locks out your mouse) and Example.blockMouseInput(false) or Example.blockMouseInput(true) wouldn't bring it back until you exit/reload the script...
I thought it was an intended behaviour at first, but after checking "SubscribeKey" to see if it acts similarly - it doesn't - after using "UnsubscribeKey" I can still use that key normally.
Give users some way to discover VID/PID etc.
Also should maybe show type of input seen - eg keyboard key, mouse button, mouse movement (relative / absolute)
We currently have a tentative system in IOWrapper/UCR, but experimenting here "closer to the metal" may give me a chance to perfect something in AHI and then port it into IOWrapper.
A temporary triage would be to add endpoints to select not via VID/PID, but via Interception ID
GetDeviceIdFromHandle
in AutoHotInterception.ahk
calls GetDeviceIdFromHandle
in the C# code:
dev := this.Instance.GetDeviceIdFromHandle(IsMouse, handle, instance)
This no longer exists in the Manager / Monitor class, as it was moved to HelperFunctions.cs
Encountered by OCP on the forums
How do I move mouse without moving my physical mouse?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.