1

Тема: AutoHotkey: Управление окнами с помощью горячих клавиш

Выкладываю фрагмент постоянно загруженного у меня скрипта, который помогает управлять разными окнами с клавиатуры: закрывать (разными способами), закрывать без сохранения (т.е. автоматически подтверждать, что сохранять изменения не надо), сворачивать/разворачивать, разворачивать(максимизировать)/восстанавливать, назначать/снимать "поверх всех". Сюда же я добавил скрипт из справки к AutoHotkey, позволяющий перетаскивать окно за любую его часть (EWD). Пользуюсь всем этим уже пару лет, и если оказываюсь где-то, где я еще не успел загрузить свой базовый скрипт, то некоторое время (недолгое, к счастью) в растерянности пытаюсь понять: "что это за странные глюки винды ". В общем, удобные фишки. Разумеется, изменить горячие клавиши или прочую мелочь под свои желания не составит у вас труда. Найдете способы улучшить - поделитесь, буду благодарен.

;*****************************************************************************
; AutoHotkey Version:   1.0.41.01+
; Автор:                Androgen Belkin
; Имя скрипта:          ControlsWinows.ahk (v.1.3)
;*****************************************************************************
; Управление окнами с помощью горячих клавиш.
;*****************************************************************************
#NoEnv         ; запрещаем имена переменных как у переменных окружения (повышаем производительность скрипта)
;~ #NoTrayIcon    ; не отображать иконку скрипта в трее
SendMode Input ; новый режим высылки без задержки и повышенной надежности
SetTitleMatchMode, 2 ; сравнивать с любой частью заголовка окна

; ========== ЗАКРЫТИЕ ПО ESCAPE (ТОЛЬКО УКАЗАННЫХ ОКОН) ===============
~ESC:: ; Escape - закрытие некоторых окон (справка, консоль, проводник, блокнот и др.)
;-----------------------------------------------------------------------------
    If EWD_Work = 1 ; если сейчас работает перемещение окна с помощью мыши (EWD), то...
        Return ; закончить обработку горячей клавиши (т.к. Escape назначена в EWD для отмены перемещения окна)
    WinGetActiveTitle, Win_To_Close_Title ; сохранить заголовок в переменной
    WinGetClass, Win_To_Close_Class, A ; получить класс активного окна
    Win_To_Close = HH Parent|ConsoleWindowClass|ExploreWClass|CabinetWClass|NativeHWNDHost|Notepad|AutoHotkey2|TWhatNodeFrm|RegEdit_RegEdit ; список классов закрываемых окон
    ; 1 справка, 2 консоль, 3 проводник, 4 проводник(другой), 5 установка и удаление программ, 6 блокнот, 7 список горячих клавиш, 8 окно выбора ключей в ART, RegEdit
    Loop, parse, Win_To_Close, | ; обработать список окон (разделитель - "|")
    {
        If Win_To_Close_Class = %A_LoopField% ; если текущее окно - из списка, то...
        {
            WinClose, ahk_class %Win_To_Close_Class% ; закрыть окно
            KeyWait, ESC ; ожидать пока клавиша не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
            Return ; закончить обработку горячей клавиши
        }
    }
; ---------- дополнительный список окон, которые нужно закрыть ---------------
; === WinClose, WinKill, PostMessage - не закрывает неспецифицированные ahk_class #32770 (например, окно FreeMemory) ===
; указать через запятую фрагменты заголовков окон, которые нужно закрыть (пробелов после запятой не делать)
    If Win_To_Close_Title contains FuncPopUp,- PromtX,- X-Translator PLATINUM,FreeMemory,FreeRAM XP Pro ; список фрагментов заголовков окон
        Send !{F4} ; закрыть окно по заголовку
    If Win_To_Close_Title = Media Library ; если окно - Media Library (Winamp)
        Send !{sc026} ; закрыть окно Media Library по горячей клавише Alt+L
    KeyWait, ESC ; ожидать пока клавиша не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ================ ЗАКРЫТИЕ ОКОН (ЛЮБЫХ) ======================
