Короткий ответ
Для горизонтальной прокрутки в Adobe Reader X отправляйте сообщения прокрутки родительскому элементу полосы прокрутки, как в sendscrolltoscrollbarparent
коде. Многие другие способы не будут работать должным образом. Этот метод дает очень быструю прокрутку, даже лучше, чем мой оригинальный драйвер мыши.
Длинный ответ
Я нашел свои ответы, но забыл об этом вопросе. По сути, я использовал уникальный метод для каждого безумного приложения. Поскольку их слишком много, я создал отдельный вопрос и ответ для всего лота ( прокрутка AutoHotkey и ускорение щелчка средней кнопкой мыши и мыши ), и здесь приведу только части, относящиеся к Adobe Reader.
Процесс должен идти так. Сначала вы вызываете gettarget
, что предполагает, что положение мыши сохранено, mx,my
и находит правильную цель для событий прокрутки на основе того, что в данный момент находится под мышью. Затем вы повторно звоните scroll
после добавления суммы, чтобы перейти к sx,sy
.
Для Adobe Reader даже вертикальная прокрутка зависит от отправки сообщений колесика в нужное место, что не согласуется, и поэтому я закончил жестким кодированием для двух основных случаев: прокрутки области отображения документа и прокрутки области закладок. Чтобы выяснить, в каком случае это происходит, я проверяю, есть ли у родительского элемента управления под мышкой вызываемый потомок AVL_AVView4
или нет. Если это так, то это то, что нужно для отправки сообщений вертикального колеса, в исполнении sendwheel
. Но для горизонтальной прокрутки получается, что отправка сообщений прокрутки на родительский элемент управления правильной полосы прокрутки работает в обоих местах, и выполняется sendscrolltoscrollbarparent
. Правильная полоса прокрутки - это та, scrollbar1
которая называется потомком родительского элемента управления под мышью.
Код
#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)
}