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

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

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

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

3 ответа3

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.

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)
}
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 устарел!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .