Respuesta corta
Para el desplazamiento horizontal en Adobe Reader X, envíe mensajes de desplazamiento al padre de la barra de desplazamiento, como sendscrolltoscrollbarparent
en el código. Muchas otras formas no funcionarían correctamente. Este método de alguna manera proporciona un desplazamiento muy rápido, incluso mejor que mi controlador de mouse original.
Respuesta larga
Había encontrado mis propias respuestas, pero me había olvidado de esta pregunta. Básicamente, utilicé un método idiosincrásico para todas y cada una de las aplicaciones locas. Como hay demasiados, he creado una pregunta y una respuesta por separado para todo el lote ( desplazamiento de AutoHotkey y aceleración del clic central y del mouse ), y solo proporciono las partes relevantes para Adobe Reader aquí.
El proceso debería ser así. Primero llama gettarget
, lo que supone que la posición del mouse está almacenada mx,my
y encuentra el objetivo correcto para los eventos de desplazamiento en función de lo que está actualmente debajo del mouse. Luego llama repetidamente scroll
después de agregar la cantidad a la que desea desplazarse sx,sy
.
Para Adobe Reader, incluso el desplazamiento vertical depende del envío de mensajes de rueda al lugar correcto, lo que no es coherente y, por lo tanto, terminé codificando los dos casos principales, que desplazan el área de visualización del documento y el área de marcadores. Para averiguar qué caso es, verifico si el padre del control bajo el mouse tiene un descendiente llamado AVL_AVView4
o no. Si lo hace, entonces ese es el correcto para enviar mensajes de rueda vertical, realizado por sendwheel
. Pero para el desplazamiento horizontal, resulta que enviar mensajes de desplazamiento al control principal de la barra de desplazamiento correcta funciona en ambos lugares, realizado por sendscrolltoscrollbarparent
. La barra de desplazamiento correcta es la que se llama scrollbar1
descendiente del padre del control bajo el mouse.
Código
#commentflag // ; Change to C++ comment style
global mx,my
global sx:=0
global sy:=0
global ctrl,window,parent
global methodx
global methody
global scrollbarx
global scrollbary
global max16bit:=32767
gettarget()
{
ctrl:=getctrlat(mx,my)
window:=getwindow(ctrl)
class:=getclass(window)
parent:=getparent(ctrl)
parentname:=getnameatroot(parent)
if( class=="AcrobatSDIWindow" )
{
if( regexmatch(parentname,"AVL_AVView")==1 )
{
ctrl:=getdescendant(parent,"AVL_AVView4")
if( ctrl=="" )
{
ctrl:=getdescendant(parent,"AVL_AVView1")
}
methodx:="scrolltoscrollbarparent"
scrollbarx:="scrollbar1"
methody:="wheel"
}
}
}
scroll:
critical on
tx:=sx
ty:=sy
sx-=tx
sy-=ty
rx:=0
ry:=0
if( tx!=0 )
{
txi:=rtoz(tx)
rx:=tx-txi
if( txi!=0 )
{
if( methodx=="scrolltoscrollbarparent" )
{
sendscrolltoscrollbarparent(scrollbarx,"h",txi)
}
}
}
if( ty!=0 )
{
if( methody=="wheel" )
{
sendwheel("v",-ty)
}
}
sx:=rx
sy:=ry
return
sendwheel(dir,amount)
{
t:=a_tickcount
msg:=( dir=="v" ? 0x20a : 0x20e )
flags:=getkeystate("Ctrl")<<3|getkeystate("Shift")<<2
amount*=120
while( amount>max16bit )
{
sendmessage msg,max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit
amount-=max16bit
if( a_tickcount-t>=timelimit )
{
return
}
}
while( amount<-max16bit )
{
sendmessage msg,-max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit
amount+=max16bit
if( a_tickcount-t>=timelimit )
{
return
}
}
sendmessage msg,round(amount)<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit
}
sendscrolltoscrollbarparent(name,dir,amount)
{
sb:=getdescendant(parent,name)
sbp:=getparent(sb)
t:=a_tickcount
msg:=( dir=="v" ? 0x115 : 0x114 )
flag:=( amount<0 ? 0 : 1 )
loop % abs(amount)
{
sendmessage msg,flag,sb,,ahk_id %sbp%,,,,timelimit
if( a_tickcount-t>=timelimit )
{
return
}
}
}
rtoz(r)
{
return ( r>0 ? floor(r) : ceil(r) )
}
getparent(handle)
{
return dllcall("GetParent","uint",handle)
}
getname(root,handle)
{
local CH,CN,S,P
WinGet, CH, ControlListHwnd, ahk_id %root%
WinGet, CN, ControlList, ahk_id %root%
setformat integerfast,h
handle+=0
handle.=""
setformat integerfast,d
LF:= "`n", CH:= LF CH LF, CN:= LF CN LF, S:= SubStr( CH, 1, InStr( CH, LF handle LF ) )
StringReplace, S, S,`n,`n, UseErrorLevel
StringGetPos, P, CN, `n, L%ErrorLevel%
Return SubStr( CN, P+2, InStr( CN, LF, 0, P+2 ) -P-2 )
}
getdescendant(handle,name)
{
local CH,CN,S,P
WinGet, CH, ControlListHwnd, ahk_id %handle%
WinGet, CN, ControlList, ahk_id %handle%
setformat integerfast,h
handle+=0
handle.=""
setformat integerfast,d
LF:= "`n", CH:= LF CH LF, CN:= LF CN LF, S:= SubStr( CN, 1, InStr( CN, LF name LF ) )
StringReplace, S, S,`n,`n, UseErrorLevel
StringGetPos, P, CH, `n, L%ErrorLevel%
Return SubStr( CH, P+2, InStr( CH, LF, 0, P+2 ) -P-2 )*1
}
getnameatroot(handle)
{
return getname(dllcall("GetAncestor","uint",handle,"uint",2),handle)
}
getnameaschild(handle)
{
return getname(getparent(handle),handle)
}
getclass(handle)
{
local class
wingetclass class,ahk_id %handle%
return class
}
getwindow(handle)
{
return dllcall("GetAncestor","uint",handle,"uint",2)
}
getctrlat2(x,y,first,current)
{
/*
Pushes the following invisible container controls to the back because they are in front of their contents for no reason
SysTabControl32 : The usual class that contains tabbed panes ( Mouse properties , ... )
Static : A class occasionally used to contain tabbed panes ( Programmer's Notepad Options > Fonts and Colours > Advanced , ... )
Button : A typical class used to contain a List Box ( Outlook Contact > Properties > General > Members , ... )
Executes WindowFromPoint again to access the contents of such container controls
*/
local handle,class,style
class:=getclass(current)
winget style,style,ahk_id %current%
if( class=="SysTabControl32" or class=="Static" or ( class=="Button" and (style&0x7)==0x7 ) )
{
dllcall("SetWindowPos","uint",current,"uint",1,"int",0,"int",0,"int",0,"int",0,"uint",0x3) // push it to the back where it belongs
handle:=dllcall("WindowFromPoint","int",x,"int",y)
//handle:=DllCall( "WindowFromPoint", "int64", (my << 32) | (mx & 0xFFFFFFFF), "Ptr") // for negative 64-bit
if( handle==first )
{
return first
}
return getctrlat2(x,y,first,handle)
}
return current
}
getctrlat(x,y)
{
local handle
handle:=dllcall("WindowFromPoint","int",x,"int",y)
//handle:=DllCall( "WindowFromPoint", "int64", (my << 32) | (mx & 0xFFFFFFFF), "Ptr") // for negative 64-bit
return getctrlat2(x,y,handle,handle)
}