#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;список окон IE.
global My_Array := Array()
;id целевого окна (ОБТЕКАЕМОГО)
global mainWinId := 0
;Получить размеры рабочей области экрана
getMonitor(){
cArray := Array()
SysGet, Monitor, Monitor, 1
SysGet, MonitorWorkArea, MonitorWorkArea, 1
WinGetPos,,,_w_, _h_, ahk_class Shell_TrayWnd ;получить размеры панели управления
cArray.1 := MonitorWorkAreaRight
cArray.2 := MonitorBottom - _h_
return cArray
}
;Ширина и высота изначально рабочей области экрана
c_Array := getMonitor()
global scrWorkArea_w := c_Array.1
global scrWorkArea_h := c_Array.2
;Ширина и высота рамки блокируемой области
global frame_w := 500
global frame_h := 200
;проверяем является ли окном IE
Check_id(id_old){
ch := false
for index, element in My_Array
{
if(id_old == element){
ch := true
}
}
return ch
}
;двигаем все окна кроме целевого
moveOrdWin(){
;обрабатываем окна IE
IfWinExist, ahk_class IEFrame
{
WinGet, id, list, ahk_exe iexplore.exe
Loop, %id% {
this_id := id%A_Index%
My_Array.Push(this_id) ;добавляем в список окон IE. Окна IE надо обрабатывать отдельно от др. окон
if(this_id != mainWinId){
WinGetPos, X, Y, , , ahk_id %this_id%
if((X<frame_w)and(Y<frame_h)){ ;если находится в блокируемой области
WinActivate, ahk_id %this_id%
SysGet, m1, Monitor, 1
;у IE окна не только класса IEFrame, поэтому надо 2 раза фигачить WinMove на всякий случай
WinMove, ahk_class IEFrame,, frame_w+1, 0, scrWorkArea_w-frame_w-1, scrWorkArea_h
WinMove,,, frame_w+1, 0, scrWorkArea_w-frame_w-1, scrWorkArea_h
}
}
}
}
;обрабатываем все остальные окна
WinGet, id, list,,, Program Manager
Loop, %id% {
this_id := id%A_Index%
if(this_id != mainWinId){
go := Check_id(this_id)
if(go == false){ ;проверяем если не окно IE
WinGetPos, X, Y, , , ahk_id %this_id%
if((X<frame_w)and(Y<frame_h)){
WinGet, WinStatus, MinMax, ahk_id %this_id%
if (WinStatus != 0)
WinRestore, ahk_id %this_id%
WinMove, ahk_id %this_id%,, frame_w+1, 0, scrWorkArea_w-frame_w-1, scrWorkArea_h
}
}
}
}
}
;Включить отслеживание открытия нового окна
DllCall("RegisterShellHookWindow", Ptr, A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage", Str, "SHELLHOOK"), "ShellProc")
OnExit("Exit")
Return
ShellProc(nCode, hWnd) {
static HSHELL_WINDOWCREATED := 1
if (nCode = HSHELL_WINDOWCREATED) {
cX := frame_w + 1
cY := 0
WinGetClass, this_class, ahk_id %hWnd%
if(this_class != "#32770")
WinMove, ahk_id %hWnd%,, frame_w+1, 0, scrWorkArea_w - frame_w - 1, scrWorkArea_h
}
}
Exit() {
DllCall("DeregisterShellHookWindow", Ptr, A_ScriptHwnd)
}
;Включаем целевое окно
^+1::
if(mainWinId == 0){
WinGet, active_id, ID, A
mainWinId := active_id
WinGet, WinStatus, MinMax, ahk_id %active_id%
if (WinStatus != 0)
WinRestore, ahk_id %active_id%
WinMove, ahk_id %active_id%,, 0, 0, frame_w, frame_h
Winset, Alwaysontop, , ahk_id %active_id%
moveOrdWin()
} else {
WinGetTitle, Title, ahk_id %mainWinId%
MsgBox, Прежде выключите целевое окно: %Title%
}
return
;Выключаем целевое окно
^+2::
WinGet, active_id, ID, A
if(mainWinId = active_id){
mainWinId := 0
Winset, Alwaysontop, , ahk_id %active_id%
}
return
;двигаем все окна, кроме целевого
^3::moveOrdWin()
От идеи мониторинга перемещения всех окон отказался. Боюсь что будет грузить систему если он каждую секунду будет прозванивать десяток окон. Сделал передвижение окон по кнопке.
И еще, почему-то IE отказывается быть целевым окном. Я вроде добавляю его id в исключение(чтобы только его не видоизменять), а он каким-то образом после этого плодит себе копию с другим id. Фиг его знает что не так с этим IE.
Ну, мне всеравно, мне для работы надо чтобы Excel всегда был на виду. Работает - и это главное.