!sc02D:: ; ALT+X - закрытие любых окон
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    WinGetActiveTitle, Win_To_Close_Title ; получить заголовок активного окна
    If ( Win_Class = "Shell_TrayWnd" OR Win_Class = "ProgMan" OR Win_Class = "AltDesk1.x" ) ; если окно - "панель задач" или "рабочий стол" или AltDesk, то...
        Return ; закончить обработку горячей клавиши (не выходить из Windows, или из AltDesk)
    ; если окно не из вышеперечисленных, то...
    If Win_Class = BaseWindow_RootWnd ; если окно - Winamp...
    {
        WinClose, ahk_class Winamp v1.x ; закрыть Winamp
        Return ; закончить обработку горячей клавиши
    }
    If Win_Class = PROCEXPL ; если окно - Process Explorer...
    {
;~        WinMenuSelectItem, ahk_class PROCEXPL,, File, Exit ; можно использовать эту строку, а можно ту, что ниже (она универсальнее)
        PostMessage, 0x111, 40001,,, ahk_class PROCEXPL ; выбрать пункт меню File -> Exit
        Return ; закончить обработку горячей клавиши
    }
    IfWinActive, HDDlife Pro - ; если активно окно HDDlife Pro...
    {
        WinMenuSelectItem,,, 1&, 5& ; выбрать меню Файл -> Выход
        Return ; закончить обработку горячей клавиши
    }
    ; если окно - не из вышеперечисленных, то...
    ; закрыть окно по заголовку, т.к. WinClose, WinKill, PostMessage - не закрывает неспецифицированные ahk_class #32770
    ; указать через запятую фрагменты заголовков окон, которые нужно закрыть (пробелов после запятой не делать)
    If Win_To_Close_Title contains AWicons,FreeMemory ; список фрагментов заголовков окон
        Send !{F4} ; закрыть окно по заголовку
    Else ; если окно должно закрываться не по заголовку, то...
        WinClose, ahk_class %Win_Class% ; закрыть окно по классу
    KeyWait, sc02D ; ожидать пока клавиша "X" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== ЗАКРЫТИЕ ОКОН БЕЗ СОХРАНЕНИЯ ==================
!#sc02D:: ; ALT+WIN+X - закрытие окон без сохранения
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    If ( Win_Class = "Shell_TrayWnd" OR Win_Class = "ProgMan" OR Win_Class = "AltDesk1.x" ) ; если окно - "панель задач" или "рабочий стол" или AltDesk, то...
        Return ; закончить обработку горячей клавиши (не выходить из Windows)
    ; если окно - не из вышеперечисленных, то...
    WinClose, ahk_class %Win_Class% ; закрыть окно
    Sleep, 200 ; пауза для ожидания окна с вопросом о сохранении
    Send {TAB} ; перейти на кнопку "нет"
    Sleep, 50 ; пауза для реакции перехода на нужную кнопку
    Send {ENTER} ; и нажать её
    KeyWait, sc02D ; ожидать пока клавиша "X" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== СВЕРНУТЬ - РАЗВЕРНУТЬ ОКНО ==================
#sc01F:: ; WIN+S - свернуть окно (ДВОЙНОЕ нажатие - развернуть)
;-----------------------------------------------------------------------------
    If Count_Presses > 0 ; если таймер уже запущен, то...
    {
        Count_Presses += 1 ; плюсуем каждое нажатие клавиши (число будет обрабатываться в подпрограмме соответствующего таймера)
        Return ; закончить обработку горячей клавиши (ее дальнейшую обработку уже определяет таймер и его подпрограмма)
    }
    ; иначе - это первое нажатие из новой серии
    Count_Presses = 1 ; выставляем флаг, что клавиша один раз нажата
    SetTimer, Timer_Presses_1, 300 ; переходить к указанной подпрограмме через каждые 300 миллисекунд
Return ; закончить обработку горячей клавиши

Timer_Presses_1: ; подпрограмма действий в зависимости от количества нажатий
    SetTimer, Timer_Presses_1, off ; выключить таймер
    If Count_Presses = 1 ; если клавиша нажата однажды...
    {
        WinGet, Win_ID, ID, A ; сохранить ID сворачиваемого окна в переменной
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
            Goto, WinAmp_Min_Restore ; ==> перейти к метке свернуть WinAmp (WinAmp_Min_Restore)
            ; Целиком скрипт для управления WinAmp'ом можно найти здесь 
            ; http://forum.script-coding.com/viewtopic.php?id=75
            ; Но чтобы этот (текущий) скрипт не "ошибался", я поместил сюда небольшой фрагментик упомянутого скрипта
            ; См. самую последнюю подпрограмму
        }
        ; если окно - не winamp, то...
        WinMinimize, ahk_class %Win_Class% ; свернуть окно
    }
    If Count_Presses = 2 ; если клавиша нажата дважды...
    {
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
            Goto, WinAmp_Min_Restore ; ==> перейти к метке Развернуть WinAmp (WinAmp_Min_Restore)
        }
        ; если окно не winamp, то...
        WinRestore, ahk_id %Win_ID% ; восстановить свернутое окно с запомненным ID
        WinActivate, ahk_id %Win_ID% ; активизировать его
        ; Не все окна нормально реагируют на команду PostMessage, 0x112, 0xF120,,, ahk_id %Win_ID%
            ; 0x112 = WM_SYSCOMMAND, 0xF120 = SC_RESTORE - развернуть
            ; 0x112 = WM_SYSCOMMAND, 0xF020 = SC_MINIMIZE - минимизировать
    }
    Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== МАКСИМИЗИРОВАТЬ - ВОССТАНОВИТЬ ОКНО ==================
