AutoHotkey
Gebruik functies in plaats van labels
Zoeken…
Opmerkingen
AutoHotkey was tot voor kort afhankelijk van labels tot versie 1.1.20. De afhankelijkheid van labels had zeer ernstige nadelen. De belangrijkste is dat labels meestal worden uitgevoerd in het globale bereik, wat betekent dat elke variabele die binnen een label wordt gedefinieerd, wereldwijd beschikbaar zal zijn. Dit klinkt geweldig totdat je je realiseert dat je bijvoorbeeld niet zomaar andere volksbibliotheken kunt gebruiken zonder ervoor te zorgen dat hun variabelen de jouwe niet verstoren.
Wereldwijd werken wanneer dat niet nodig is, is gewoon een slechte gewoonte.
Dus dit is waar functies binnenkomen. Vanaf versie 1.1.20 accepteert elke AutoHotkey-opdracht die een labelnaam als parameter accepteert, nu ook een functienaam.
Zeer eenvoudig voorbeeld dat het gebruik van de functie op SetTimer demonstreert.
;Sends the keystroke for the letter "a" every 3 seconds.
#Persistent
SetTimer, SendLetterA, 3000
return
SendLetterA() {
Send, a
}
Geavanceerd gebruik van SetTimer: dezelfde functie oproepen met verschillende parameters
Dit is een voorbeeld van iets dat met labels meteen onmogelijk zou zijn geweest. Als u hetzelfde label meerdere keren tegelijkertijd uitvoert en ze vertrouwen op variabelen die erin worden gedefinieerd, interfereren ze zeer waarschijnlijk en veroorzaken ze onverwacht gedrag.
Hier is hoe het te doen met functies:
; 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%
}
Hier is hoe het niet te doen (met labels):
;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 met functies in plaats van labels
Voorbeeld waarin wordt getoond hoe Guis wordt gemaakt met behulp van functies in plaats van 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
}
Sneltoetsen met functies in plaats van labels
Voorbeelden van het gebruik van functies met sneltoetsen:
Hotkey, a, MyFunction ; Calls MyFunction() when a is pressed
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
Of:
a::MyFunction()
MyFunction() {
MsgBox You pressed %A_ThisHotkey%.
}
Lade menu acties met functies
#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
}
Algemeen voorbeeld van functies versus labels
Ik zal het basisgebruik van het gebruik van functies versus het gebruik van labels + gosub demonstreren.
In dit voorbeeld implementeren we eenvoudige functionaliteit om twee nummers toe te voegen en op te slaan in een variabele.
Met functies:
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"
}
Met labels (doe dat alstublieft niet):
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
OnClipboardVeranderen met functie / label
De volgende code is afkomstig uit de officiële AutoHotkey-documentatie:
Functie implementatie:
#Persistent
OnClipboardChange("ClipChanged")
return
ClipChanged(Type) {
ToolTip Clipboard data type: %Type%
Sleep 1000
ToolTip ; Turn off the tip.
}
Label implementatie:
#Persistent
return
OnClipboardChange:
ToolTip Clipboard data type: %A_EventInfo%
Sleep 1000
ToolTip ; Turn off the tip.
return
Meer gecompliceerd Gui-voorbeeld met meerdere lijstweergaven met dezelfde callback-functie voor gebeurtenissen
Dit script laat zien hoe gecompliceerde GUI-gebeurtenissen van verschillende besturingselementen in dezelfde terugbelfunctie voor gebeurtenissen kunnen worden ontvangen. We zullen daarvoor twee ListView-besturingselementen gebruiken.
Nu elke keer dat een actie wordt gedetecteerd op een van die ListView-besturingselementen, willen we een precieze beschrijving van wat er is gebeurd en hebben die zich aangemeld bij een bewerkingsbesturingselement in dezelfde GUI.
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
}