Скрипт, защищающий некоторые программы от случайного закрытия. При нажатии на "крестик" программа не закрывается, а "сворачивается" скриптом (делается невидимой). При щелчке колесиком мыши на рабочем столе (или правой на иконке) скрипт выводит список свернутых таким образом окон в виде меню, из которого эти окна можно восстановить. Обрабатываются программы: Adobe Distiller, Adobe Acrobat, Adobe Photoshop, PageMaker, FAR, Mozilla (браузер). Кроме того, скрипт содержит дополнительное меню для вызова некоторых часто используемых программ и окон: MyComputer, MyDocuments, Internet Explorer, Mozilla, WinRAR, Свойства экрана, Панель управления, Корзина, Установка и удаление программ, SiSoftSandra. Список обрабатываемых программ и пунктов меню легко изменить/расширить.
Автор скрипта - Steve Key.
;#NoTrayIcon ;я думаю, иконка не нужна, если меню вызывается и так...
;если не нужно - раскомментируйте предыдущую строчку
;эта установка убирает "системные" пункты меню иконки скрипта в трее;
;если эти пункты нужны, задайте "Y" вместо "N"
mwt_StandardMenu = n
;если "Моё меню" не нужно, поставьте "N"
mwt_MyMenu = y
;ширина и высота крестика в верхнем правом углу окон, подобрать по факту
; 33 - это экспериментально подобранный размер крестика у меня на компе,
; я люблю настраивать размеры кнопок, системного шрифта и лифтов побольше,
; чтобы "не целиться" в них мышкой, обычно же 29-30 хватает...
WKrest = 33
HKrest = 33
;Моё меню
if mwt_StandardMenu = Y
Menu, Tray, Add ;разделитель
if mwt_MyMenu = Y
{
Menu, Tray, Add, Диски, MyComputer
Menu, Tray, Add, Документы, MyDocuments
Menu, Tray, Add, Internet Explorer, IE
Menu, Tray, Add, Браузер, Mozilla
Menu, Tray, Add, Архиватор, WinRAR
Menu, Tray, Add, Свойства экрана, Screen
Menu, Tray, Add, Панель управления, Panel
Menu, Tray, Add, Корзина, Bin
Menu, Tray, Add, Удаление программ, DelProgs
Menu, Tray, Add, SiSoftSandra, Sandra
;заготовка для вложенного меню
;Menu, Folders, Add, Корзина, Bin
;Menu, Tray, Add, Папки, :Folders
Menu, Tray, Add ;разделитель меню от скрытых программ, можно два поставить...
}
;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk конец определения моего меню
;установка иконки скрипта в трее
;я думаю, она нахрен не нужна, если меню вызывается и так...
Menu, Tray, Icon, %A_WinDir%\system32\Shell32.dll, 91
;максимальное количество окон, которое может быть скрыто
mwt_MaxWindows = 10
;горячая клавиша, скрывающая текущее окно
;;;;;;;;;;;;;;;;mwt_Hotkey = #h ;Win+H убрано, запускается по-другому - Steve Key
;горячая клавиша, восстанавливающая все скрытые окна
mwt_HotkeyRestoreAll = ^#MButton ;Ctrl+Win+Колесико мыши
;может быть запущено не более одного экземпляра сценария
#SingleInstance
;работать со скрытыми окнами
DetectHiddenWindows, On
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;назначение горячей клавиши, восстанавливающей все скрытые окна
Hotkey, %mwt_HotkeyRestoreAll%, mwt_RestoreAll
;при завершении сценария необходимо отобразить все скрытые окна, если таковые есть
OnExit, mwt_RestoreAllThenExit
;настройка меню иконки скрипта в трее
if mwt_StandardMenu = n
Menu, Tray, NoStandard
;добавляются пункты меню для восстановления и выхода
Menu, Tray, Add, Восстановить все, mwt_RestoreAll
Menu, Tray, Add, Выход, mwt_RestoreAllThenExit
Menu, Tray, Add
;ограничение ширины меню (в символах)
mwt_MaxLength = 25
return ;конец секции авто-выполнения скрипта
;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk Начало моей проги
$LButton:: ;левая кнопка мыши...
Click Down ;Нажимаем кнопку мыши, чтобы сделать окно текущим, и всё...
return
$LButton Up:: ;все действия делаем, как и принято в Windows, при отжатии кнопки
;...если отжата на крестике закрытия окна (в правом верхнем углу)
CoordMode, Mouse, Screen
MouseGetPos,xpos,ypos ;получаем координаты мыши...
WinGetClass, class, A ;все по возможности, обращается к текущему окну...
WinGetPos, winX, winY, Width,, A
if(xpos>=winX+Width-WKrest AND xpos<=winX+Width AND ypos<=winY+HKrest)
{
WinGetActiveTitle, Win_To_Close_Title ;сохранить заголовок в переменной
WinGetClass, Win_To_Close_Class, A ;получить класс активного окна
; список классов закрываемых окон через |
Win_To_Close = Distiller|AdobeAcrobat|Photoshop|VWClass500|ConsoleWindowClass|MozillaWindowClass
;ну, эти окна понятно, что значат|PageMaker |FAR |Mozilla (браузер)
;класс окна можно посмотреть Windows Spy, вызвав его из стандартного меню AHK (если таковое включить)
Loop, parse, Win_To_Close, | ;обработать список окон (разделитель - "|")
{
If Win_To_Close_Class = %A_LoopField% ;если текущее окно - из списка, то...
{
gosub mwt_Minimize
}
}
}
Click Up ;отпустить кнопку мыши нужно в любом случае, и она не сработает,
return ;если окно поменяли или убрали, что нам и нужно...
;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk Конец моей проги
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;подпрограмма, скрывающая текущее окно
mwt_Minimize:
if mwt_WindowCount >= %mwt_MaxWindows%
{
MsgBox Не может быть скрыто одновременно больше, чем %mwt_MaxWindows% окон.
return
}
;получаем активное окно и используем его как "последнее найденное окно",
;т.е. окно по умолчанию для всех дальнейших вызовов функций, связанных с окнами
WinWait, A,, 2
if ErrorLevel <> 0
return
;получаем информацию об активном окне (последнем найденном?..)
WinGet, mwt_ActiveID, ID ;хэндл (HWND) окна
WinGetTitle, mwt_ActiveTitle ;заголовок окна
WinGetClass, mwt_ActiveClass ;имя класса окна
WinGet, mwt_ActivePID, PID ;идентификатор процесса, которому принадлежит окно
WinGet, mwt_List, List, ahk_pid %mwt_ActivePID% ;список всех окон этого процесса
WinGet, mwt_ActiveProcess, ProcessName ;имя процесса, которому принадлежит окно
;рабочий стол и панель задач скрывать нельзя
if mwt_ActiveClass in Shell_TrayWnd,Progman
return
;поскольку скрытие окна не будет деактивировать его, переключимся
;в другое окно (как будто пользователь нажал Alt+Escape)
Send, !{esc}
;собственно скрываем нужные окна процесса (делаем их невидимыми),
;скрытию подлежат все окна текущего процесса со стилем WS_VISIBLE,
;mwt_WindowsIDs - список хэндлов скрываемых окон,
;разделённых символом | (вертикальная черта)
mwt_WindowsIDs = ""
;проводник - особый случай, скрывать можно только текущее окно процесса
If mwt_ActiveProcess = explorer.exe
{
WinHide, ahk_id %mwt_ActiveID%
mwt_WindowsIDs = %mwt_WindowsIDs%|%mwt_ActiveID%
}
;скрываем все видимые окна процесса
Else
{
Loop, %mwt_List%
{
mwt_id := mwt_List%A_Index%
WinGet, style, Style, ahk_id %mwt_id%
if ( style & 0x10000000 ) ;WS_VISIBLE
{
WinHide, ahk_id %mwt_id%
;Result := DllCall("ShowWindow", "UInt", mwt_id, "Int", "0")
mwt_WindowsIDs = %mwt_WindowsIDs%|%mwt_id%
}
}
}
;если заголовок окна пуст, используем имя класса,
;т.к. нам нужен непустой заголовок пункта меню
if mwt_ActiveTitle =
mwt_ActiveTitle = ahk_class %mwt_ActiveClass%
;обрезаем заголовок окна до максимальной длины mwt_MaxLength
StringLeft, mwt_ActiveTitle, mwt_ActiveTitle, %mwt_MaxLength%
;обеспечение уникальности заголовка пункта меню:
Loop, %mwt_MaxWindows%
{
if mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
{
;Нашли такой же заголовок, так что заголовок не уникален.
StringTrimLeft, mwt_ActiveIDShort, mwt_ActiveID, 2
StringLen, mwt_ActiveIDShortLength, mwt_ActiveIDShort
StringLen, mwt_ActiveTitleLength, mwt_ActiveTitle
mwt_ActiveTitleLength += %mwt_ActiveIDShortLength%
mwt_ActiveTitleLength += 1
if mwt_ActiveTitleLength > %mwt_MaxLength%
{
TrimCount = %mwt_ActiveTitleLength%
TrimCount -= %mwt_MaxLength%
StringTrimRight, mwt_ActiveTitle, mwt_ActiveTitle, %TrimCount%
}
;создаём уникальный заголовок:
mwt_ActiveTitle = %mwt_ActiveTitle% %mwt_ActiveIDShort%
break
}
}
;на всякий случай проверим, нет ли этого окна уже в списке ранее скрытых
mwt_AlreadyExists = n
Loop, %mwt_MaxWindows%
{
if mwt_WindowID%a_index% = %mwt_ActiveID%
{
mwt_AlreadyExists = y
break
}
}
;добавим окно в массив и в меню
if mwt_AlreadyExists = n
{
Menu, Tray, add, %mwt_ActiveTitle%, RestoreFromTrayMenu
mwt_WindowCount += 1
Loop, %mwt_MaxWindows% ;поиск свободного элемента в массиве
{
if mwt_WindowID%a_index% = ;элемент свободен
{
mwt_WindowID%a_index% = %mwt_ActiveID%
mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
mwt_WindowPID%a_index% = %mwt_ActivePID%
mwt_WinIDs%a_index% = %mwt_WindowsIDs%
break
}
}
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню иконки скрипта в трее,
;соответствующая конкретному скрытому окну
RestoreFromTrayMenu:
Menu, Tray, delete, %A_ThisMenuItem%
;поиск окна по его уникальному заголовку, сохраненному как название пункта меню
Loop, %mwt_MaxWindows%
{
if mwt_WindowTitle%a_index% = %A_ThisMenuItem%
{
StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
StringTrimRight, PIDToRestore, mwt_WindowPID%a_index%, 0
mwt_WindowsIDs := mwt_WinIDs%a_index%
Loop, parse, mwt_WindowsIDs, |
WinShow, ahk_id %A_LoopField%
WinActivate ahk_id %IDToRestore%
mwt_WindowID%a_index% = ;очищаем элементы массивов
mwt_WindowTitle%a_index% =
mwt_WindowPID%a_index% =
mwt_WinIDs%a_index% =
mwt_WindowCount -= 1
break
}
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню скрипта
;"Выход и восстановление всех скрытых окон"
mwt_RestoreAllThenExit:
Gosub, mwt_RestoreAll
ExitApp ;завершение работы скрипта
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню скрипта
;"Восстановление всех скрытых окон"
mwt_RestoreAll:
Loop, %mwt_MaxWindows%
{
if mwt_WindowID%a_index% <>
{
StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
StringTrimRight, PIDToRestore, mwt_WindowPID%a_index%, 0
mwt_WindowsIDs := mwt_WinIDs%a_index%
Loop, parse, mwt_WindowsIDs, |
WinShow, ahk_id %A_LoopField%
WinActivate ahk_id %IDToRestore%
StringTrimRight, MenuToRemove, mwt_WindowTitle%a_index%, 0
Menu, Tray, delete, %MenuToRemove%
mwt_WindowID%a_index% =
mwt_WindowTitle%a_index% =
mwt_WindowPID%a_index% =
mwt_WinIDs%a_index% =
mwt_WindowCount -= 1
}
if mwt_WindowCount = 0
break
}
return
;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
;Дальше идет моя прога: Steve Key
MButton:: ;нажатие на колесико мыши на рабочем столе показывает контекстное меню
;такое же, как у иконки скрипта...
MouseGetPos, x, y, win
WinGetClass, class, ahk_id %win%
IfEqual, class, Progman
{
Menu, Tray, Show
}
Else
{
send {MButton}
}
return
;собственно, мое меню
MyDocuments:
Run ::{450d8fba-ad25-11d0-98a8-0800361b1103} ;Мои документы
return
WinRAR:
Run, WinRAR.exe ;если WinRAR установлена, то вызовется
return
Mozilla:
Run, mozilla.exe ;если Mozilla установлен, то вызовется
Return
IE:
Run, about:blank ;вызов Интернет Эксплорера
return
MyComputer:
Run ::{20d04fe0-3aea-1069-a2d8-08002b30309d} ;Мой компьютер
Return
Bin:
Run ::{645ff040-5081-101b-9f08-00aa002f954e} ;Корзина
Return
Screen:
Run, desk.cpl ;Свойства Экрана
return
DelProgs:
Run, appwiz.cpl ;Установка и удаление программ
return
Sandra:
Run, SanCpl.cpl ;если Сандра установлена, то вызовется
return
Panel:
Run rundll32.exe shell32.dll`,Control_RunDLL ;Панель управления
return
;Конец действий моего меню колесиком мыши на рабочем столе!