![Тонкая настройка этой красной рамки вокруг активного окна AHK-скрипта](https://rvso.com/image/1525455/%D0%A2%D0%BE%D0%BD%D0%BA%D0%B0%D1%8F%20%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0%20%D1%8D%D1%82%D0%BE%D0%B9%20%D0%BA%D1%80%D0%B0%D1%81%D0%BD%D0%BE%D0%B9%20%D1%80%D0%B0%D0%BC%D0%BA%D0%B8%20%D0%B2%D0%BE%D0%BA%D1%80%D1%83%D0%B3%20%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%BE%D0%BA%D0%BD%D0%B0%20AHK-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0.png)
Я новичок в autohotkey, но я нашел этот полезный скрипт для установки красной рамки вокруг моего активного окна, делая его более заметным. Я установил autohotkey и запустил скрипт, однако у меня есть две проблемы:
- Не работает ни при развернутом, ни при прижатом к одной стороне окне.
- Граница не ровная
Я прикрепил несколько фотографий, демонстрирующих проблему:
Если кто-то может помочь и исправить этот скрипт или предоставить подробные инструкции по его исправлению (имейте в виду, что я новичок), я буду признателен.
#Persistent
SetTimer, DrawRect, 50
border_thickness = 10
border_color = FF0000
DrawRect:
WinGetPos, x, y, w, h, A
if (x="")
return
Gui, +Lastfound +AlwaysOnTop +Toolwindow
iw:= w+4
ih:= h + 4
w:=w+ 8
h:=h + 8
x:= x - border_thickness
y:= y - border_thickness
Gui, Color, FF0000
Gui, -Caption
WinSet, Region, 0-0 %w%-0 %w%-%h% 0-%h% 0-0 %border_thickness%-%border_thickness% %iw%-%border_thickness% %iw%-%ih% %border_thickness%-%ih% %border_thickness%-%border_thickness%
Gui, Show, w%w% h%h% x%x% y%y% NoActivate, Table awaiting Action
return
решение1
Я бы рекомендовал переименовать переменные, чтобы они имели смысл. WinSet
Оператор рисует два прямоугольника в парах координат x/y, поэтому именование переменных в парах координат x/y и назначение их перед оператором WinSet
менее запутанно
В этом конкретном примере вы также рисуете границу вокруг внешней стороны окна. Когда внешняя сторона окна находится на краю экрана, граница находится за пределами экрана, поэтому она не будет видна. Если вы хотите нарисовать ее на экране, когда граница находится на краю экрана (или даже за его пределами), вам нужно будет нарисовать границу внутри (или частично внутри) границы окна, а не рисовать ее за пределами границы окна.
Но это лишь частичное решение, поскольку в развернутом состоянии окно находится даже дальше от экрана, чем просто на краю(ах). В этом случае вам придется обнаружить развернутое состояние и сместить границу еще дальше, чем она обычно находится, на определенное количество пикселей.
Я подправил, переименовал переменные и подправил ваш код, чтобы привести пример. Вы можете изменить другой «тип границы», чтобы увидеть эффект... остальное — просто математика, если вы хотите нарисовать его по-другому.
#Persistent
SetTimer, DrawRect, 50
border_thickness = 5
border_color = FF0000
DrawRect:
WinGetPos, x, y, w, h, A
if (x="")
return
Gui, +Lastfound +AlwaysOnTop +Toolwindow
borderType:="inside" ; set to inside, outside, or both
if (borderType="outside") {
outerX:=0
outerY:=0
outerX2:=w+2*border_thickness
outerY2:=h+2*border_thickness
innerX:=border_thickness
innerY:=border_thickness
innerX2:=border_thickness+w
innerY2:=border_thickness+h
newX:=x-border_thickness
newY:=y-border_thickness
newW:=w+2*border_thickness
newH:=h+2*border_thickness
} else if (borderType="inside") {
WinGet, myState, MinMax, A
if (myState=1)
offset:=8
else
offset:=0
outerX:=offset
outerY:=offset
outerX2:=w-offset
outerY2:=h-offset
innerX:=border_thickness+offset
innerY:=border_thickness+offset
innerX2:=w-border_thickness-offset
innerY2:=h-border_thickness-offset
newX:=x
newY:=y
newW:=w
newH:=h
} else if (borderType="both") {
outerX:=0
outerY:=0
outerX2:=w+2*border_thickness
outerY2:=h+2*border_thickness
innerX:=border_thickness*2
innerY:=border_thickness*2
innerX2:=w
innerY2:=h
newX:=x-border_thickness
newY:=y-border_thickness
newW:=w+4*border_thickness
newH:=h+4*border_thickness
}
Gui, Color, %border_color%
Gui, -Caption
;WinSet, Region, 0-0 %w%-0 %w%-%h% 0-%h% 0-0 %border_thickness%-%border_thickness% %iw%-%border_thickness% %iw%-%ih% %border_thickness%-%ih% %border_thickness%-%border_thickness%
WinSet, Region, %outerX%-%outerY% %outerX2%-%outerY% %outerX2%-%outerY2% %outerX%-%outerY2% %outerX%-%outerY% %innerX%-%innerY% %innerX2%-%innerY% %innerX2%-%innerY2% %innerX%-%innerY2% %innerX%-%innerY%
;Gui, Show, w%w% h%h% x%x% y%y% NoActivate, Table awaiting Action
Gui, Show, w%newW% h%newH% x%newX% y%newY% NoActivate, Table awaiting Action
return
Также, просто для информации, есть также способы перехвата событий обратного вызова Windows для событий перемещения окна, так что вам не придется использовать 50-мс таймер, который всегда обновляется. В этом случае он будет обновляться только при перемещении окна, и таймер будет иметь видимую задержку и накладные расходы на обработку. Но таймер — это гораздо более простое решение для реализации с самого начала (как вы уже сделали), и во многих случаях это действительно не стоит дополнительной сложности для перехвата событий окна, если вам это не нужно. Просто сообщаю вам, что это возможно.
решение2
Вместо того, чтобы исправлять свой скрипт, возьмите этот код, который делает именно то, что вам нужно.
#Requires AutoHotkey 2.0+
#SingleInstance Force
SetTimer(DrawBorder,100)
DrawBorder(){
Static OS:=3
Static BG:="FF0000"
Static myGui:=Gui("+AlwaysOnTop +ToolWindow -Caption","GUI4Border")
myGui.BackColor:=BG
WA:=WinActive("A")
If WA && !WinGetMinMax(WA) && !WinActive("GUI4Border ahk_class AutoHotkeyGUI"){
WinGetPos(&wX,&wY,&wW,&wH,WA)
myGui.Show("x" wX " y" wY " w" wW " h" wH " NA")
Try WinSetRegion("0-0 " wW "-0 " wW "-" wH " 0-" wH " 0-0 " OS "-" OS " " wW-OS
. "-" OS " " wW-OS "-" wH-OS " " OS "-" wH-OS " " OS "-" OS,"GUI4Border")
}Else{
myGui.Hide()
Return
}
}