1

Тема: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

В Firefox есть такая маст хэв опция middlemouse.scrollbarPosition;true, которая мгновенно переносит в любую точку скроллбара по нажатию СКМ, в остальной же системе это реализовано с помощью зажатия Shift+ЛКМ, а СКМ простаивает. Так вот, всегда мечтал перенести эту возможность во все используемые программы, и судя по всему, опять AHK+мастера script-coding.com=мечты сбываются.

Из темы AHK: Зумирование изображений в браузере колесом мыши. узнал, что можно выделить любую часть окна приложения, в которой будут действовать нужные переназначения, т.е. можно переназначить только на скроллбарах СКМ=Shift+ЛКМ. Так-же как бонус, назначать любые другие функции на элементы интерфейса, например, левый клик по статусбару Notepad++, как выделено зелёным на изображении, возвращает вверх документа, посылая СКМ=Shift+HOME, а правый клик, в самый низ, посылая СКМ=Shift+END.

Помогите пожалуйста готовым кодом, в который я бы мог сам добавлять ahk_exe и корректировать координаты для разных приложений, что-то вроде этого:

ahk_exe Notepad++.exe
Координаты вертикального скроллбара: *
СКМ=Shift+ЛКМ
ahk_exe Notepad++.exe
Координаты горизонтального скроллбара: *
СКМ=Shift+ЛКМ
ahk_exe Notepad++.exe
Координаты статусбара: *
ЛКМ=СКМ+Ctrl+HOME
ahk_exe Notepad++.exe
Координаты статусбара: *
ЛКМ=СКМ+Ctrl+END
ahk_exe MPC-BE.exe
Координаты вертикального скроллбара: *
ЛКМ=Shift+ЛКМ
Сам исполнительный код...

http://i.imgur.com/wA53jvc.png

2

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Наваял пока весьма черновой скрипт для этого. Работает, в принципе примерно так, как и просили, но скриптом я пока очень недоволен.
Есть объект scrollBars, который надо наполнять данными для обучения скрипта работе со скроллбарами разных окон.
'exe' - ProcessName принадлежащий окну;
'ctrl' - classNN control'а, который показывает WinSpy при наведении на scrollbar;
'sbvlo' - отступ от правой границы окна влево до левой границы вертикального scrollbar;
'sbvro' - отступ от правой границы окна влево до правой границы вертикального scrollbar;
'sbhto' - отступ от нижней границы окна вверх до верхней границы горизонтального scrollbar;
'sbhbo' - отступ от нижней границы окна вверх до нижней границы горизонтального scrollbar;
Все отступы в пикселях.

Скрипт умеет работать и с неактивными окнами, но для работы с неактивными окнами пока надо активировать их, есть настройка doNotSwitchWinFocus, если она включена (true), то скрипт будет возвращать фокус на первоначально активное окно.

По-хорошему, чтобы скрипт работал правильно - надо решить пару проблем, которые я пока не уверен, что решаемые:
1. т.к. не для всех скролбаров (пример - notepad.exe) создаётся отдельное окно/контрол, то тяжело определить находится ли в момент мидлклика под курсором скроллбар или же нет.
2. активировать неактивные окна - мне не нравится, я вот ради этой фичи себе даже держу постоянно запущенным скрипт для прокрутки неактивных окон под курсором без их активации. Но отправлять Shift+ЛКМ в неактивные окна у меня пока не получилось и я не уверен, что это вообще возможно: ControlSend не позволяет отправлять клики, соответственно надо делать 3 действия скопом: controlsend {shiftdown}; controlclick; controlsend {shiftup}, но тут тоже проблема: надо знать какому окну/контролу их отправлять.
Я пытался прослушать WinSpy'ем какие же сообщения, куда и с какими аргументами отправляются при shift+ЛКМ по скроллу, но пока никаких положительных результатов это не дало.

3

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy
Спасибо большое, что обратили внимание на задачу.