#sc010:: ; WIN+Q - максимизировать/восстановить окно
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    ; НЕ ОБРАБАТЫВАТЬ ОКНО WINAMP
    If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        Return ; закончить обработку горячей клавиши
    ; если окно - не winamp, то...
    WinGetPos, X, Y,,, A ; получить позицию текущего окна
    If ( X=-4 and Y=-4) ; если окно максимизировано, то...
        WinRestore, A ; восстановить окно
    Else ; если не максимизировано, то...
        WinMaximize, A ; максимизировать окно
    KeyWait, sc010 ; ожидать пока клавиша "Q" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== НАЗНАЧИТЬ/СНЯТЬ ОКНО - ПОВЕРХ ВСЕХ ==================
#sc01E:: ; WIN+A (английская) - окно "поверх всех" (ДВОЙНОЕ нажатие - снять "поверх всех")
;-----------------------------------------------------------------------------
    If Count_Presses > 0 ; если таймер уже запущен, то...
    {
        Count_Presses += 1 ; плюсуем каждое нажатие клавиши (число будет обрабатываться в подпрограмме соответствующего таймера)
        Return ; закончить обработку горячей клавиши (ее дальнейшую обработку уже определяет таймер и его подпрограмма)
    }
    ; Иначе - это первое нажатие из новой серии
    Count_Presses = 1 ; выставляем флаг, что клавиша один раз нажата
    SetTimer, Timer_Presses_2, 300 ; переходить к указанной подпрограмме через каждые 300 миллисекунд
Return ; закончить обработку горячей клавиши

Timer_Presses_2: ; подпрограмма действий в зависимости от количества нажатий
    SetTimer, Timer_Presses_2, off ; выключить таймер
    If Count_Presses = 1 ; если клавиша нажата однажды...
    {
        ; ОБРАБОТАТЬ ОКНО WINAMP
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            PostMessage, 0x111, 40019,,, ahk_class Winamp v1.x ; окно - поверх всех
            Goto, LabelEXIT2 ; ==> перейти к окончанию обработки
        } ; если окно не Winamp, то...
        WinGet, Win_ID, ID, A ; получить ID активного окна
        WinSet, AlwaysOnTop, ON, ahk_id %Win_ID% ; окно - поверх всех
    }
    Else If Count_Presses = 2 ; если клавиша нажата дважды...
    {
        ; ОБРАБОТАТЬ ОКНО WINAMP
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
            PostMessage, 0x111, 40019,,, ahk_class Winamp v1.x ; снять "поверх всех"
        WinGet, Win_ID, ID, A ; получить ID активного окна
        WinSet, AlwaysOnTop, OFF, ahk_id %Win_ID% ; снять "поверх всех"
    }
    LabelEXIT2:
    Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== ПЕРЕМЕЩЕНИЕ ОКНА МЫШЬЮ (EWD) ==================
; Это - чуть-чуть переделанных скрипт из справки к AutoHotkey - Easy Window Dragging (EWD)
#LButton:: ; WIN+Левая мышь - перемещение окон за любое место внутри окна
;-----------------------------------------------------------------------------
    ; Вы можете отпустить клавишу WIN после нажатия левой кнопки, вместо того, чтобы удерживать ее
    ; И вы можете во время перемещения нажать Escape, чтобы отменить перемещение
    CoordMode, Mouse ; переключиться на абсолютные координаты экрана
    MouseGetPos, EWD_MouseStartX, EWD_MouseStartY, EWD_MouseWin ; получить начальную позицию мыши и ID окна под мышью
    WinGetClass, EWD_Win_Class, ahk_id %EWD_MouseWin% ; получаем класс окна под мышью
    If EWD_Win_Class = ProgMan ; если это рабочий стол, то...
        Return ; закончить обработку горячей клавиши
    WinGetPos, EWD_OriginalPosX, EWD_OriginalPosY,,, ahk_id %EWD_MouseWin% ; запоминаем исходные координаты окна
    SetTimer, EWD_WatchMouse, 10 ; переходить к указанной подпрограмме через каждые 10 мс
