Панорамирование/скроллинг/рука в Office
🌰 Прокрутка офисных приложений нажатым колесом мыши, как принято в CAD
Введение
При работе в дизайнерских программах, при просмотре карт или PDF-документов Вы можете передвигать чертёж/карту/документ при зажатой кнопке мыши. В CADах это обычно средняя кнопка, в PDF — левая, в 2gis — левая или правая.
Обычно за включение этого режима отвечает кнопка с иконкой руки (panning hand), вроде такой:
Однако в офисных приложениях нажатие на колесо вызывает режим прокрутки, когда документ начинает ползти в сторону перемещения мыши, что не всегда удобно. Попробуем вернуть «нормальное» поведение колеса в приложениях Microsoft Office.
Word
С word-ом проще всего. Функция «рука» встроена в ворд, она называется «Режим панорамирования»:
В этом режиме удобно редактировать графические элементы в word при большом увеличении. Если функция панорамирования в ворде нужна Вам периодически, то можно вынести её на панель быстрого доступа. А чтобы назначить эту функцию на среднюю кнопку мыши, используем следующий скрипт AHK:
#HotIf WinActive("ahk_class OpusApp") ; Когда открыт Word... MButton:: WordPan() WordPan(*) { if !(wd := GetWord()) ; Если ворд не берётся, return ; то выход try { WD.ActiveWindow.View.Panning := True ; рука вкл Click "down" ; зажали ЛКМ KeyWait "MButton" ; ждём отпускания колеса Click "up" ; отжали лкм WD.ActiveWindow.View.Panning := False ; рука выкл } } GetWord(Force:=0) { static wd := "" return GetComApp(&wd, force, "Word.Application", "Word") }
Скачать все скрипты из статьи
В скрипте используется функция GetComApp.
Visio
В visio тоже несложно использовать «руку», но она активируется странным сочетанием Ctrl+Shift+Правая кнопка мыши. Поменяем на среднюю кнопку:
#HotIf WinActive("ahk_class VISIOA") MButton:: { SendInput "{Ctrl down}{Shift down}" Sleep 20 Send "{Rbutton down}" KeyWait "MButton" Send "{Rbutton up}" SendInput "{Ctrl up}{Shift up}" }
Для большего сходства с автокадом включите опцию «Панорамирование с помощью IntelliMouse» в настройках visio, чтобы поворот колеса менял увеличение:
Excel
А теперь начинается самое интересное. В экселе режима руки нет, хотя он был бы очень кстати для прокрутки широких таблиц влево-вправо. С другой стороны, в Excel имеется поддержка клавиши ScrollLock. Когда Scroll Lock активен (индикатор на клавиатуре горит), клавиши управления курсором ↑↓←→ не передвигают выделение, а осуществляют прокрутку листа, при этом выделение не сбивается. Попробуйте сами. Excel — одна из немногих программ, где работает Scroll Lock.
А ведь это решение! При зажатии колеса мыши мы будем активировать режим Scroll Lock, а при отжатии — снимать его. Останется периодически опрашивать положение мыши, и, если она передвинулась, сдвигать лист в соответствующую сторону клавишами ↑↓←→. Скрипт для Excel:
#HotIf WinActive("ahk_class XLMAIN") ; Excel MButton:: ScrollLockPan ; Панорамирование СкроллЛоком ScrollLockPan() { static XT := 30 ; Порог обнаружения движения мыши (пикселей) static YT := 30 static MPOLLING := 50 ; Частота опроса мыши, мс mx0:=my0:=mx1:=my1 := 0 ; Начальные и конечные координаты мыши MouseGetPos &mx0, &my0 SetScrollLockState 1 ; Скролл лок ВКЛ Loop { Sleep MPOLLING if !GetKeyState("MButton", "P") { ; Если колесо отпущено, SetScrollLockState 0 ; отключаем скролл лок return ; и выходим } MouseGetPos &mx1, &my1 dx := mx1-mx0 dy := my1-my0 dx := round(dx/XT*1) ; Здесь значения можно подобрать по вкусу dy := round(dy/YT*4) ; Я умножил на 4, чтобы по вертикали двигалось поживее ;tooltip "dx " dx " dy " dy if dX > 0 { Send "{Left " dX "}" ; Нажимаем «влево» нужное число раз (в dX — число) } else if dX < 0 { Send "{Right " abs(dX) "}" } if dY > 0 { Send "{Up " dY "}" } else if dY < 0 { Send "{Down " abs(dY) "}" } mx0 := mx1 my0 := my1 } }
Скачать все скрипты из статьи
Разумеется, перемещение листа будет не плавным, как в Word или Visio, а скачками: целыми колонками и строчками сразу. Также сдвиг не будет численно соответствовать количеству пикселей, на которые переместилась мышь. Да это и невозможно, ведь в общем случае все колонки имеют разную ширину, а строки отличаются по высоте.
Отрегулируйте параметры задержки (MPOLLING
), порогов (XT
, YT
) и множители в формулах определения dX/dY так, как Вам будет удобнее.
PowerPoint
В PowerPoint тоже нет функции «рука». Действуем аналогично: опрашиваем положение мыши, вычисляем сдвиг, но вместо ScrollLock вызываем функцию SmallScroll, передавая в неё величину сдвигов:
#HotIf WinActive("ahk_class PPTFrameClass") ; PowerPoint 2010+ MButton:: ComPanP(GetPoint()) #HotIf WinActive("ahk_class PP12FrameClass") ; PowerPoint 2007 MButton:: ComPanP(GetPoint()) ComPanP(App) { ; Панорамирование для PowerPoint static XT := 20 ; Это для панорамирования колёсиком static YT := 20 static MPOLLING := 50 mx0:=mx1:=my0:=my1:=0 MouseGetPos &mx0, &my0 if !GetKeyState("MButton", "P") return loop { sleep MPOLLING MouseGetPos &mx1, &my1 dx := mx1-mx0 dy := my1-my0 if !GetKeyState("MButton", "P") return dx := round(dx/XT*2) dy := round(dy/YT*4) ;tooltip "dx " dx " dy " dy if (dX||dY) { try { App.ActiveWindow.SmallScroll -dY, dY, -dX, dX ; Отрицательные значения не воспринимает } catch { Tooltip "Отпустите кнопку и начните ещё раз!" KeyWait "MButton" Sleep 50 SendLevel 1 SendEvent "^+{MButton}" SendLevel 0 Tooltip return } mx0 := mx1 my0 := my1 } } } GetPoint(Force:=0) { static pp := "" return GetComApp(&pp, force, "PowerPoint.Application", "PowerPoint", "PP_") }
Скачать все скрипты из статьи
Аналогично, параметры настраиваем по вкусу.
В powerpoint есть неприятная особенность: слайд переключатся на следующий, если прокрутить в самый низ или верх слайда. См. Как отключить переход к следующему слайду колёсиком в PowerPoint.
Другие программы
Использованный приём с регулярным опросом мыши можно распространить и на другие приложения, где Вам хотелось бы добавить панорамирование. Вопрос в том, как сообщать программе, что мы хотим сдвинуть её окно. Один из способов сделать это — послать окну программы сообщение о прокрутке:
; 0x114 — горизонтальная прокрутка ; 0x115 — вертикальная ; | 1/0 — направление ; | | id элемента управления ; | | | HWND окна ; | | | | ; ↓ ↓ ↓ ↓ PostMessage 0x114, 1, 0, ctrl, win
Узнать id элемента управления можно задав ClassNN, полученный с помощью утилиты Window spy из комплекта программы AutoHotKey:
Вот пример скрипта для WordPad:
#HotIf WinActive("ahk_class WordPadClass") ; WordPad MButton::PanWordPad() PanWordPad(*) { static XT := 30 static YT := 30 static MOUSEPOLLING := 50 mx0:=my0:=mx1:=my1:=0 win := WinGetID("A") ; получим id активного окна ctrl := ControlGetHWND("RICHEDIT50W1", win) ; получим id основного элемента управления, который двигать будем MouseGetPos &mx0, &my0 Loop { Sleep MOUSEPOLLING if !GetKeyState("MButton", "P") { return } MouseGetPos &mx1, &my1 dx := mx1-mx0 dy := my1-my0 dx := -round(dx/XT*3) dy := -round(dy/YT*1) ;tooltip "dx " dx " dy " dy if (dX||dY) { if dX > 0 { loop dX PostMessage 0x114, 1, 0, ctrl, win ; вправо } else if dX < 0 { loop abs(dX) PostMessage 0x114, 0, 0, ctrl, win ; влево } if dY > 0 { loop dY PostMessage 0x115, 1, 0, ctrl, win ; вниз } else if dY < 0 { loop abs(dY) PostMessage 0x115, 0, 0, ctrl, win ; вверх } } mx0 := mx1 my0 := my1 } }