Тонкая настройка этой красной рамки вокруг активного окна AHK-скрипта

Тонкая настройка этой красной рамки вокруг активного окна AHK-скрипта

Я новичок в autohotkey, но я нашел этот полезный скрипт для установки красной рамки вокруг моего активного окна, делая его более заметным. Я установил autohotkey и запустил скрипт, однако у меня есть две проблемы:

  1. Не работает ни при развернутом, ни при прижатом к одной стороне окне.
  2. Граница не ровная

Я прикрепил несколько фотографий, демонстрирующих проблему:picutre показывает проблемы

Если кто-то может помочь и исправить этот скрипт или предоставить подробные инструкции по его исправлению (имейте в виду, что я новичок), я буду признателен.

#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
  }
}

Связанный контент