Return ; закончить обработку горячей клавиши

EWD_WatchMouse: ; подпрограмма обработки событий в таймере
    EWD_Work = 1 ; флаг, что подпрограмма выполняется (он нужен для корректной работы закрытия окон по Escape)
    GetKeyState, EWD_LButtonState, LButton, P ; проверить нажата ли левая кнопка мыши
    If EWD_LButtonState = U ; если кнопка отпущена, то закончить перемещение окна...
    {
        SetTimer, EWD_WatchMouse, off ; отключить таймер
        EWD_Work = ; сбрасываем флаг, что подпрограмма выполняется
        Return ; конец подпрограммы, закончить обработку горячей клавиши
    }
    GetKeyState, EWD_EscapeState, Escape, P ; проверить нажата ли клавиша Escape
    If EWD_EscapeState = D ; если нажата, то отменить перемещение окна (вернуть его в начальные координаты)
    {
        SetTimer, EWD_WatchMouse, off ; отключить таймер
        EWD_Work = ; сбрасываем флаг, что подпрограмма выполняется
        WinMove, ahk_id %EWD_MouseWin%,, %EWD_OriginalPosX%, %EWD_OriginalPosY% ; вернуть окно в начальные координаты
        Return ; конец подпрограммы, закончить обработку горячей клавиши
    }
    ; ...если кнопка нажата, то перемешать окно вслед за перемещением указателя мыши
    CoordMode, Mouse ; переключиться на абсолютные координаты экрана
    MouseGetPos, EWD_MouseX, EWD_MouseY ; получить текущие координаты мыши
    WinGetPos, EWD_WinX, EWD_WinY,,, ahk_id %EWD_MouseWin% ; получить позицию окна под мышкой
    SetWinDelay, -1 ; перемещать окно немедленно
    ; переместить окно под мышью вслед за мышью
    WinMove, ahk_id %EWD_MouseWin%,, EWD_WinX + EWD_MouseX - EWD_MouseStartX, EWD_WinY + EWD_MouseY - EWD_MouseStartY
    EWD_MouseStartX := EWD_MouseX ; обновить X координату для следующего вызова этой подпрограммы по таймеру
    EWD_MouseStartY := EWD_MouseY ; обновить Y координату для следующего вызова этой подпрограммы по таймеру
Return ; закончить подпрограмму и обработку горячей клавиши
;-----------------------------------------------------------------------------


WinAmp_Min_Restore: ; метка входа из WIN + S (фрагмент скрипта для управления Winamp'ом)
;-----------------------------------------------------------------------------
    WinGet, State, MinMax, ahk_class Winamp v1.x
    If State = -1 ; если окно минимизировано, то...
        WinActivate, ahk_class Winamp v1.x ; восстановить свернутое окно
    else ; если окно НЕ минимизировано, то...
    {
        IfWinActive, ahk_class BaseWindow_RootWnd ; если окно активно, то...
            WinMinimize, ahk_class Winamp v1.x ; свернуть окно
        else ; если окно НЕ активно, то...
            WinActivate, ahk_class Winamp v1.x ; активизировать окно (вывести на передний план)
    }
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).

2

Re: AutoHotkey: Управление окнами с помощью горячих клавиш

Функционал скрипта:
1. Закрытие окон определённых программ по нажатию Esc. Вы сможете закрывать по Esc окна CHM-справки, командного интерпретатора, проводника, апплета "Установка и удаление программ", блокнота, служебного окна скрипта AutoHotkey, редактора реестра и некоторых других специфических программ (полный список - см. комментарии в тексте скрипта).
2. Закрытие окон любых программ по нажатию Alt+X - замена Alt+F4 или меню "Файл" - "Выход".
3. Закрытие окон любых программ без сохранения изменений по нажатию Alt+Win+X - автоматическое нажатие кнопки "Нет" при запросе о сохранении.
4. Сворачивание окон любых программ по нажатию Win+S. Свёрнутое таким образом окно запоминается и может быть восстановлено в любой момент нажатием Win+S+S.
5. Максимизация/восстановление окон любых программ по нажатию Win+Q (переключатель).
6. Назначение окон любых программ "поверх всех" по нажатию Win+A (английская). Обработанное таким образом окно запоминается и может быть приведено в прежнее состояние в любой момент нажатием Win+A+A.
7. Перемещение окон любых программ с помощью левой кнопки мыши за любое место внутри окна при удержании клавиши Win. (Является аналогом перетаскивания окон в KDE при нажатой клавише Alt.) При перемещении клавишу Win можно бросить. Нажатие Esc во время перемещения отменяет перемещение.

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

