Как центрировать любое окно на экране с помощью AutoHotKey

В Windows окна могут появляться в случайных местах. Это раздражает и замедляет работу. AutoHotKey (AHK) умеет читать свойства активного окна и экрана и управлять положением окна. В этом руководстве вы:
- увидите минимальный рабочий скрипт на AHK для центрирования активного окна;
- поймёте, как вычисляются координаты и зачем нужны специальные проверки;
- получите расширенные варианты для нескольких мониторов и исключений;
- получите чек-листы, тесты и рекомендации по совместимости.
Что нам нужно сделать в общем виде
Короткая методология:
- Получить идентификатор (заголовок) активного окна.
- Узнать ширину и высоту этого окна.
- Узнать ширину и высоту видимой области экрана (учитывая панель задач).
- Вычислить координаты, позволяющие разместить окно по центру.
- Выполнить команду перемещения окна (WinMove) на вычисленные координаты.
- Привязать всё это к горячей клавише, чтобы запускать «по требованию».
Важно: реализуем действие по запросу, а не автозапуск для всех окон, чтобы не мешать полноэкранным приложениям и играм.
Требования и совместимость
- Скрипты ниже написаны для AutoHotKey версии 1 (v1.x). Если вы используете AHK v2, синтаксис отличается — см. раздел Совместимость.
- Установите текущую стабильную версию AutoHotKey (не v2 beta, не устаревшую 1.0).
- Для редактирования используйте простой текстовый редактор (Notepad, VS Code, Notepad++). Не сохраняйте в RTF или DOCX.
Шаг 1 — создаём файл скрипта и горячую клавишу
- Установите AutoHotKey.
- В Проводнике щёлкните правой кнопкой на папке и выберите New > AutoHotKey Script.
- Переименуйте файл, правой кнопкой — Edit Script.
- Добавьте горячую клавишу. В AHK:
- = Shift
- ^ = Ctrl
- ! = Alt
Пример: Ctrl+Y — это ^y::
Минимальная структура функции
#NoEnv ; Рекомендуется для совместимости и производительности
SendMode Input ; Быстрый и надёжный режим отправки ввода
SetWorkingDir %A_ScriptDir% ; Текущая директория скрипта
^y::
; тут будет наш код
returnКомментарий (строки, начинающиеся с ;) не выполняются — они только для читателя.
Шаг 2 — получаем данные активного окна
Нам нужны заголовок окна и его размеры. Используем WinGetTitle и WinGetPos:
WinGetTitle, ActiveWindowTitle, A
WinGetPos,,, Width, Height, %ActiveWindowTitle%Пояснение:
- WinGetTitle получает заголовок активного окна и записывает его в переменную ActiveWindowTitle.
- WinGetPos возвращает левый, верхний, ширину и высоту. Мы используем только Width и Height.
- A указывает на активное (текущее) окно.
Шаг 3 — откуда берём размеры экрана
AutoHotKey уже содержит переменные с размерами видимой области основного монитора:
- A_ScreenWidth — ширина видимой области экрана в пикселях.
- A_ScreenHeight — высота видимой области экрана в пикселях.
Эти переменные учитывают рабочую область (не всегда — в редких конфигурациях с панелями или сторонними тулбарами может потребоваться SysGet).
Шаг 4 — вычисляем целевые координаты
Логика простая: чтобы центрировать окно нужно от центра экрана отнять половину ширины (и высоты) окна.
TargetX := (A_ScreenWidth / 2) - (Width / 2)
TargetY := (A_ScreenHeight / 2) - (Height / 2)Здесь “:=” означает вычисляемое присваивание (числовые выражения).
Шаг 5 — перемещаем окно
Команда WinMove перемещает/изменяет размер окна. Мы передаём ей заголовок и координаты:
WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY%Полная последовательность внутри горячей клавиши выглядит так:
^y::
WinGetTitle, ActiveWindowTitle, A
WinGetPos,,, Width, Height, %ActiveWindowTitle%
TargetX := (A_ScreenWidth/2) - (Width/2)
TargetY := (A_ScreenHeight/2) - (Height/2)
WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY%
returnФинальный базовый скрипт
Скопируйте, сохраните как .ahk и дважды щёлкните файл, чтобы запустить скрипт.
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
^y::
WinGetTitle, ActiveWindowTitle, A ; Получаем заголовок активного окна
WinGetPos,,, Width, Height, %ActiveWindowTitle% ; Получаем размеры окна
TargetX := (A_ScreenWidth/2) - (Width/2) ; Горизонтальная цель
TargetY := (A_ScreenHeight/2) - (Height/2) ; Вертикальная цель
WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY% ; Перемещаем окно
returnВарианты и расширения (ценны на практике)
Ниже — набор полезных улучшений и альтернативных подходов. Выберите то, что подходит вашей рабочей среде.
1) Центрировать внутри рабочей области (учитывать панель задач)
Если панель задач расположена не внизу или у вас несколько панелей, можно получить рабочую область через SysGet:
SysGet, WorkArea, MonitorWorkArea, 1 ; рабочая область первого монитора
WorkWidth := WorkAreaRight - WorkAreaLeft
WorkHeight := WorkAreaBottom - WorkAreaTop
TargetX := (WorkWidth/2) - (Width/2) + WorkAreaLeft
TargetY := (WorkHeight/2) - (Height/2) + WorkAreaTop2) Исключать полноэкранные приложения и игры
Проверим, не является ли окно полноэкранным или свернутым:
if (Width >= A_ScreenWidth && Height >= A_ScreenHeight)
{
; Возможно полноэкранный режим — не трогаем окно
return
}
if WinActive("ahk_class Shell_TrayWnd")
{
; Пример: исключение панели задач
}3) Исключать определённые заголовки или классы окон
Можно пропускать окна, если их заголовок или класс содержат текст:
if ActiveWindowTitle ~= "(?i)Spotify|YouTube|OBS" ; regex-исключение по заголовку
return
WinGetClass, winClass, %ActiveWindowTitle%
if (winClass = "Shell_TrayWnd") ; исключить панель задач
return4) Центрировать на мониторе, где находится активное окно
Если у вас несколько мониторов и хотите центрировать окно именно на том мониторе, где оно сейчас находится, используйте SysGet и вычисляйте монитор по положению окна:
; Получаем позицию и определяем монитор
WinGetPos, X, Y, W, H, %ActiveWindowTitle%
SysGet, MonitorCount, MonitorCount
Loop %MonitorCount%
{
SysGet, m, Monitor, %A_Index%
if (X >= mLeft && X <= mRight)
{
MonLeft := mLeft
MonTop := mTop
MonRight := mRight
MonBottom := mBottom
break
}
}
MonWidth := MonRight - MonLeft
MonHeight := MonBottom - MonTop
TargetX := (MonWidth/2)-(W/2)+MonLeft
TargetY := (MonHeight/2)-(H/2)+MonTop5) Переключение между мониторами (toggle)
Короткий вариант «перебрасывания» окна между мониторами с помощью переключателя PositionToggle. Этот код простой и понятный, но не самый «элегантный».
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
PositionToggle := 1
^y::
WinGetTitle, ActiveWindowTitle, A
WinGetPos,,, Width, Height, %ActiveWindowTitle%
if (PositionToggle = 1)
{
TargetX := (A_ScreenWidth/2) - (Width/2)
TargetY := (A_ScreenHeight/2) - (Height/2)
PositionToggle := 2
}
else
{
SysGet, Mon2, Monitor, 2
Mon2Width := Mon2Right - Mon2Left
Mon2Height := Mon2Bottom - Mon2Top
TargetX := (Mon2Width/2) - (Width/2) + A_ScreenWidth
TargetY := (Mon2Height/2) - (Height/2) + Mon2Top
PositionToggle := 1
}
WinMove, %ActiveWindowTitle%,, %TargetX%, %TargetY%
returnОбратите внимание: в некоторых конфигурациях мониторы могут быть расположены не строго «в ряд» по горизонтали. Тогда нужно корректнее вычислять смещение.
Когда решение не сработает или даст неожиданный результат
- Окно без заголовка или с динамическим заголовком — WinGetTitle может вернуть пустую строку; лучше работать по HWND (идентификатору окна) при необходимости.
- Окна с нестандартной рамкой, оконные менеджеры из сторонних программ или эмуляторы — могут вести себя иначе.
- Полноэкранные приложения часто имеют размеры, равные экрану; логика проверки поможет не трогать такие окна.
- Если у вас «виртуальные рабочие столы» Windows, поведение может отличаться.
Отладка и проверка
- Вставьте MsgBox после вычисления TargetX/TargetY, чтобы увидеть координаты:
MsgBox, TargetX=%TargetX%`nTargetY=%TargetY%- Если WinMove не работает, попробуйте использовать HWND вместо заголовка:
WinGet, hwnd, ID, A
WinMove, ahk_id %hwnd%,, %TargetX%, %TargetY%- Если окно закрывается или сворачивается при попытке перемещения — проверьте плагины/надстройки приложения.
Безопасность и права
- Скрипт не отправляет нажатия клавиш и не управляет вводом в приложениях по умолчанию — он только читает статус окон и перемещает их.
- Не давайте запускаться неизвестным AHK-скриптам — в них могут быть команды, отправляющие ввод или выполняющие системные действия.
Совместимость и миграция на AHK v2
Ключевая заметка: синтаксис AHK v2 отличается. Приведённые выше скрипты написаны для AHK v1.x. Если вы используете v2, нужно адаптировать синтаксис (например, операторы := и вызовы SysGet/WinGet выглядят иначе). В официальной документации AHK v2 есть раздел с примерами миграции.
Роль‑ориентированные чек‑листы
Для пользователя:
- Установить AutoHotKey (стабильную версию).
- Создать .ahk файл и вставить базовый скрипт.
- Запустить скрипт и протестировать Ctrl+Y на нескольких окнах.
Для администратора (корпоративное окружение):
- Проверить политику безопасности относительно автозапуска скриптов.
- При необходимости подписать/проверить скрипт на предмет нежелательных команд.
- Распространить шаблон скрипта через каталог скриптов и инструкции.
Для разработчика/модератора AHK:
- Добавить логирование ошибок и MsgBox для диагностики.
- Подготовить версию, работающую с HWND, чтобы избежать зависимостей от заголовков.
- Добавить конфигурационный файл для исключений.
Критерии приёмки
- Скрипт переносит активное окно в центр основного монитора при нажатии заданной горячей клавиши.
- Скрипт пропускает полноэкранные окна и окна из списка исключений.
- Скрипт корректно обрабатывает окна с нестандартными размерами (проверено на трёх приложениях).
Тесты и шаблоны тестовых случаев
- Обычное приложение (Блокнот): окно среднего размера — результат: центр экрана.
- Маленькое окно (диалог): центр по центру экрана.
- Полноэкранный плеер — скрипт ничего не делает.
- Окно без заголовка — обработать через HWND.
- Два монитора: центрирование на активном мониторе и переключение при toggle.
Частые проблемы и исправления
Проблема: ничего не происходит при нажатии горячей клавиши.
- Решение: проверьте, запущен ли .ahk файл (значок в трее). Убедитесь, что вы не переназначили клавишу системой.
Проблема: окно перемещается, но остаётся обрезанным или частично скрытым.
- Решение: используйте WinRestore перед WinMove, чтобы восстановить нормальный размер окна.
Проблема: некорректное поведение на нескольких мониторах.
- Решение: используйте SysGet и вычисляйте координаты относительно конкретного монитора.
Мини‑методология изменений и расширений
- Добавьте журнал действий для отладки (файл логов).
- Реализуйте конфигурацию исключений в INI/JSON.
- Переведите логику на работу с HWND для надёжности.
- Добавьте UI для настройки горячих клавиш (опционально).
Краткий глоссарий
- AutoHotKey (AHK): простая скриптовая система для автоматизации действий в Windows.
- WinMove: команда AHK для перемещения/изменения размера окна.
- WinGetPos: команда AHK, возвращающая позицию и размеры окна.
- HWND: уникальный идентификатор окна в системе (альтернатива заголовку).
Примеры альтернативных подходов
- Использовать встроенные в DE/WM менеджеры окон (редко применимо в Windows).
- Использовать сторонние утилиты типа DisplayFusion для более сложной логики управления окнами.
- Писать небольшую утилиту на .NET, которая использует WinAPI для управления окнами (больше контроля, сложнее).
Краткая сводка и рекомендации
- Базовый скрипт работает быстро и надёжно для большинства приложений.
- Для продвинутых сценариев используйте SysGet, HWND и логику проверки мониторов.
- Не забудьте исключать полноэкранные приложения и окна без заголовков.
Если хотите, могу адаптировать скрипт под вашу конкретную конфигурацию мониторов или добавить конфигурационный файл для списка исключений.
Часто задаваемые вопросы
Q: Сработает ли скрипт с AHK v2?
A: Нет — синтаксис отличается. Если нужен вариант для v2, подготовлю перевод.
Q: Можно ли сделать, чтобы скрипт автоматически центрировал каждое новое окно?
A: Да, но автоматическое применение может мешать полноэкранным приложениям или всплывающим диалогам. Рекомендуется запускать по горячей клавише для контроля.
Q: Что делать, если окно не имеет заголовка?
A: В таких случаях используйте WinGet с ID (HWND) и работайте с ahk_id %hwnd%.
Похожие материалы
Повторяющиеся встречи в Zoom — планирование и управление
Spatial Audio на AirPods Pro — как включить
Исправить ошибку 0x8007007f при обновлении до Windows 11
Создать Bitmoji для Snapchat — пошагово
Minecraft на Nintendo Switch через BedrockConnect