2018-03-06 19:53:04 +00:00
#include %A_LineFile% \. . \CLR . ahk
2018-03-28 19:39:29 +00:00
class AutoHotInterception {
2018-03-30 18:04:58 +00:00
_contextManagers := { }
2019-01-31 01:46:08 +00:00
__New ( cls := " Manager " ) {
2018-10-06 14:39:52 +00:00
bitness := A_PtrSize == 8 ? " x64 " : " x86 "
dllName := " interception.dll "
dllFile := A_LineFile " \..\ " bitness " \ " dllName
2019-01-31 01:46:08 +00:00
if ( ! FileExist ( dllFile ) ) {
2018-10-06 14:39:52 +00:00
MsgBox % " Unable to find lib\ " bitness " \ " dllName " , exiting...`nYou should extract both x86 and x64 folders from the library folder in interception.zip into AHI's lib folder. "
2018-04-22 17:48:41 +00:00
ExitApp
}
2018-10-06 14:39:52 +00:00
2018-04-22 18:20:30 +00:00
hModule := DllCall ( " LoadLibrary " , " Str " , dllFile , " Ptr " )
2019-01-31 01:46:08 +00:00
if ( hModule == 0 ) {
2018-04-22 18:20:30 +00:00
this_bitness := A_PtrSize == 8 ? " 64-bit " : " 32-bit "
other_bitness := A_PtrSize == 4 ? " 64-bit " : " 32-bit "
2018-10-06 14:39:52 +00:00
MsgBox % " Bitness of " dllName " does not match bitness of AHK.`nAHK is " this_bitness " , but " dllName " is " other_bitness " . "
2018-04-22 18:20:30 +00:00
ExitApp
}
DllCall ( " FreeLibrary " , " Ptr " , hModule )
2018-03-29 13:59:20 +00:00
dllName := " AutoHotInterception.dll "
dllFile := A_LineFile " \..\ " dllName
2018-03-30 15:03:35 +00:00
hintMessage := " Try right-clicking lib\ " dllName " , select Properties, and if there is an 'Unblock' checkbox, tick it`nAlternatively, running Unblocker.ps1 in the lib folder (ideally as admin) can do this for you. "
2019-01-31 01:46:08 +00:00
if ( ! FileExist ( dllFile ) ) {
2018-04-22 17:48:41 +00:00
MsgBox % " Unable to find lib\ " dllName " , exiting... "
2018-03-28 19:39:29 +00:00
ExitApp
}
2018-10-06 14:39:52 +00:00
2018-03-28 19:39:29 +00:00
asm := CLR_LoadLibrary ( dllFile )
try {
2018-03-30 18:04:58 +00:00
this . Instance := asm . CreateInstance ( " AutoHotInterception. " cls )
2018-03-28 19:39:29 +00:00
}
catch {
2018-03-29 14:28:54 +00:00
MsgBox % dllName " failed to load`n`n " hintMessage
2018-03-28 19:39:29 +00:00
ExitApp
}
2019-01-31 01:46:08 +00:00
if ( this . Instance . OkCheck ( ) != " OK " ) {
2018-03-29 14:28:54 +00:00
MsgBox % dllName " loaded but check failed!`n`n " hintMessage
2018-03-28 19:39:29 +00:00
ExitApp
}
2018-03-06 19:53:04 +00:00
}
2019-01-31 01:46:08 +00:00
GetInstance ( ) {
2018-03-30 18:06:04 +00:00
return this . Instance
}
2019-01-31 01:46:08 +00:00
2018-03-30 18:04:58 +00:00
; --------------- Input Synthesis ----------------
2019-01-31 01:46:08 +00:00
SendKeyEvent ( id , code , state ) {
2018-03-30 18:04:58 +00:00
this . Instance . SendKeyEvent ( id , code , state )
}
2019-01-31 01:46:08 +00:00
SendMouseButtonEvent ( id , btn , state ) {
2018-03-30 18:04:58 +00:00
this . Instance . SendMouseButtonEvent ( id , btn , state )
}
2019-01-31 01:46:08 +00:00
SendMouseButtonEventAbsolute ( id , btn , state , x , y ) {
2018-03-31 17:49:19 +00:00
this . Instance . SendMouseButtonEventAbsolute ( id , btn , state , x , y )
}
2019-01-31 01:46:08 +00:00
SendMouseMove ( id , x , y ) {
2018-03-30 18:04:58 +00:00
this . Instance . SendMouseMove ( id , x , y )
}
2019-01-31 01:46:08 +00:00
SendMouseMoveRelative ( id , x , y ) {
2018-03-30 18:04:58 +00:00
this . Instance . SendMouseMoveRelative ( id , x , y )
}
2019-01-31 01:46:08 +00:00
SendMouseMoveAbsolute ( id , x , y ) {
2018-03-30 18:04:58 +00:00
this . Instance . SendMouseMoveAbsolute ( id , x , y )
}
* /
; --------------- Querying ------------------------
2019-01-31 01:46:08 +00:00
GetDeviceId ( IsMouse , VID , PID , instance := 1 ) {
2018-03-30 18:04:58 +00:00
static devType := { 0 : " Keyboard " , 1 : " Mouse " }
2018-07-02 17:50:57 +00:00
dev := this . Instance . GetDeviceId ( IsMouse , VID , PID , instance )
2019-01-31 01:46:08 +00:00
if ( dev == 0 ) {
2018-03-30 18:04:58 +00:00
MsgBox % " Could not get " devType [ isMouse ] " with VID " VID " , PID " PID " , Instance " instance
ExitApp
}
return dev
}
2019-01-31 01:46:08 +00:00
GetDeviceIdFromHandle ( isMouse , handle , instance := 1 ) {
2018-07-02 17:54:19 +00:00
static devType := { 0 : " Keyboard " , 1 : " Mouse " }
dev := this . Instance . GetDeviceIdFromHandle ( IsMouse , handle , instance )
2019-01-31 01:46:08 +00:00
if ( dev == 0 ) {
2018-07-02 17:54:19 +00:00
MsgBox % " Could not get " devType [ isMouse ] " with Handle " handle " , Instance " instance
ExitApp
}
return dev
}
2019-01-31 01:46:08 +00:00
GetKeyboardId ( VID , PID , instance := 1 ) {
2018-07-02 17:50:57 +00:00
return this . GetDeviceId ( false , VID , PID , instance )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
GetMouseId ( VID , PID , instance := 1 ) {
2018-07-02 17:50:57 +00:00
return this . GetDeviceId ( true , VID , PID , instance )
2018-03-06 19:53:04 +00:00
}
2019-01-31 01:46:08 +00:00
GetKeyboardIdFromHandle ( handle , instance := 1 ) {
2018-07-02 18:07:27 +00:00
return this . GetDeviceIdFromHandle ( false , handle , instance )
2018-07-02 17:54:19 +00:00
}
2019-01-31 01:46:08 +00:00
GetMouseIdFromHandle ( handle , instance := 1 ) {
2018-07-02 18:07:27 +00:00
return this . GetDeviceIdFromHandle ( true , handle , instance )
2018-07-02 17:54:19 +00:00
}
2019-01-31 01:46:08 +00:00
GetDeviceList ( ) {
2018-03-28 19:39:29 +00:00
DeviceList := { }
2018-03-30 18:04:58 +00:00
arr := this . Instance . GetDeviceList ( )
2018-03-28 19:39:29 +00:00
for v in arr {
2018-07-02 17:54:19 +00:00
DeviceList [ v . id ] := { ID : v . id , VID : v . vid , PID : v . pid , IsMouse : v . IsMouse , Handle : v . Handle }
2018-03-28 19:39:29 +00:00
}
return DeviceList
2018-03-06 19:53:04 +00:00
}
2019-01-31 01:46:08 +00:00
2018-03-30 18:04:58 +00:00
; ---------------------- Subscription Mode ----------------------
2019-01-31 01:46:08 +00:00
SubscribeKey ( id , code , block , callback , concurrent := false ) {
2019-01-28 13:53:58 +00:00
this . Instance . SubscribeKey ( id , code , block , callback , concurrent )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
SubscribeMouseButton ( id , btn , block , callback , concurrent := false ) {
2019-01-28 13:53:58 +00:00
this . Instance . SubscribeMouseButton ( id , btn , block , callback , concurrent )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
SubscribeMouseMove ( id , block , callback , concurrent := false ) {
2019-01-28 13:53:58 +00:00
this . Instance . SubscribeMouseMove ( id , block , callback , concurrent )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
SubscribeMouseMoveRelative ( id , block , callback , concurrent := false ) {
2019-01-28 13:53:58 +00:00
this . Instance . SubscribeMouseMoveRelative ( id , block , callback , concurrent )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
SubscribeMouseMoveAbsolute ( id , block , callback , concurrent := false ) {
2019-01-28 13:53:58 +00:00
this . Instance . SubscribeMouseMoveAbsolute ( id , block , callback , concurrent )
2018-03-30 18:04:58 +00:00
}
2019-01-31 01:46:08 +00:00
2018-03-30 18:04:58 +00:00
; ------------- Context Mode ----------------
; Creates a context class to make it easy to turn on/off the hotkeys
2019-01-31 01:46:08 +00:00
CreateContextManager ( id ) {
if ( this . _contextManagers . ContainsKey ( id ) ) {
2018-03-30 18:04:58 +00:00
Msgbox % " ID " id " already has a Context Manager "
ExitApp
}
cm := new this . ContextManager ( this , id )
this . _contextManagers [ id ] := cm
return cm
}
; Helper class for dealing with context mode
class ContextManager {
IsActive := 0
2019-01-31 01:46:08 +00:00
__New ( parent , id ) {
2018-03-30 18:04:58 +00:00
this . parent := parent
this . id := id
result := this . parent . Instance . SetContextCallback ( id , this . OnContextCallback . Bind ( this ) )
}
2019-01-31 01:46:08 +00:00
OnContextCallback ( state ) {
2018-03-30 18:04:58 +00:00
Sleep 0
this . IsActive := state
}
}
2018-03-06 19:53:04 +00:00
}