3

Re: AutoHotkey: Управление окнами с помощью горячих клавиш

Вариант того же скрипта, где запрещено перетаскивание при нажатой Win максимизированных окон:

;*****************************************************************************
; AutoHotkey Version:   1.0.41.01+
; Автор:                Androgen Belkin
; Имя скрипта:          ControlsWinows.ahk (v.1.3)
;*****************************************************************************
; Управление окнами с помощью горячих клавиш.
;*****************************************************************************
#NoEnv         ; запрещаем имена переменных как у переменных окружения (повышаем производительность скрипта)
;~ #NoTrayIcon    ; не отображать иконку скрипта в трее
SendMode Input ; новый режим высылки без задержки и повышенной надежности
SetTitleMatchMode, 2 ; сравнивать с любой частью заголовка окна

; ========== ЗАКРЫТИЕ ПО ESCAPE (ТОЛЬКО УКАЗАННЫХ ОКОН) ===============
~ESC:: ; Escape - закрытие некоторых окон (справка, консоль, проводник, блокнот и др.)
;-----------------------------------------------------------------------------
    If EWD_Work = 1 ; если сейчас работает перемещение окна с помощью мыши (EWD), то...
        Return ; закончить обработку горячей клавиши (т.к. Escape назначена в EWD для отмены перемещения окна)
    WinGetActiveTitle, Win_To_Close_Title ; сохранить заголовок в переменной
    WinGetClass, Win_To_Close_Class, A ; получить класс активного окна
    Win_To_Close = HH Parent|ConsoleWindowClass|ExploreWClass|CabinetWClass|NativeHWNDHost|Notepad|AutoHotkey2|TWhatNodeFrm|RegEdit_RegEdit ; список классов закрываемых окон
    ; 1 справка, 2 консоль, 3 проводник, 4 проводник(другой), 5 установка и удаление программ, 6 блокнот, 7 список горячих клавиш, 8 окно выбора ключей в ART, RegEdit
    Loop, parse, Win_To_Close, | ; обработать список окон (разделитель - "|")
    {
        If Win_To_Close_Class = %A_LoopField% ; если текущее окно - из списка, то...
        {
            WinClose, ahk_class %Win_To_Close_Class% ; закрыть окно
            KeyWait, ESC ; ожидать пока клавиша не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
            Return ; закончить обработку горячей клавиши
        }
    }
; ---------- дополнительный список окон, которые нужно закрыть ---------------
; === WinClose, WinKill, PostMessage - не закрывает неспецифицированные ahk_class #32770 (например, окно FreeMemory) ===
; указать через запятую фрагменты заголовков окон, которые нужно закрыть (пробелов после запятой не делать)
    If Win_To_Close_Title contains FuncPopUp,- PromtX,- X-Translator PLATINUM,FreeMemory,FreeRAM XP Pro ; список фрагментов заголовков окон
        Send !{F4} ; закрыть окно по заголовку
    If Win_To_Close_Title = Media Library ; если окно - Media Library (Winamp)
        Send !{sc026} ; закрыть окно Media Library по горячей клавише Alt+L
    KeyWait, ESC ; ожидать пока клавиша не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ================ ЗАКРЫТИЕ ОКОН (ЛЮБЫХ) ======================
