1 (изменено: Piton, 2018-11-16 12:37:06)

Тема: 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
			}
		}
    }
}

2

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

Piton, добавьте префикс скриптового языка в название темы. Оформите код тегом "Code". Поставьте заглавную букву в предложении.

3

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

stealzy пишет:

Переименуйте тему по правилам, код оборачивают тегом код.
Send {RButton Down}, Send {RButton Up} — действие происходит на этих строках, для начала поставьте перед ними ToolTip-ы чтобы убедиться, что они выполняются.

stealzy Спасибо за ответ, ToolTipы поставил. В "проблемных" приложениях правая кнопка мыши через S-pen отрабатывает на уровне autohotkey судя по информации в окне ToolTip, при этом в самом приложении ничего не происходит. По всей видимости сложность в том, что эти приложения обучены работать с планшетным пером, и когда на экране имеется курсор пера, то обработка вызова правой кнопки мыши осуществляется нестандартно этими приложениями (Office, Krita, Chrome...). Подскажите пожалуйста, что ещё можно попробовать чтобы определить причину проблемы работы правой кнопки мыши через кнопку стилуса используя AHK  в прриложениях перечисленных выше?

4

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

stealzy пишет:

Попробовать заменить Send на Click.

не помогло к сожалению

5

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

Пробуйте другие режимы для send.
У вас это самая первая строка:

SendMode Input

6 (изменено: Piton, 2018-11-27 13:44:59)

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

Malcev Спасибо за ответ, пробовал разные режимы play и тд аналогичный результат, проблема осталась

7

Re: AHK: стилус не работает в некоторых приложениях (right mouse button)

Пробуйте отправлять на хардварном уровне:
https://autohotkey.com/boards/viewtopic.php?t=9009
https://autohotkey.com/boards/viewtopic.php?t=27007
https://autohotkey.com/boards/viewtopic … mp;t=45307