AutoHotkey
Verwenden Sie Funktionen anstelle von Etiketten
Suche…
Bemerkungen
AutoHotkey verwendete bis zu Version 1.1.20 stark Etiketten. Das Vertrauen in Labels hatte sehr gravierende Nachteile. Die Hauptsache ist, dass Labels normalerweise im globalen Bereich ausgeführt werden, was bedeutet, dass alle Variablen, die in einem Label definiert sind, global verfügbar sind. Das klingt großartig, bis Sie feststellen, dass Sie zum Beispiel nicht nur die Bibliotheken anderer Personen verwenden können, ohne sich zu vergewissern, dass ihre Variablen Ihre Variablen nicht beeinträchtigen.
Im globalen Bereich zu arbeiten, wenn es nicht notwendig ist, ist einfach schlechte Praxis.
Hier kommen also Funktionen zum Einsatz. Ab Version 1.1.20 akzeptiert jeder AutoHotkey-Befehl, der einen Labelnamen als Parameter akzeptiert, jetzt alternativ einen Funktionsnamen.
Ein sehr einfaches Beispiel, das die Verwendung von Funktionen auf SetTimer veranschaulicht.
;Sends the keystroke for the letter "a" every 3 seconds.
#Persistent
SetTimer, SendLetterA, 3000
return
SendLetterA() {
Send, a
}
Erweiterte Verwendung von SetTimer: Gleiche Funktion mit verschiedenen Parametern aufrufen
Dies ist ein Beispiel für etwas, das mit Etiketten nicht möglich gewesen wäre. Wenn Sie dasselbe Label mehrmals gleichzeitig ausführen und auf Variablen angewiesen sind, die in ihnen definiert werden, kann dies zu Interferenzen führen und unerwartetes Verhalten verursachen.
So machen Sie es mit Funktionen:
; This script will switch between showing "Hello 1" and "Hello 2"
#Persistent
DisplayMessage_Hello1 := Func("DisplayMessage").bind("Hello 1")
SetTimer, %DisplayMessage_Hello1%, 2000
Sleep, 1000
DisplayMessage_Hello2 := Func("DisplayMessage").bind("Hello 2")
SetTimer, %DisplayMessage_Hello2%, 2000
DisplayMessage(messageToDisplay) {
TrayTip ; remove other traytips
TrayTip, Message to display:, %messageToDisplay%
}
So machen Sie es nicht (mit Etiketten):
;This script will never display the message "Hello 1". It will always show "Hello 2".
#Persistent
messageToDisplay := "Hello 1"
SetTimer, DisplayMessage, 2000
Sleep, 1000
messageToDisplay := "Hello 2"
SetTimer, DisplayMessage, 2000
DisplayMessage:
TrayTip ; remove other traytips
TrayTip, Message to display:, %messageToDisplay%
Return
Gui mit Funktionen anstelle von Labels
Beispiel zum Erstellen von Guis mit Funktionen anstelle von Labels.
Gui, Add, Button, gCtrlEvent vButton1, Button 1
Gui, Add, Button, gCtrlEvent vButton2, Button 2
Gui, Add, Button, gGoButton, Go Button
Gui, Add, Edit, vEditField, Example text
Gui, Show,, Functions instead of labels
CtrlEvent(CtrlHwnd:=0, GuiEvent:="", EventInfo:="", ErrLvl:="") {
GuiControlGet, controlName, Name, %CtrlHwnd%
MsgBox, %controlName% has been clicked!
}
GoButton(CtrlHwnd:=0, GuiEvent:="", EventInfo:="", ErrLvl:="") {
GuiControlGet, EditField
MsgBox, Go has been clicked! The content of the edit field is "%EditField%"!
}
GuiClose(hWnd) {
WinGetTitle, windowTitle, ahk_id %hWnd%
MsgBox, The Gui with title "%windowTitle%" has been closed!
ExitApp
}
Hotkeys mit Funktionen statt Beschriftungen
Beispiele für die Verwendung von Funktionen mit Hotkeys:
Hotkey, a, MyFunction ; Calls MyFunction() when a is pressed
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
Oder:
a::MyFunction()
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
Aktionen im Tablettmenü mit Funktionen
#Persistent
Menu, Tray, NoStandard ; remove default tray menu entries
Menu, Tray, Add, MyDefaultAction, OnDefaultTrayAction ; add a new tray menu entry
Menu, Tray, Add, Exit, Exit ; add another tray menu entry
Menu, Tray, Default, MyDefaultAction ;When doubleclicking the tray icon, run the tray menu entry called "MyDefaultAction".
OnDefaultTrayAction() {
MsgBox, You double clicked the tray icon of this script or you clicked the MyDefaultAction entry!
}
Exit() {
MsgBox, You clicked the Exit entry! The script will close itself now.
ExitApp
}
Allgemeines Beispiel für Funktionen vs. Labels
Ich werde die grundlegende Verwendung von Funktionen und von Labels + Gosub demonstrieren.
In diesem Beispiel implementieren wir eine einfache Funktionalität, um zwei Zahlen hinzuzufügen und in einer Variablen zu speichern.
Mit Funktionen:
c := Add(3, 2) ; function call
MsgBox, Result: %c%
Add(a, b) { ; This is a function. Put it wherever you want, it doesn't matter.
; the a and b inside of this function are set by the function call above
Return a+b ; the function will return the result of the expression "a+b"
}
Mit Etiketten (bitte mach das nicht):
a := 3
b := 2
GoSub, Add ; execute the label "Add" then jump back to the next line here
MsgBox, Result: %c%
Return ; without this, the label would be executed again for no reason.
Add: ; This is a label. Please put them at the bottom of your script and use "Return" in a line above.
c := a+b
Return
OnClipboardChange mit Funktion / Label
Der folgende Code stammt aus der offiziellen AutoHotkey-Dokumentation:
Funktionsimplementierung:
#Persistent
OnClipboardChange("ClipChanged")
return
ClipChanged(Type) {
ToolTip Clipboard data type: %Type%
Sleep 1000
ToolTip ; Turn off the tip.
}
Label-Implementierung:
#Persistent
return
OnClipboardChange:
ToolTip Clipboard data type: %A_EventInfo%
Sleep 1000
ToolTip ; Turn off the tip.
return
Kompliziertes Gui-Beispiel mit mehreren Listenansichten, die dieselbe Ereignisrückruffunktion verwenden
Dieses Skript veranschaulicht, wie komplizierte GUI-Ereignisse von verschiedenen Steuerelementen in derselben Ereignisrückruffunktion empfangen werden. Wir werden dafür zwei ListView-Steuerelemente verwenden.
Jedes Mal, wenn eine Aktion in einem dieser ListView-Steuerelemente erkannt wird, möchten wir eine genaue Beschreibung der Vorgänge und müssen diese in einem Bearbeitungssteuerelement in derselben GUI anmelden.
Gui, Add, ListView, gListCtrlEvent vMyFirstListView AltSubmit -ReadOnly R10 w310, ColumnTitle1|ColumnTitle2|ColumnTitle3
Gui, Add, ListView, gListCtrlEvent vMySecondListView AltSubmit -ReadOnly R10 w310, ColumnTitle1|ColumnTitle2|ColumnTitle3
Gui, Add, Text, w310, Action Log
Gui, Add, Edit, vLog R7 w310,
Gui, Show,, Functions instead of labels
; Create example entries for the first ListView
Gui, ListView, MyFirstListView
Loop, 10 {
LV_Add("", "Column-1 | Row-" A_Index , "Column-2 | Row-" A_Index, "Column-3 | Row-" A_Index)
}
LV_ModifyCol()
; Create example entries for the second ListView
Gui, ListView, MySecondListView
Loop, 10 {
LV_Add("", "Column-1 | Row-" A_Index , "Column-2 | Row-" A_Index, "Column-3 | Row-" A_Index)
}
LV_ModifyCol()
ListCtrlEvent(ctrlHwnd:=0, guiEvent:="", eventInfo:="", errLvl:="") {
GuiControlGet, ctrlName, Name, %CtrlHwnd%
whatHappened := "Action detected!`n"
whatHappened .= "Control handle: " ctrlHwnd "`n"
whatHappened .= "Control name: " ctrlName "`n"
If (guiEvent = "DoubleClick") {
whatHappened .= "`nThe user has double-clicked within the control."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "R") {
whatHappened .= "`nThe user has double-right-clicked within the control."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "ColClick") {
whatHappened .= "`nThe user has clicked a column header."
whatHappened .= "`n> Column number: " eventInfo
} Else If (guiEvent = "D") {
whatHappened .= "`nThe user has attempted to start dragging a row or icon."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "d") {
whatHappened .= "`nThe user has attempted to start right-click-dragging a row or icon."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "e") {
whatHappened .= "`nThe user has finished editing the first field of a row."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "Normal") {
whatHappened .= "`nThe user has left-clicked a row."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "RightClick") {
whatHappened .= "`nThe user has right-clicked a row."
whatHappened .= "`n> Focused row number: " eventInfo
} Else If (guiEvent = "A") {
whatHappened .= "`nA row has been activated."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "C") {
whatHappened .= "`nThe ListView has released mouse capture."
} Else If (guiEvent = "E") {
whatHappened .= "`nThe user has begun editing the first field of a row."
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "F") {
whatHappened .= "`nThe ListView has received keyboard focus."
} Else If (guiEvent = "f") {
whatHappened .= "`nThe ListView has lost keyboard focus."
} Else If (guiEvent = "I") {
whatHappened .= "`nItem changed. (A row has changed by becoming selected/deselected, checked/unchecked, etc.)"
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "K") {
whatHappened .= "`nThe user has pressed a key while the ListView has focus."
whatHappened .= "`n> Key pressed: " GetKeyName(Format("vk{:x}", eventInfo))
} Else If (guiEvent = "M") {
whatHappened .= "`nItem changed. (A row has changed by becoming selected/deselected, checked/unchecked, etc.)"
whatHappened .= "`n> Row number: " eventInfo
} Else If (guiEvent = "S") {
whatHappened .= "`nMarquee. The user has started to drag a selection-rectangle around a group of rows or icons."
} Else If (guiEvent = "s") {
whatHappened .= "`nThe user has finished scrolling the ListView."
}
GuiControlGet, Log
GuiControl,, Log, % whatHappened "`n---------------------`n" Log
}
GuiClose(hWnd) {
WinGetTitle, windowTitle, ahk_id %hWnd%
MsgBox, The Gui with title "%windowTitle%" is going to be closed! This script will exit afterwards!
ExitApp
}