!sc02D:: ; ALT+X - закрытие любых окон
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    WinGetActiveTitle, Win_To_Close_Title ; получить заголовок активного окна
    If ( Win_Class = "Shell_TrayWnd" OR Win_Class = "ProgMan" OR Win_Class = "AltDesk1.x" ) ; если окно - "панель задач" или "рабочий стол" или AltDesk, то...
        Return ; закончить обработку горячей клавиши (не выходить из Windows, или из AltDesk)
    ; если окно не из вышеперечисленных, то...
    If Win_Class = BaseWindow_RootWnd ; если окно - Winamp...
    {
        WinClose, ahk_class Winamp v1.x ; закрыть Winamp
        Return ; закончить обработку горячей клавиши
    }
    If Win_Class = PROCEXPL ; если окно - Process Explorer...
    {
;~        WinMenuSelectItem, ahk_class PROCEXPL,, File, Exit ; можно использовать эту строку, а можно ту, что ниже (она универсальнее)
        PostMessage, 0x111, 40001,,, ahk_class PROCEXPL ; выбрать пункт меню File -> Exit
        Return ; закончить обработку горячей клавиши
    }
    IfWinActive, HDDlife Pro - ; если активно окно HDDlife Pro...
    {
        WinMenuSelectItem,,, 1&, 5& ; выбрать меню Файл -> Выход
        Return ; закончить обработку горячей клавиши
    }
    ; если окно - не из вышеперечисленных, то...
    ; закрыть окно по заголовку, т.к. WinClose, WinKill, PostMessage - не закрывает неспецифицированные ahk_class #32770
    ; указать через запятую фрагменты заголовков окон, которые нужно закрыть (пробелов после запятой не делать)
    If Win_To_Close_Title contains AWicons,FreeMemory ; список фрагментов заголовков окон
        Send !{F4} ; закрыть окно по заголовку
    Else ; если окно должно закрываться не по заголовку, то...
        WinClose, ahk_class %Win_Class% ; закрыть окно по классу
    KeyWait, sc02D ; ожидать пока клавиша "X" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== ЗАКРЫТИЕ ОКОН БЕЗ СОХРАНЕНИЯ ==================
!#sc02D:: ; ALT+WIN+X - закрытие окон без сохранения
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    If ( Win_Class = "Shell_TrayWnd" OR Win_Class = "ProgMan" OR Win_Class = "AltDesk1.x" ) ; если окно - "панель задач" или "рабочий стол" или AltDesk, то...
        Return ; закончить обработку горячей клавиши (не выходить из Windows)
    ; если окно - не из вышеперечисленных, то...
    WinClose, ahk_class %Win_Class% ; закрыть окно
    Sleep, 200 ; пауза для ожидания окна с вопросом о сохранении
    Send {TAB} ; перейти на кнопку "нет"
    Sleep, 50 ; пауза для реакции перехода на нужную кнопку
    Send {ENTER} ; и нажать её
    KeyWait, sc02D ; ожидать пока клавиша "X" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== СВЕРНУТЬ - РАЗВЕРНУТЬ ОКНО ==================
#sc01F:: ; WIN+S - свернуть окно (ДВОЙНОЕ нажатие - развернуть)
;-----------------------------------------------------------------------------
    If Count_Presses > 0 ; если таймер уже запущен, то...
    {
        Count_Presses += 1 ; плюсуем каждое нажатие клавиши (число будет обрабатываться в подпрограмме соответствующего таймера)
        Return ; закончить обработку горячей клавиши (ее дальнейшую обработку уже определяет таймер и его подпрограмма)
    }
    ; иначе - это первое нажатие из новой серии
    Count_Presses = 1 ; выставляем флаг, что клавиша один раз нажата
    SetTimer, Timer_Presses_1, 300 ; переходить к указанной подпрограмме через каждые 300 миллисекунд
Return ; закончить обработку горячей клавиши

Timer_Presses_1: ; подпрограмма действий в зависимости от количества нажатий
    SetTimer, Timer_Presses_1, off ; выключить таймер
    If Count_Presses = 1 ; если клавиша нажата однажды...
    {
        WinGet, Win_ID, ID, A ; сохранить ID сворачиваемого окна в переменной
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
            Goto, WinAmp_Min_Restore ; ==> перейти к метке свернуть WinAmp (WinAmp_Min_Restore)
            ; Целиком скрипт для управления WinAmp'ом можно найти здесь 
            ; http://forum.script-coding.com/viewtopic.php?id=75
            ; Но чтобы этот (текущий) скрипт не "ошибался", я поместил сюда небольшой фрагментик упомянутого скрипта
            ; См. самую последнюю подпрограмму
        }
        ; если окно - не winamp, то...
        WinMinimize, ahk_class %Win_Class% ; свернуть окно
    }
    If Count_Presses = 2 ; если клавиша нажата дважды...
    {
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
            Goto, WinAmp_Min_Restore ; ==> перейти к метке Развернуть WinAmp (WinAmp_Min_Restore)
        }
        ; если окно не winamp, то...
        WinRestore, ahk_id %Win_ID% ; восстановить свернутое окно с запомненным ID
        WinActivate, ahk_id %Win_ID% ; активизировать его
        ; Не все окна нормально реагируют на команду PostMessage, 0x112, 0xF120,,, ahk_id %Win_ID%
            ; 0x112 = WM_SYSCOMMAND, 0xF120 = SC_RESTORE - развернуть
            ; 0x112 = WM_SYSCOMMAND, 0xF020 = SC_MINIMIZE - минимизировать
    }
    Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== МАКСИМИЗИРОВАТЬ - ВОССТАНОВИТЬ ОКНО ==================
