Beispielsweise wurden in Visual Studio Express 2013 viele der Formatierungsverknüpfungen in Ctrl+ „eingebettet“ E. Um eine Auswahl zu kommentieren, muss man gedrückt halten Ctrl, drücken E, drücken C,Dannfreigeben Ctrl.
Wäre ichVersendungSolche Eingaben würde ich schreiben
SendInput {Ctrl Down}ec{Ctrl Up}
Aber wie mache ich aus dieser Sequenz einen Hotkey? Ich habe es versucht
{Ctrl Down}EC{Ctrl Up}::
MsgBox, "Hello, world!"
Return
aber das verursacht natürlich einen Syntaxfehler:
Antwort1
Endlich herausgefunden.
tl;dr
Ersetzen Sie ^e
durch den ersten gewünschten Tastendruck. Ersetzen Sie 3
durch den ASCII-Index des zweiten gewünschten Tastendrucks. Dies erzwingt, dass die Taste Ctrlwährend beider Tastendrücke gedrückt gehalten wird, andernfalls wird der Vorgang abgebrochen.
~$Ctrl UP::
ChordIsBroken := True
Return
^e::
ChordIsBroken := False
Input, OutputVar, L1 M
If (!ChordIsBroken && Asc(OutputVar) = 3)
{
MsgBox "Hello, World!"
}
Else
{
SendInput %OutputVar%
}
Return
ShiftUm dies auf anstelle von anzupassen Ctrl, müssten Sie das Ctrl
s ersetzen, das entfernen M
und einen einfacheren Vergleich wie OutputVar = C
anstelle von durchführen. Ich bin nicht sicher, wie ich dies auf und Asc(OutputVar) = 3
erweitern kann , aber vielleicht müssen Sie es versuchen oder so etwas in der Art.Alt
Win
L2
Erläuterung
Input
schien ein naheliegender Ausgangspunkt zu sein. Input
fordert AHK auf, auf Benutzereingaben zu warten,z.B
^e::
Input, OutputVar, L1 ; "L1" means wait for 1 keystroke then continue.
If (OutputVar = "c")
{
MsgBox, "Hello, World!"
}
Return
Das Meldungsfeld oben wird CtrlEdann ausgelöst C. Aber wir suchen nach CtrlC, also beheben wir das:
^e::
Input, OutputVar, L1 M ; "M" allows storage of modified keystrokes (^c).
If (Asc(OutputVar) = 3) ; ASCII character 3 is ^c.
{
MsgBox "Hello, World!"
}
Return
Jetzt haben wir ein Meldungsfenster, wenn wir CtrlEdann drücken CtrlC. Aber es gibt ein Problem damit: Das Meldungsfenster wird ausgelöst, auch wenn ichfreigeben Ctrlzwischen den beiden Tastenanschlägen. Wie erkennen wir also im Wesentlichen eine {Ctrl Up}
Eingabe in der Mitte? Sie können nicht einfach beim Eingeben prüfen –
^e::
if (!GetKeyState("Ctrl"))
{
Return
}
Input, OutputVar, L1 M
; ...
—auch können Sie nicht einfach nach der Eingabe prüfen—
^e::
Input, OutputVar, L1 M
if (!GetKeyState("Ctrl"))
{
Return
}
; ...
– und Sie können nicht einmal mit beidem durchkommen, denn egal, was Sie tun, Sie werden die {Ctrl Up}
„while“-Blockierung für die Eingabe verpassen.
Dann schaute ich inDokumentation überHotkey
zur Inspiration. Der benutzerdefinierte Kombinationsoperator, &
, schien vielversprechend. Aber leider
^e & ^c::
; ...
hat einen Kompilierungsfehler verursacht; anscheinend &
dient das zum Kombinierenunverändertnur Tastenanschläge.
Schließlich war es soweit UP
, und dort gelang mir endlich der Durchbruch. Ich habe Ctrl's neu definiert UP
, um einenUmschaltenDadurch wird die Auslösung des Meldungsfelds verhindert!
$Ctrl::Send {Ctrl Down} ; The $ prevents an infinite loop. Although this
$Ctrl UP:: ; line seems redundant, it is in fact necessary.
ChordIsBroken := True ; Without it, Ctrl becomes effectively disabled.
Send {Ctrl Up}
Return
^e::
ChordIsBroken := False
Input, OutputVar, L1 M
If (!ChordIsBroken && Asc(OutputVar) = 3)
{
MsgBox "Hello, World!"
}
Return
Wenn ich jetzt drücke CtrlE, dann loslasse Ctrlund wieder drücke CtrlC, passiert wie erwartet nichts!
Es gab noch eine letzte Sache zu beheben. Bei „Abbruch“ (ein „gebrochener Akkord“) wollte ich, dass alle Tastenanschläge wieder normal sind. Aber im obigen Code Input
müsste ein Tastenanschlag „aufgebraucht“ werden, bevor er zurückkehrt, unabhängig davon, ob es sich um einen gebrochenen Akkord oder einen irrelevanten sekundären Tastenanschlag handelt. Das Hinzufügen eines Else
Falls löst dieses Problem auf schöne Weise:
Else
{
SendInput %OutputVar%
}
So, da haben Sie es – „Akkorde“ in AutoHotkey. (Obwohl ich das nicht gerade als „Akkord“ bezeichnen würde. Eher alsMelodie, mit Basslinie ;-)
@hippibruder weist großzügig darauf hin, dass ich die Definition vermeiden kann, $Ctrl::
indem ich verwende ~
, um nicht blockierend zu machen $Ctrl UP::
. Dies ermöglicht eine gewisse Vereinfachung! (Das Endergebnis finden Sie im Abschnitt tl;dr oben.)
Und noch etwas. Wenn Sie vielleicht bei einer "Stornierung" (einem "gebrochenen Akkord") den ersten Tastendruck ausführen möchten,dh CtrlEallein, fügen Sie das einfach in den Else
Block ein,
Else
{
SendInput ^e
SendInput %OutputVar%
}
und vergessen Sie nicht, den Hotkey zu ändern in
$^e::
um eine Endlosschleife zu vermeiden.
Antwort2
Ich glaube nicht, dass es in AHK integrierte Unterstützung für Tastenklänge gibt. Eine Möglichkeit, diese zu erkennen, wäre, einen Hotkey für die erste Taste im Akkord (^e) zu registrieren und dann den Input-Befehl zu verwenden, um die nächsten Tasten zu erkennen.
; Tested with AHK_L U64 v1.1.14.03 (and Visual Studio 2010)
; This doesn't block the input. To block it remove '~' from the hotkey and 'V' from Input-Cmd
~^e::
; Input-Cmd will capture the next keyinput as its printable representation.
; (i.e. 'Shift-a' produces 'A'. 'a' produces 'a'. 'Ctrl-k' produces nothing printable. This can be changed with 'M' option. Maybe better approch; See help)
; Only the next, because of 'L1'. (Quick-Fail; Not necessary)
; To detect 'c' and 'u' with control pressed I used them as EndKeys.
; If a EndKey is pressed the Input-Cmd will end and save the EndKey in 'ErrorLevel'.
Input, _notInUse, V L1 T3, cu
; Return if Input-Cmd was not terminated by an EndKey
; or 'Control' is no longer pressed. (It would be better if Input-Cmd would be also terminated by a {Ctrl Up}. I don't know if that is possible)
if ( InStr(ErrorLevel, "Endkey:") != 1
|| !GetKeyState("Control") )
{
return
}
; Extract the EndKey-Name from 'ErrorLevel' (ErrorLevel == "Endkey:c")
key := SubStr(ErrorLevel, 8)
if ( InStr(key, "c") == 1 )
{
TrayTip,, ^ec
}
else if ( InStr(key, "u") == 1 )
{
TrayTip,, ^eu
}
else
{
MsgBox, wut? key="%key%"
}
return