1. т.к. не для всех скролбаров (пример - notepad.exe) создаётся отдельное окно/контрол, то тяжело определить находится ли в момент мидлклика под курсором скроллбар или же нет.

У многих программ скроллбар сливается с окном, тот же Notepad++. Вот именно поэтому я и хотел скрипт, который не зависит от классов скроллбара, а просто реагирует на окно по exe и вручную настроенную зону, элементарно, только 30 пикселей справа и 60 снизу.

2. активировать неактивные окна - мне не нравится, я вот ради этой фичи себе даже держу постоянно запущенным скрипт для прокрутки неактивных окон под курсором без их активации.

Я решал эту проблему, посылая СКМ+Shift+ЛКМ, если известен класс скроллбара, то работает очень неплохо.

я вот ради этой фичи себе даже держу постоянно запущенным скрипт для прокрутки неактивных окон под курсором без их активации

Поделитесь пожалуйста скриптом.

4 (изменено: Alectric, 2015-03-29 21:04:13)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Поделитесь пожалуйста скриптом.

+ открыть спойлер
#SingleInstance,Force
AutoTrim,Off
CoordMode,Mouse,Screen
Menu,Tray,UseErrorLevel
SendMode,Input
SetBatchLines,-1
SetControlDelay,0
;SetFormat,float,6.0
SetKeyDelay,0
SetTitleMatchMode,2
SetWinDelay,20
SetWorkingDir,%A_ScriptDir%
StringCaseSense,Off
#MaxHotkeysPerInterval,100000000000

scrollspeedup=1


; ////////// скроллинг неактивных окон ____________________________HOTKEYS_________________________
~*$WheelDown::
~*$WheelUp::
stringtrimleft,Wheel,A_ThisHotkey,3
keywait,%a_thishotkey%,L
;if (Wheell=0 or whellwork=1)
;  return
whellwork=1
if scrollspeedup=0
  scrollloop=1