#sc010:: ; WIN+Q - максимизировать/восстановить окно
;-----------------------------------------------------------------------------
    WinGetClass, Win_Class, A ; получить класс активного окна
    ; НЕ ОБРАБАТЫВАТЬ ОКНО WINAMP
    If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        Return ; закончить обработку горячей клавиши
    ; если окно - не winamp, то...
    WinGetPos, X, Y,,, A ; получить позицию текущего окна
    If ( X=-4 and Y=-4) ; если окно максимизировано, то...
        WinRestore, A ; восстановить окно
    Else ; если не максимизировано, то...
        WinMaximize, A ; максимизировать окно
    KeyWait, sc010 ; ожидать пока клавиша "Q" не будет отпущена (чтобы исключить срабатывание от простого удержания нажатой клавиши)
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== НАЗНАЧИТЬ/СНЯТЬ ОКНО - ПОВЕРХ ВСЕХ ==================
#sc01E:: ; WIN+A (английская) - окно "поверх всех" (ДВОЙНОЕ нажатие - снять "поверх всех")
;-----------------------------------------------------------------------------
    If Count_Presses > 0 ; если таймер уже запущен, то...
    {
        Count_Presses += 1 ; плюсуем каждое нажатие клавиши (число будет обрабатываться в подпрограмме соответствующего таймера)
        Return ; закончить обработку горячей клавиши (ее дальнейшую обработку уже определяет таймер и его подпрограмма)
    }
    ; Иначе - это первое нажатие из новой серии
    Count_Presses = 1 ; выставляем флаг, что клавиша один раз нажата
    SetTimer, Timer_Presses_2, 300 ; переходить к указанной подпрограмме через каждые 300 миллисекунд
Return ; закончить обработку горячей клавиши

Timer_Presses_2: ; подпрограмма действий в зависимости от количества нажатий
    SetTimer, Timer_Presses_2, off ; выключить таймер
    If Count_Presses = 1 ; если клавиша нажата однажды...
    {
        ; ОБРАБОТАТЬ ОКНО WINAMP
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
        {
            PostMessage, 0x111, 40019,,, ahk_class Winamp v1.x ; окно - поверх всех
            Goto, LabelEXIT2 ; ==> перейти к окончанию обработки
        } ; если окно не Winamp, то...
        WinGet, Win_ID, ID, A ; получить ID активного окна
        WinSet, AlwaysOnTop, ON, ahk_id %Win_ID% ; окно - поверх всех
    }
    Else If Count_Presses = 2 ; если клавиша нажата дважды...
    {
        ; ОБРАБОТАТЬ ОКНО WINAMP
        WinGetClass, Win_Class, A ; получить класс активного окна
        If Win_Class = BaseWindow_RootWnd ; если класс окна - Winamp
            PostMessage, 0x111, 40019,,, ahk_class Winamp v1.x ; снять "поверх всех"
        WinGet, Win_ID, ID, A ; получить ID активного окна
        WinSet, AlwaysOnTop, OFF, ahk_id %Win_ID% ; снять "поверх всех"
    }
    LabelEXIT2:
    Count_Presses = 0 ; сбросить счет и подготовится к следующему ряду нажатий
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------


