
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:
- Es funktioniert nicht, wenn es maximiert ist oder wenn das Fenster an einer Seite ausgerichtet ist.
- Die Grenze ist nicht gleichmäßig
Ich habe einige Bilder angehängt, die das Problem zeigen:
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, WinSet
die 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
}
}