Optimieren Sie diesen roten Rahmen um das aktive Fenster AHK-Skript

Optimieren Sie diesen roten Rahmen um das aktive Fenster AHK-Skript

Ich bin ein Autohotkey-Neuling, habe aber dieses nützliche Skript gefunden, um einen roten Rahmen um mein aktives Fenster zu setzen, damit es besser auffällt. Ich habe Autohotkey installiert und das Skript ausgeführt, habe jedoch zwei Probleme:

  1. Es funktioniert nicht, wenn es maximiert ist oder wenn das Fenster an einer Seite ausgerichtet ist.
  2. Die Grenze ist nicht gleichmäßig

Ich habe einige Bilder angehängt, die das Problem zeigen:Bild zeigt Probleme

Ich wäre dankbar, wenn mir jemand helfen und dieses Skript reparieren oder detaillierte Anweisungen zur Reparatur geben könnte (denken Sie bitte daran, dass ich ein Neuling bin).

#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

Antwort1

Ich würde empfehlen, die Variablen umzubenennen, damit sie Sinn ergeben. Die Anweisung zeichnet zwei Kästchen in Paaren von x/y-Koordinaten, daher ist es weniger verwirrend, WinSetdie Variablen in x/y-Koordinatenpaaren zu benennen und sie vor der Anweisung zuzuweisenWinSet

In diesem speziellen Beispiel zeichnen Sie auch den Rahmen um die Außenseite des Fensters. Wenn sich die Außenseite des Fensters am Bildschirmrand befindet, ist der Rahmen außerhalb des Bildschirms und daher nicht sichtbar. Wenn Sie ihn auf dem Bildschirm zeichnen möchten, während sich der Rahmen am (oder sogar außerhalb des) Bildschirmrands befindet, müssen Sie den Rahmen innerhalb (oder teilweise innerhalb) der Fenstergrenze zeichnen, anstatt ihn außerhalb der Fenstergrenze zu zeichnen.

Dies ist jedoch nur eine Teillösung, da das Fenster im maximierten Zustand noch weiter vom Bildschirm entfernt ist als nur an den Rändern. In diesem Fall müssen Sie einen maximierten Zustand erkennen und den Rand um eine bestimmte Anzahl von Pixeln noch weiter verschieben, als dies normalerweise der Fall wäre.

Ich habe die Variablen umbenannt und Ihren Code optimiert, um ein Beispiel zu geben. Sie können den unterschiedlichen „Rahmentyp“ ändern, um die Auswirkungen zu sehen ... der Rest ist nur Mathematik, wenn Sie ihn anders zeichnen möchten.

#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

Nur zur Information: Es gibt auch Möglichkeiten, die Windows-Callback-Ereignisse für Fensterbewegungsereignisse zu verknüpfen, sodass Sie keinen 50-ms-Timer verwenden müssen, der ständig aktualisiert wird. In diesem Fall würde es nur aktualisiert, wenn sich das Fenster bewegt, und der Timer bringt sichtbare Verzögerungen und Verarbeitungsaufwand mit sich. Aber der Timer ist bei weitem die einfachere Lösung, die von Anfang an implementiert werden kann (wie Sie es bereits getan haben), und in vielen Fällen lohnt sich die zusätzliche Komplexität nicht wirklich, die Fensterereignisse zu verknüpfen, wenn Sie dies nicht benötigen. Ich möchte Sie nur wissen lassen, dass dies möglich ist.

Antwort2

Anstatt Ihr Skript zu korrigieren, nehmen Sie diesen Code, der genau das tut, was Sie wollen.

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

verwandte Informationen