else
{
  if A_TimeSincePriorHotkey<400
  {
    if (!speedup:=speedup>10 ? 0 : speedup="" ? 1 : speedup+1)
      scrollmulti++
  }
  else
  {
    scrollmulti=1
    speedup=
  }
  oldthishotkey:=a_thishotkey
  if scrollmulti>65
    scrollmulti=65
  if A_TimeSincePriorHotkey<17
    scrollloop=4
  else if A_TimeSincePriorHotkey<20
    scrollloop=3
  else if A_TimeSincePriorHotkey<30
    scrollloop=2
  else
    scrollloop=1
  scrollloop*=scrollmulti
}
scroll:=Wheel="WheelUp" ? (120*scrollloop)<<16 : (-120*scrollloop)<<16
;tooltip,%scrollmulti%`n"%speedup%"`n%scrollloop%`n%scroll%
mousegetpos,mx,my,win,ctrl
WinID:=DllCall("WindowFromPoint", "int64", mX & 0x00000000FFFFFFFF | mY<<32)
winget,id,id,A
wingetclass,wheelclass,ahk_id %win%
wingettitle,wheeltetle,ahk_id %win%
if wheeltetle contains UltraEdit-32,Notepad2
  ctrl=EditControl1
if wheelclass not contains tooltip
{
  if (win!=id and ctrl="")
  {
    winactivate,ahk_id %win%
    whellwork=0
    return
  }
  ControlFocus,%ctrl%,ahk_id %win%
  if (scrollloop!=1 or win!=id)
    sendMessage, 0x20A, %Scroll%, (my<<16)|mx,, ahk_id %Winid%
}
whellwork=0
return
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

5

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

АНК: Прокрутка окна под курсором мыши без активации окна

6 (изменено: Drugoy, 2015-03-30 18:06:05)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Esc пишет:

У многих программ скроллбар сливается с окном, тот же Notepad++. Вот именно поэтому я и хотел скрипт, который не зависит от классов скроллбара, а просто реагирует на окно по exe и вручную настроенную зону, элементарно, только 30 пикселей справа и 60 снизу.

Так скрипт что я пока сделал - именно так и работает. Если у скроллбара нет своего собственного класса - он есть у текстового поля. Со скриптом выше - надо просто запускать 'Window Spy' и наводить на скроллбар и использовать тот класс, что он показывает, не боясь, что этот класс принадлежит ещё кому-то.

Esc пишет:

Я решал эту проблему, посылая СКМ+Shift+ЛКМ, если известен класс скроллбара, то работает очень неплохо.

Я не понимаю как это должно решать проблему: если отправлять их через send - send не работает с неактивными окнами. Если через ControlSend/Click, то вот я и говорю, что у меня пока не получилось.

Esc пишет:

Поделитесь пожалуйста скриптом.

Здесь лежит скрипт но я чего-то его забываю обновить уже давно, он не совсем актуальный, лучше пока скриптом YMP попользоваться, а на днях я либо обновлю свой (либо сначала его чуть доделаю, чтобы не проигрывал скрипту YMP из-за корректной работы с hh.exe (виндовая читалка .chm файлов)). Он будет чуть более функциональный (скролл над таббаром должен переключать вкладки).

7

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Alectric, YMP
Спасибо.

Drugoy
Прошу прощения за задержку, да, работает так, как нужно, сначала не понял, видимо мешали какие-то твики, спасибо большое. Но почему-то не могу добавить Notepad++, вот так правильно?

{"exe": "notepad++.exe", "ctrl": "Scintilla2", "sbvlo": 100, "sbvro": 100, "sbhto": 100, "sbhbo": 100}

8 (изменено: Drugoy, 2015-04-27 23:45:52)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Esc
Ну, значения отступов вы видимо от балды взяли
Нет смысла задавать sbvlo равным sbvro, а также sbhto равным sbhbo, ведь тогда разница между ними равна 0, а значит и ширина вертикального/высота горизонтального скроллбара скриптом будет восприниматься равной нулю (в вашем случае на расстоянии в 100 пикселей от правой и нижней границ контрола).
А вот почему Scintilla2?
у меня вот такое работает:

{"exe": "notepad++.exe", "ctrl": "Scintilla1", "sbvlo": 20, "sbvro": 3, "sbhto": 60, "sbhbo": 43}

9

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy
Спасибо, пытался просто проверить и подумал эти значения немного о другом, теперь понял. А класс просто у меня другая программа определяет по своему как-то. )

А зачем использовать classNN, а не для всего окна по exe? Мне кажется есть небольшие проблемы, когда уводишь мышь за правую границу он не сразу определяет класс, нужно курсор отвести влево и обратно.

10 (изменено: yalanne, 2015-04-30 14:15:01)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Можно отслеживать полосу прокрутки через Accessibility. Вот что у меня получилось:

~Mbutton::
if Getscroll()
sendinput +{Lbutton}
return

Getscroll(){
Role := Acc_ObjectFromPoint(Child).accRole(Child)
if (Role = 39) or (Role = 43)
return 1
return 0
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
    static h
   (!h && DllCall("LoadLibrary", Str, "oleacc", Ptr))
    If    DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
    Return    ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Проверял в notepad, notepad++. А в проводнике почему то не хочет. Но если в начало добавить строку

Mbutton::return

то есть отключить её в системе. при этом условии в проводнике работает.

11

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Esc пишет:

А зачем использовать classNN, а не для всего окна по exe?

У одного окна могут быть скроллбары у разных контролов. При этом контролы могут позицией быть независимы друг от друга, поэтому отступы отсчитывать для них было бы не от чего.


Esc пишет:

Мне кажется есть небольшие проблемы, когда уводишь мышь за правую границу он не сразу определяет класс, нужно курсор отвести влево и обратно.

За правую границу чего? Справа от скроллбара часто фон от основного окна (шириной, например, в 1px), а ещё правей - ещё и виндовая рамка окна (например, стекло от темы оформления Windows Aero). Они - не относятся к скролбару.
У меня вроде всегда всё ОК срабатывает, если чего - попробуйте поменять отступы.

yalanne
Ваш код очень хороший и я утащу его к себе в скрипт
Только не могли бы вы в образовательных целях ваш код разжать и подробно прокомментировать, пожалуйста? Я вот его не очень понимаю:
Как работает "Acc_ObjectFromPoint(Child).accRole(Child)"? Что за Child и откуда он взялся? Судя по тому, что он при вызове функции присутствует дважды - я правильно понимаю, что она рекурсивно вызывает себя сама же уже передавая хэндл на дочерний элемент в качестве аргумента?
К чему там "static h" и "!h", если они нигде не используются?
Безопасно ли делать LoadLibrary без последующей её выгрузки?

yalanne пишет:

Проверял в notepad, notepad++. А в проводнике почему то не хочет. Но если в начало добавить строку

А у меня работает и в проводнике (w7sp1x64, Aero).

12 (изменено: yalanne, 2015-04-30 01:32:28)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy, К сожалению я сломал винду на глухо. А установить новую пока что нет возможности.
А на смартфоне не удобно код объяснять.
Но попробую:

yalanne пишет:
+ Вот таблица role значений
ROLE_SYSTEM_TITLEBAR            = 0x00000001
ROLE_SYSTEM_MENUBAR             = 0x00000002
ROLE_SYSTEM_SCROLLBAR           = 0x00000003
ROLE_SYSTEM_GRIP                = 0x00000004
ROLE_SYSTEM_SOUND               = 0x00000005
ROLE_SYSTEM_CURSOR              = 0x00000006
ROLE_SYSTEM_CARET               = 0x00000007
ROLE_SYSTEM_ALERT               = 0x00000008
ROLE_SYSTEM_WINDOW              = 0x00000009
ROLE_SYSTEM_CLIENT              = 0x0000000A
ROLE_SYSTEM_MENUPOPUP           = 0x0000000B
ROLE_SYSTEM_MENUITEM            = 0x0000000C
ROLE_SYSTEM_TOOLTIP             = 0x0000000D
ROLE_SYSTEM_APPLICATION         = 0x0000000E
ROLE_SYSTEM_DOCUMENT            = 0x0000000F
ROLE_SYSTEM_PANE                = 0x00000010
ROLE_SYSTEM_CHART               = 0x00000011
ROLE_SYSTEM_DIALOG              = 0x00000012
ROLE_SYSTEM_BORDER              = 0x00000013
ROLE_SYSTEM_GROUPING            = 0x00000014
ROLE_SYSTEM_SEPARATOR           = 0x00000015
ROLE_SYSTEM_TOOLBAR             = 0x00000016
ROLE_SYSTEM_STATUSBAR           = 0x00000017
ROLE_SYSTEM_TABLE               = 0x00000018
ROLE_SYSTEM_COLUMNHEADER        = 0x00000019
ROLE_SYSTEM_ROWHEADER           = 0x0000001A
ROLE_SYSTEM_COLUMN              = 0x0000001B
ROLE_SYSTEM_ROW                 = 0x0000001C
ROLE_SYSTEM_CELL                = 0x0000001D
ROLE_SYSTEM_LINK                = 0x0000001E
ROLE_SYSTEM_HELPBALLOON         = 0x0000001F
ROLE_SYSTEM_CHARACTER           = 0x00000020
ROLE_SYSTEM_LIST                = 0x00000021
ROLE_SYSTEM_LISTITEM            = 0x00000022
ROLE_SYSTEM_OUTLINE             = 0x00000023
ROLE_SYSTEM_OUTLINEITEM         = 0x00000024
ROLE_SYSTEM_PAGETAB             = 0x00000025
ROLE_SYSTEM_PROPERTYPAGE        = 0x00000026
ROLE_SYSTEM_INDICATOR           = 0x00000027
ROLE_SYSTEM_GRAPHIC             = 0x00000028
ROLE_SYSTEM_STATICTEXT          = 0x00000029
ROLE_SYSTEM_TEXT                = 0x0000002A
ROLE_SYSTEM_PUSHBUTTON          = 0x0000002B
ROLE_SYSTEM_CHECKBUTTON         = 0x0000002C
ROLE_SYSTEM_RADIOBUTTON         = 0x0000002D
ROLE_SYSTEM_COMBOBOX            = 0x0000002E
ROLE_SYSTEM_DROPLIST            = 0x0000002F
ROLE_SYSTEM_PROGRESSBAR         = 0x00000030
ROLE_SYSTEM_DIAL                = 0x00000031
ROLE_SYSTEM_HOTKEYFIELD         = 0x00000032
ROLE_SYSTEM_SLIDER              = 0x00000033
ROLE_SYSTEM_SPINBUTTON          = 0x00000034
ROLE_SYSTEM_DIAGRAM             = 0x00000035
ROLE_SYSTEM_ANIMATION           = 0x00000036
ROLE_SYSTEM_EQUATION            = 0x00000037
ROLE_SYSTEM_BUTTONDROPDOWN      = 0x00000038
ROLE_SYSTEM_BUTTONMENU          = 0x00000039
ROLE_SYSTEM_BUTTONDROPDOWNGRID  = 0x0000003A
ROLE_SYSTEM_WHITESPACE          = 0x0000003B
ROLE_SYSTEM_PAGETABLIST         = 0x0000003C
ROLE_SYSTEM_CLOCK               = 0x0000003D

Вот их описание

Child Это имя переменной ее имя можно задать самому. С помощью Acc_ObjectFromPoint в эту переменную вносится ид элемента который находится под курсором. А затем с помощью accRole проверяется роль этого элемента(что он может делать)
Например У самого ползунка прокрутки эта роль равна 39 иначе называемая ROLE_SYSTEM_INDICATOR (0x00000027)
а у пустой области прокрутки 43 ROLE_SYSTEM_PUSHBUTTON (0x0000002B)
То есть если под курсором элемент с ролью 39 или 43 значит это прокрутка.

static ... можно и не использовать, а просто загружать библиотеку. а насчет выгрузки не знаю.

13 (изменено: Esc, 2015-04-30 01:30:31)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy пишет:

У одного окна могут быть скроллбары у разных контролов. При этом контролы могут позицией быть независимы друг от друга, поэтому отступы отсчитывать для них было бы не от чего.

Ясно, спасибо.

Drugoy пишет:

За правую границу чего? Справа от скроллбара часто фон от основного окна (шириной, например, в 1px), а ещё правей - ещё и виндовая рамка окна (например, стекло от темы оформления Windows Aero). Они - не относятся к скролбару.
У меня вроде всегда всё ОК срабатывает, если чего - попробуйте поменять отступы.

За правую границу окна, т.е. если курсор прилетает справа и сразу на скроллбар, но я уже выяснил, что проблема не в вашем коде, сторонний софт так же работает.

А 0.3 версия не предполагает добавления программ и отступов или я чего-то не понял?

14 (изменено: Drugoy, 2015-04-30 10:58:32)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Esc пишет:

За правую границу окна

Правая граница окна != скроллбар

Esc пишет:

А 0.3 версия не предполагает добавления программ и отступов или я чего-то не понял?

Я подумал, что это теперь не нужно, после того как уважаемый тов. yalanne предложил более надёжный способ детектирования скроллбара под курсором. Я потестировал его вчера и вроде всё ок было со всеми окнами кроме Firefox (но там своя настройка же есть, так что я подумал, что это не страшно).
Сейчас вот заметил, что этот метод не работает с hh.exe (просмотрщик *.chm файлов) и mspaint.exe, так что возможно придётся использовать комбинированный подход и применять тот или иной метод в зависимости от окна.


Если ещё удастся как-то отправлять Shift+Click в неактивное окно без его активации - это будет вообще бомба.

15

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy пишет:

не работает  mspaint.exe

Я немного код изменил теперь работает у меня в паинте и в проводнике.

16

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

yalanne а ваш код совместим со всеми версиями ahk (x32_ansi, x32_unicode, x64)? Или только с какими-то конкретными? А то я вижу там "Int64" у вас и т.к. ничего в этом не понимаю - меня это настораживает.

17 (изменено: yalanne, 2015-04-30 18:18:35)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Drugoy, Скорей всего совместимо. Я не писал функцию Acc_ObjectFromPoint, она вырезана вот тут. Я и не разбирался что внутри  этой функции происходит.
А строку

(!h && DllCall("LoadLibrary", Str, "oleacc", Ptr))

Я позаимствовал у teadrinker. в этом сообщении

Хм я нашел более простой вариант:

~Mbutton::
if ( Acc_ObjectFromPoint().accRole(0) ) = 3
sendinput +{Lbutton}
return

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
    static h
   (!h && DllCall("LoadLibrary", Str, "oleacc", Ptr))
    If    DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
    Return    ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

В таком виде соответствует названию

Acc_ObjectFromPoint().accRole(0)

3 это ROLE_SYSTEM_SCROLLBAR
В первом варианте через Child проверялась роль у дочерних элементов линии прокрутки.Дочерних элементов у линии прокрутки всего 5

+ открыть спойлер

http://i.imgur.com/dnzVumf.png

Esc,

Esc пишет:

назначать любые другие функции на элементы интерфейса, например, левый клик по статусбару Notepad++, как выделено зелёным на изображении, возвращает вверх документа, посылая СКМ=Shift+HOME, а правый клик, в самый низ, посылая СКМ=Shift+END.

Вот так подойдет:

~Lbutton::
if ( Acc_ObjectFromPoint().accRole(0) ) = 23 and winactive("ahk_exe notepad++.exe")
send ^{home}
return

~Rbutton::
if ( Acc_ObjectFromPoint().accRole(0) ) = 23 and winactive("ahk_exe notepad++.exe")
send ^{end}
return


Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
    static h
   (!h && DllCall("LoadLibrary", Str, "oleacc", Ptr))
    If    DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
    Return    ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

только там надо не шифт а контрол нажимать что бы переместится в начало или конец.

18

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

yalanne
Увы, но это не исправило проблем с hh.exe и mspaint.exe.
Есть подозрение, что скроллбары в них или задизэйблены, или скрыты, или к ним применён ещё какой-то стиль/ex-стиль, что они "прозрачны" для AccessibleObjectFromPoint, но непрозрачны для клика.

19 (изменено: Drugoy, 2015-05-10 03:28:03)

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Неверно выразился в последнем сообщении - hh.exe и mspaint.exe подпадают под две разных категории окон:
- в mspaint.exe Acc_ObjectFromPoint().accRole(0) "видит" скроллбары и определяет их роль верно (как 3, т.е. как скроллбар);
- в hh.exe Acc_ObjectFromPoint().accRole(0) "не видит" скроллбары и роль определяется не как 3.

При этом с обеими категориями окон есть беда с кликами:
- если использовать ControlClick в неактивное окно по позиции курсора в нём, то клик проходит ПОД скроллбар: в случае с mspaint.exe - если под скроллбаром скрыт кусок полотна, то клик отсылается на полотно (если под скроллом полотна нет, то клик успешно проходит по скроллбару). Аналогично и с hh.exe: клик над скроллбару в левой навигационной части проходит не в скроллбар, а в список под ним (подсвечивает элемент из списка).
- если использовать Send то ему требуется активация окна, что убого.

Сейчас я обновил свой скрипт до версии 0.4: в скрипте используется комбинированный подход: при работе с неактивными окнами там где можно используется подход ControlSend + ControlClick (самый оптимальный), там где это [по крайней мере пока] невозможно (пример: mspaint.exe) - используется подход Send +{LButton} с временной активацией окна. Во всех остальных случаях отправляется просто Send {MButton}.

В версии 0.5 планирую вернуть преконфигурируемые правила, чтобы можно было в 3 случае дать скрипту указаний при каких условиях следует действовать как в случае 2.

А ещё если получится ещё успешно пошаманить с ControlClick, то возможно, что в версии 0.6 удастся целиком избежать принудительной активации окон, даже для сложных окон вроде mspaint.exe.

А ещё можно побольше поиграться с Acc библиотекой и я не уверен, но возможно, что получится избежать составления преконфигурируемых правил по отступам, а составлять их по Acc-навигации: проблема в том, что Acc_ObjectFromPoint().accRole(0) в окнах типа hh.exe определяет у скроллбаров роль не как 3, но есть подозрение, что если пошарить по родительским/дочерним объектам в Acc-дереве объектов, то возможно у кого-то из них есть роль 3 и нам этого знания будет достаточно.

20

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

В hh.exe, Aсс не видит полосу прокрутки, по сути для него полоса и рабочая область одно и тоже:

+ курсор на полосе

(Что бы увеличить клик по картинке)http://i.imgur.com/7zqAGwv.jpg

+ курсор на рабочей области

(Что бы увеличить клик по картинке)http://i.imgur.com/HPur06x.jpg

Но hh.exe работает на движке internet explorer, у него аналогично:

+ курсор на полосе

(Что бы увеличить клик по картинке)http://i.imgur.com/cXoxxqi.jpg

+ курсор на рабочей области

(Что бы увеличить клик по картинке)http://i.imgur.com/VGwJ4JJ.jpg

Надо копать в строну ie полосы прокрутки и ее управления через ahk.

p.s вот ahkspy

21

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Это не Acc.
Acc показывает более полную картину:

+ более полная картина.пнг

https://i.imgur.com/wjHluYI.png

Внутри выделенного элемента нет полос прокрутки, но если перейти к его родителю - то после него идут полосы прокрутки, и ещё при 2 переходах на уровень вверх тоже есть полосы прокрутки.
1 из этих 3 групп, вероятно, и отвечает за нужный нам скроллбар.

22

Re: AHK: Мгновенный переход по скроллбару средней кнопкой мыши, как в FF

Хм интересно. Я вот разобрался как на подуровни смотреть. вот пример:

+ код
Lwin::
MouseGetPos, , , hWnd
client := Acc_ObjectFromWindow(hWnd)
popup_menu := Acc_GetChild(client, "3,1,1")

MsgBox % popup_menu.AccName(1)


;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Acc_Init()
{
    Static    h
    If Not    h
        h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}

Acc_ObjectFromWindow(hWnd, idObject = 0)
{
    Acc_Init()
    If    DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
    Return    ComObjEnwrap(9,pacc,1)
}

Acc_Children(Acc) {
    if ComObjType(Acc,"Name") != "IAccessible"
        ErrorLevel := "Invalid IAccessible Object"
    else {
        Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
        if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
            Loop %cChildren%
                i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
            return Children.MaxIndex()?Children:
        } else
            ErrorLevel := "AccessibleChildren DllCall Failed"
    }
    if Acc_Error()
        throw Exception(ErrorLevel,-1)
}

Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
    try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

Acc_Error(p="") {
    static setting:=0
    return p=""?setting:setting:=p
}

Acc_GetChild(Acc, path="") {
    Loop Parse, path, csv
        Acc := Acc_Children(Acc)[A_LoopField]
    return Acc
}

;----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

В данном примере по нажатию lwin скрипт смотрит на первый элемент первого меню
(в блокноте это - Файл > Создать CTRL+N; В hh.exe это - Файл > Печать...)

В строке

Acc_GetChild(client, "3,1,1")

3,1,1 это путь к меню:

+ открыть спойлер

http://i.imgur.com/lZAJMax.png

А уже при вызове самого msgbox'а

MsgBox % popup_menu.AccName(1)

  1 значит первый элемент меню.