Тема: AHK: стилус не работает в некоторых приложениях (right mouse button)
Привет! В наличии имеется планшет Samsung Galaxy Book 12 (со стилусом S-Pen). На стилусе имеется кнопка, которая дефолтно не переназначается под правую кнопку мышы. Чтобы это исправить написали скрипт AHK который переназначает кнопку пера (стилуса) на правый клик мышы. Скрипт в целом работает хорошо, кнопка стилуса отрабатывает как правая кнопка в большинстве приложений. Но есть несколько приложений, которые упорно не позволяют внутри себя (внутри окна данных приложений) отрабатывать нажатию кнопки стилуса как нажатию правой кнопки мыши. В таких приложениях просто не отрабатывается правая кнопка мыши, т.е. при нажатии кнопки на стилусе ничего не происходит.
Скрипт не работает в следующих приложениях:
- В браузере Chrome
- В MS Office
- В рисовальном приложении Krita (аналог Photoshop), а если быть точным, то не работает только в главном окне приложения (т.е. в окне холста, - где непосредственно происходит рисование стилусом и по правой кнопке мыши вызывается меню кистей), в других окнах Krita правая кнопка работает.
Поделитесь пожалуйста советом что может влиять на данную ситуацию, и как побороть эту проблему, как сделать, чтобы все приложения без исключения видели нажатие правой кнопки мыши в момент нажатия аппаратной кнопки на стилусе. Или хотябы как понять каким образом этими приложениями обрабатывается команда от AHK, что эта команда не учитывается приложением.
Сам скрипт:
SendMode Input
SetWorkingDir %A_ScriptDir%
Coordmode, Mouse, Screen
; write the coordinates you get from "example2_with_min_max_XY.ahk"
global Xmin := 0
global Xmax := 25272
global Ymin := 0
global Ymax := 16848
; write the resolution of your display
global screenXmax := 2160
global screenYmax := 1440
; calculation the ratio to convert pen coordinates to mouse coordinates
global kX := (Xmax - Xmin) / screenXmax
global kY := (Ymax - Ymin) / screenYmax
; Set up our pen constants
global PEN_HOVERING := 0 ; Pen is inside the area where screen see the pen and pen and don't touch the screen.
global PEN_TOUCHING := 1 ; Pen is touching screen.
global PEN_BTN_HOVERING := 8 ; Button is pressed with pen is inside the area where screen see the pen and pen and don't touch the screen.
global PEN_BTN_TOUCHING := 12 ; Button is pressed with pen is touching screen.
/*
The package from pen data flow
Package consist of 26 blocks
00 0 0 0000 0011 1111 11 1122 2222 ; Blocks address with size 4 bits
01 2 3 4567 8901 2345 67 8901 2345 ;
02 2 0 0000 0000 0000 20 0000 0000 ; Left Up of the screen
02 0 0 0000 0000 0000 20 0000 0000 ; Out of screen
02 2 0 B662 CC41 0000 20 0000 0000 ; Right Down of the screen
02 0 0 B662 CC41 0000 20 0000 0000 ; Out of screen
02 2 0 0000 0000 0000 58 0000 0000 ; Almost out of the screen (but screen still see the pen)
02 2 0 0000 0000 0000 00 0000 0000 ; Almost touching the screen (but not touching)
02 2 1 0000 0000 0100 00 6400 8403 ; Touching the screen
Resume:
xx x x xxxx xxxx xxxx xx #### #### ; ???? tiltX tiltY
xx x x xxxx xxxx xxxx ## xxxx xxxx ; Z position
xx x x xxxx xxxx #### xx xxxx xxxx ; ????
xx x x xxxx #### xxxx xx xxxx xxxx ; Y position
xx x x #### xxxx xxxx xx xxxx xxxx ; X position
xx x # xxxx xxxx xxxx xx xxxx xxxx ; Using mode
xx # x xxxx xxxx xxxx xx xxxx xxxx ; Connection mode
## x x xxxx xxxx xxxx xx xxxx xxxx ; ????
Connection mode:
2 - Connection with pen exists
0 - Lose connection with pen
Using mode:
0x00 ( 0) - Hovering
0x01 ( 1) - Touching (after touching button will not be active)
0x08 ( 8) - Button is pressed when hovering
0x0C (12) - Touching with button pressed (after touching button will not be active)
X position pen:
0000 - minimum = 0
(B862) 0x62B8 - about maximum = 25272 (2160 points) 12 pen points in 1 screen point
Cursor X position = X position pen / 12
Y position pen:
0000 - minimum = 0
(D041) 0x41D0 - about maximum = 16848 (1440 points) 12 pen points in 1 screen point
Cursor Y position = Y position pen / 12
*/
/*
Convert blocks of package to date structure from variables
Package consist of 26 blocks
00 0 0 0000 0011 1111 11 1122 2222 ; Blocks address with size 4 bits
01 2 3 4567 8901 2345 67 8901 2345 ;
Data structure from variables:
UInt (32 bits) (variables 1)
00000000 ; Blocks address with size 4 bits
67452301 ;
UInt (32 bits) (variables 2)
11111100 ; Blocks address with size 4 bits
45230189 ;
UInt (32 bits) (variables 3)
22221111 ; Blocks address with size 4 bits
23018967 ;
UInt (32 bits) (variables 4)
33222222 ; Blocks address with size 4 bits
01896745 ;
*/
; Send Alt, Ctrl and Shift keys along with the right-click if
; necessary
SendModifierKeys() {
static lastAlt := 0
static lastCtrl := 0
static lastShift := 0
AltState := GetKeyState("Alt")
CtrlState := GetKeyState("Ctrl")
ShiftState := GetKeyState("Shift")
if (AltState <> lastAlt) {
if (AltState)
{
Send {Alt Down}
} else {
Send {Alt Up}
}
lastAlt := AltState
}
if (CtrlState <> lastCtrl) {
if (CtrlState) {
Send {Ctrl Down}
} else {
Send {Ctrl Up}
}
lastCtrl := CtrlState
}
if (ShiftState <> lastShift) {
if (ShiftState) {
Send {Shift Down}
} else {
Send {Shift Up}
}
lastShift := ShiftState
}
}
; Calucation radius offset cursor mouse
RadiusMouseOffset(mouseXpos_Old, mouseXpos, mouseYpos_Old, mouseYpos){
Local RadiusTrimerDisableOnMouse := 100
Local dX := mouseXpos_Old - mouseXpos
Local dY := mouseYpos_Old - mouseYpos
if (sqrt(dX * dX + dY * dY) < RadiusTrimerDisableOnMouse){
MouseMove %mouseXpos_Old%, %mouseYpos_Old%, 0 ;Send to system cursor old position of mouse/pen
}else{
MouseMove %mouseXpos%, %mouseYpos%, 0 ;Send to system cursor new position of mouse/pen
}
}
#include AHKHID.ahk
WM_INPUT := 0xFF
USAGE_PAGE := 13
USAGE := 2
AHKHID_UseConstants()
AHKHID_AddRegister(1)
AHKHID_AddRegister(USAGE_PAGE, USAGE, A_ScriptHwnd, RIDEV_INPUTSINK)
AHKHID_Register()
OnMessage(WM_INPUT, "Work")
Work(wParam, lParam) {
Local type, inputInfo, inputData, raw, UsingMode, ConnectionMode
; static iii := 0
static lastInput := -1 ; Last code for compare with constants
static sPen_RBtn := 0 ;Last state of pen
Local sPen_Xpos ;X position cursor of pen
Local sPen_Ypos ;Y position cursor of pen
; Local sPen_Zpos ;Z position cursor of pen
Local mouseXpos ;X position cursor of mouse
Local mouseYpos ;Y position cursor of mouse
Local mouseXpos_Old ;X position cursor of mouse
Local mouseYpos_Old ;Y position cursor of mouse
Critical
;Get device type
type := AHKHID_GetInputInfo(lParam, II_DEVTYPE) ;Connect to device
if (type = RIM_TYPEHID) { ;if type device is "pen"
inputData := AHKHID_GetInputData(lParam, uData) ;Connect to commands flow of pen
sPen_Xpos := NumGet(uData, 2, "WORD") ;Read X position cursor of pen (offset on 2 bytes in package, size in 16 bits (2 bytes))
sPen_Ypos := NumGet(uData, 4, "WORD") ;Read Y position cursor of pen (offset on 4 bytes in package, size in 16 bits (2 bytes))
sPen_Xpos := (sPen_Xpos & 0xFFFF)
sPen_Ypos := (sPen_Ypos & 0xFFFF)
mouseXpos := sPen_Xpos / kX ; Convert to X position cursor for mouse
mouseYpos := sPen_Ypos / kY ; Convert to Y position cursor for mouse
/*
sPen_Zpos := NumGet(uData, 8, "UChar") ;Read Z position cursor of pen (offset on 8 bytes in package, size in 8 bits (1 byte))
*/
raw := NumGet(uData, 1, "UChar") ;Read Z position cursor of pen (offset on 8 bytes in package, size in 8 bits (1 byte))
UsingMode := raw & 0x1F ;Decode command to code using mode for compare with constants
ConnectionMode := raw & 0x20 ; Decode command to code connection mode for tracking the information flow from pen till screen see the pen
; iii++
; if (mod(iii,2) = 0){
; FileAppend, >[%sPen_Xpos%][%sPen_Ypos%].[%mouseXpos%][%mouseYpos%].[%UsingMode%].[%ConnectionMode%]`n, *C:\draw\777.txt
; }else{
; FileAppend, >[%sPen_Xpos%][%sPen_Ypos%].[%mouseXpos%][%mouseYpos%].[%UsingMode%].[%ConnectionMode%], *C:\draw\777.txt
; }
if (ConnectionMode <> 0){ ; Connection with pen exists
if (UsingMode <> lastInput) { ;Check the difference commands in flow
if (UsingMode == PEN_BTN_HOVERING){ ;New code is "hovering + btn"
sPen_RBtn := 1 ;Mark pressed button state
; MouseMove -100, -100, 0 ;Send to system cursor position of mouse/pen out of the screen (Krita and Chrome cheating)
; Click left
MouseMove %mouseXpos%, %mouseYpos%, 0 ;Send to system cursor position of mouse/pen
mouseXpos_Old := mouseXpos
mouseYpos_Old := mouseYpos
SendModifierKeys()
Send {RButton Down} ;Right button pressed
}else{
if (lastInput == PEN_BTN_HOVERING){ ;Last code is "hovering + btn"
; RadiusMouseOffset(mouseXpos_Old, mouseXpos, mouseYpos_Old, mouseYpos)
SendModifierKeys()
Send {RButton Up} ;Right button is release
}
sPen_RBtn := 0 ;Mark button released state
}
lastInput := UsingMode ;Save new code for new loop
}
}else{ ; Lost connection with pen
if (sPen_RBtn <> 0){ ;Last state of pen "Button is pressed"
; RadiusMouseOffset(mouseXpos_Old, mouseXpos, mouseYpos_Old, mouseYpos)
SendModifierKeys()
Send {RButton Up} ;Right button is release
}
}
}
}