Прокрутка по горизонтали в Adobe Reader с помощью AutoHotkey

0

Я хочу использовать AutoHotkey для горизонтальной прокрутки документа в Adobe Reader X. Отправка сообщений колесика (0x20e) не работает, а также отправка сообщений прокрутки (0x114). Единственный способ, который я мог найти, - это отправлять клики на стрелки полосы прокрутки, но это делает прокрутку по горизонтали очень медленной, помимо того, что сильно замедляет одновременную вертикальную прокрутку. Кроме того, я заметил, что мой драйвер мыши (UltraNav) может прокручиваться в явно модальном диалоговом окне в Adobe Reader X, таком как диалоговое окно «Открыть файл», в то время как ни один из вышеперечисленных трех методов не может. Так кто-нибудь знает, что мой драйвер мыши может делать или по-другому?

Я только что нашел четвертый метод, который работает довольно хорошо для большинства приложений, для которых первые два не дают результатов, - это отправка клавиш со стрелками на полосу прокрутки. Когда он отвечает правильно, он также отвечает на {PgUp} и {PgDn}, которые прокручивают страницу. Тем не менее, он все еще не работает в модальном диалоговом окне, поэтому то, что делает драйвер мыши, остается для меня загадкой, хотя кажется, что оно прокручивается на те же суммы. Кроме того, этот метод не работает в проводнике Windows (как ожидается); ключи, отправленные на полосы прокрутки, также отправляются в основную область. Например, controlsend,%scrollbarname%,{Down},ahk_id %window%будет успешно прокручиваться полоса прокрутки, но при этом текущая позиция выбора будет перемещаться вниз, если это возможно. Я не могу найти какой-либо другой способ управления горизонтальной полосой прокрутки в проводнике Windows без отправки щелчков мыши.

редактировать

Посмотрите прокрутку AutoHotkey и ускорение среднего щелчка и мыши, которая была моей первоначальной целью, Adobe Reader - лишь одно из многих приложений, которые не понимают обычные сообщения колесика.

user21820
источник

Ответы:

1

У Adobe Reader есть странный способ обработки горизонтальной прокрутки. Это то, что я использую, чтобы решить эту проблему:

#IfWinActive, ahk_exe Acrobat.exe
F13::
  While GetKeyState("F13") {
    Send, {Shift down}{WheelUp}
    Sleep, 100
  }
  Send, {Shift up}
  Return

F14::
  While GetKeyState("F14") {
    Send, {Shift down}{WheelDown}
    Sleep, 100
  }
  Send, {Shift up}
  Return
#IfWinActive

Примечание. Я изменил назначение клавиш левой и правой прокрутки мыши на клавиши F, чтобы их можно было использовать в AutoHotKey, поскольку я также использую Logitech SetPoint.

Stephan
источник
Извините, я забыл ответить на свой вопрос после того, как несколько месяцев спустя нашел собственное решение. Смотрите мой ответ для деталей.
user21820
У меня недостаточно очков, чтобы комментировать ваш ответ, но я просто хотел поблагодарить вас за то, что вы поделились своим решением.
Стефан
Конечно, пожалуйста! Если у вас есть какие-либо вопросы по поводу моего решения или моего полного сценария по другому вопросу, который я создал, не стесняйтесь спрашивать меня. Чтобы уведомить одного пользователя, @<username>укажите где-нибудь свой комментарий.
user21820
0

Вы можете щелкнуть (только нажмите левую кнопку мыши, пока не высвободите ее) в начале полосы прокрутки, там, где на изображении ниже находится красная точка. После перемещения мыши как можно ниже, в том месте, где зеленая точка находится на изображении ниже. Теперь отпустите левую кнопку мыши. Скорость прокрутки должна быть достаточно хорошей.

введите описание изображения здесь

Вот полный код скрипта AutoHotkey:

CoordMode, Mouse, Screen
InitX := 
InitY :=
DestX := 
DestY :=
Click, Left, Down, %InitX%, %InitY%
Mousemove, %DestX%, %DestY%, 0
Click, Left, Up

Переменные InitX и InitY должны содержать координаты (x и y соответственно) начальных точек. Координаты красной точки на изображении выше.

Переменные DestX и DestY должны содержать координаты (x и y соответственно) для пунктов назначения. Координаты зеленой точки на изображении выше.

ИЗДАНО :

Может ли это помочь вам: http://ahkscript.org/boards/viewtopic.php?f=5&t=4028

Загрузите новую версию AutoHotkey с http://ahkscript.org/ (текущая версия). AutoHotkey от autohotkey.com устарел!

vasili111
источник
Ну, я не упомянул этот метод в своем вопросе, но это не то, что я хочу, так как скорость прокрутки будет изменяться в зависимости от ширины документа и совсем не будет плавной для широких документов. И я хотел горизонтальную прокрутку, потому что сообщения вертикального колеса хорошо работают для большинства приложений.
user21820
Кстати, я использую AutoHotkey_L, который, я считаю (не могу вспомнить, откуда я его скачал), взят с сайта ahkscript.org. =)
user21820
@ user21820 Мой сценарий будет работать с любой полосой прокрутки (горизонтальной или вертикальной или любой другой;)), просто дайте ей правильные координаты (начальную и конечную). Скорость прокрутки будет достаточно быстрой. Если вам нужно сделать это плавно, вы можете играть со скоростью мыши. В настоящее время это имеет значение 0. Это может пойти до 100(больше значения, меньше скорость). И да, скорость прокрутки зависит от ширины документа. Код обновлен.
vasili111
Вы не понимаете Если документ длинный, просто перетаскивая полосу прокрутки на 1 пиксель, можно будет прокрутить его на много страниц. Это абсолютно нежелательно, поэтому сообщения колесика лучше подходят для вертикальной прокрутки. Для горизонтальной прокрутки это обычно не так уж плохо, но я все еще не хочу, чтобы скорость прокрутки изменялась в зависимости от ширины документа. В любом случае, поскольку мой четвертый метод отлично работает с Adobe Reader, у меня остается только один вопрос: что именно делает UltraNav? Но спасибо, что поделились своим методом!
user21820
@ user21820 В конце моего вопроса проверьте раздел EDITED . Может быть, это может помочь вам.
vasili111
0

Короткий ответ

Для горизонтальной прокрутки в 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)
}
user21820
источник
0

Мое решение:

#IfWinActive, ahk_exe Acrobat.exe
WheelLeft::
    Send,{shift down}
    sleep,20
    Send,{WheelUp}
    sleep,20
    Send,{shift up}
    return
WheelRight::
    Send,{shift down}
    sleep,20
    Send,{WheelDown}
    sleep,20
    Send,{shift up}
    return
#IfWinActive

Вы можете увеличить число 20, чтобы прокрутить медленнее

Фейран Чжан
источник