; ========== ПЕРЕМЕЩЕНИЕ ОКНА МЫШЬЮ (EWD) ==================
; Это - чуть-чуть переделанных скрипт из справки к AutoHotkey - Easy Window Dragging (EWD)
#LButton:: ; WIN+Левая мышь - перемещение окон за любое место внутри окна
;-----------------------------------------------------------------------------
    ; Вы можете отпустить клавишу WIN после нажатия левой кнопки, вместо того, чтобы удерживать ее
    ; И вы можете во время перемещения нажать Escape, чтобы отменить перемещение
    CoordMode, Mouse ; переключиться на абсолютные координаты экрана
    MouseGetPos, EWD_MouseStartX, EWD_MouseStartY, EWD_MouseWin ; получить начальную позицию мыши и ID окна под мышью
    WinGetClass, EWD_Win_Class, ahk_id %EWD_MouseWin% ; получаем класс окна под мышью
    If EWD_Win_Class = ProgMan ; если это рабочий стол, то...
        Return ; закончить обработку горячей клавиши
    WinGet, State, MinMax, ahk_id %EWD_MouseWin% ; проверяем не максимизировано ли окно
    If State = 1 ; если максимизировано, то...
    {
        SplashImage,, W160 H48 B1 FM10 CT000080,, Окно максимизировано,, Arial ; показать сообщение (чтоб не думалось)
        SetTimer, Remove_Splash, 600 ; переходить к указанной подпрограмме через каждые 0.6 секунды
        Return ; закончить обработку горячей клавиши

        Remove_Splash: ; подпрограмма удаления SplashImage
            SetTimer, Remove_Splash, Off ; выключить таймер
            SplashImage, Off ; удалить сплэш
        Return ; конец подпрограммы
    }
    WinGetPos, EWD_OriginalPosX, EWD_OriginalPosY,,, ahk_id %EWD_MouseWin% ; запоминаем исходные координаты окна
    SetTimer, EWD_WatchMouse, 10 ; переходить к указанной подпрограмме через каждые 10 мс
Return ; закончить обработку горячей клавиши

EWD_WatchMouse: ; подпрограмма обработки событий в таймере
    EWD_Work = 1 ; флаг, что подпрограмма выполняется (он нужен для корректной работы закрытия окон по Escape)
    GetKeyState, EWD_LButtonState, LButton, P ; проверить нажата ли левая кнопка мыши
    If EWD_LButtonState = U ; если кнопка отпущена, то закончить перемещение окна...
    {
        SetTimer, EWD_WatchMouse, off ; отключить таймер
        EWD_Work = ; сбрасываем флаг, что подпрограмма выполняется
        Return ; конец подпрограммы, закончить обработку горячей клавиши
    }
    GetKeyState, EWD_EscapeState, Escape, P ; проверить нажата ли клавиша Escape
    If EWD_EscapeState = D ; если нажата, то отменить перемещение окна (вернуть его в начальные координаты)
    {
        SetTimer, EWD_WatchMouse, off ; отключить таймер
        EWD_Work = ; сбрасываем флаг, что подпрограмма выполняется
        WinMove, ahk_id %EWD_MouseWin%,, %EWD_OriginalPosX%, %EWD_OriginalPosY% ; вернуть окно в начальные координаты
        Return ; конец подпрограммы, закончить обработку горячей клавиши
    }
    ; ...если кнопка нажата, то перемешать окно вслед за перемещением указателя мыши
    CoordMode, Mouse ; переключиться на абсолютные координаты экрана
    MouseGetPos, EWD_MouseX, EWD_MouseY ; получить текущие координаты мыши
    WinGetPos, EWD_WinX, EWD_WinY,,, ahk_id %EWD_MouseWin% ; получить позицию окна под мышкой
    SetWinDelay, -1 ; перемещать окно немедленно
    ; переместить окно под мышью вслед за мышью
    WinMove, ahk_id %EWD_MouseWin%,, EWD_WinX + EWD_MouseX - EWD_MouseStartX, EWD_WinY + EWD_MouseY - EWD_MouseStartY
    EWD_MouseStartX := EWD_MouseX ; обновить X координату для следующего вызова этой подпрограммы по таймеру
    EWD_MouseStartY := EWD_MouseY ; обновить Y координату для следующего вызова этой подпрограммы по таймеру
Return ; закончить подпрограмму и обработку горячей клавиши
;-----------------------------------------------------------------------------


WinAmp_Min_Restore: ; метка входа из WIN + S (фрагмент скрипта для управления Winamp'ом)
;-----------------------------------------------------------------------------
    WinGet, State, MinMax, ahk_class Winamp v1.x
    If State = -1 ; если окно минимизировано, то...
        WinActivate, ahk_class Winamp v1.x ; восстановить свернутое окно
    else ; если окно НЕ минимизировано, то...
    {
        IfWinActive, ahk_class BaseWindow_RootWnd ; если окно активно, то...
            WinMinimize, ahk_class Winamp v1.x ; свернуть окно
        else ; если окно НЕ активно, то...
            WinActivate, ahk_class Winamp v1.x ; активизировать окно (вывести на передний план)
    }
Return ; закончить обработку горячей клавиши
;-----------------------------------------------------------------------------

Идею опубликовал Androgen.

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