Bsp. 2 : Tastaturlayout (bei Laptops) anpassen (extended version)
Aber: Der obige Code soll natürlich nur dann laufen, wenn ich auch direkt an dieser Laptop-Tastatur sitze. Die meiste Zeit arbeite ich mit einer externen Tastatur, d.h. da wäre dieser Tasten-Tausch hinderlich. Es wäre gut, das Skript würde nun erkennen, an welcher Tastatur ich sitze.
Gelöst habe ich das dadurch, dass ich eine Tastenkombination definiert habe, die das Script selbst neu läd. Beim Laden wird dann geschaut, ob meine externe Tastatur erkannt wird oder nicht, und abhängig davon wird das obige Tasten-Remapping gemacht oder eben nicht.
Ich will darauf gar nicht im Detail eingehen, sondern zeige den Code vor allem deshalb, um die Mächtigkeit von AutoHotkey zu demonstrieren:
; --- Konfiguration ---
MyExternalKeyboardId := "b35b_REV"
global ExternalKeyboardBool := false
; --- Initialisierung ---
try {
o := HidListObj()
; Checken, ob ein Keyboard-Name den String enthält
for keyboard in o.Keyboard {
if InStr(keyboard.Name, MyExternalKeyboardId) {
global ExternalKeyboardBool := true
break
}
}
} catch {
MsgBox("Fehler beim Auslesen der Hardware-Liste.", "Fehler", 16)
}
; --- Benutzerbestätigung ---
MsgTitle := "AutoHotkey gestartet"
MsgText := ExternalKeyboardBool ? "Externes Keyboard gefunden!`n`nPasst das?" :
"KEIN externes Keyboard gefunden...`n`nPasst das?"
Result := MsgBox(MsgText, MsgTitle, 32 + 4) ; Icon Frage + Ja/No
if (Result = "No") {
global ExternalKeyboardBool := !ExternalKeyboardBool
MsgBox("OK, Einstellung geändert...", "Keyboard geändert", "Iconi T1")
}
; --- Hotkeys ---
; Skript neu laden
^!r:: Reload()
; Die Direktive #HotIf sorgt dafür, dass die Hotkeys NUR dann aktiv sind,
; wenn die Bedingung (KEIN externes Keyboard) erfüllt ist.
; Das spart die manuellen Checks in jedem Hotkey.
#HotIf !ExternalKeyboardBool
PgUp::Home
PgDn::End
Home::PgUp
End::PgDn
+PgUp::+Home
+PgDn::+End
+Home::+PgUp
+End::+PgDn
; Backspace Fix für defekte Taste
$BackSpace:: {
Send("{BackSpace Down}")
Sleep(70)
Send("{BackSpace Up}")
}
; Globaler Ersatz für Backspace
PrintScreen::BackSpace
#HotIf
/************************************************************************
* FUNKTIONEN
************************************************************************/
/**
* Erstellt ein Objekt mit allen HID-Geräten
* Basiert auf: https://www.autohotkey.com/boards/viewtopic.php?p=58347#p58347
*/
HidListObj() {
F := { Mouse: [], Keyboard: [], HID: [] }
B := Map(0, "Mouse", 1, "Keyboard", 2, "HID")
iCount := 0
; Erste Abfrage für die Anzahl der Geräte
DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", &iCount, "UInt", A_PtrSize * 2)
if (iCount = 0)
return F
uHIDList := Buffer(iCount * (A_PtrSize * 2))
DllCall("GetRawInputDeviceList", "Ptr", uHIDList, "UInt*", &iCount, "UInt", A_PtrSize * 2)
loop iCount {
offset := (A_Index - 1) * (A_PtrSize * 2)
hDevice := NumGet(uHIDList, offset, "Ptr")
Type := NumGet(uHIDList, offset + A_PtrSize, "UInt")
TypeName := B.Has(Type) ? B[Type] : "HID"
deviceInfo := {}
deviceInfo.Handle := hDevice
; Gerätename abrufen
iLength := 0
DllCall("GetRawInputDeviceInfo", "Ptr", hDevice, "UInt", 0x20000007, "Ptr", 0, "UInt*", &iLength)
if (iLength > 0) {
nameBuf := Buffer((iLength + 1) * 2)
DllCall("GetRawInputDeviceInfo", "Ptr", hDevice, "UInt", 0x20000007, "Ptr", nameBuf, "UInt*", &iLength)
deviceInfo.Name := StrGet(nameBuf)
}
; Geräteinfo abrufen
iLength := 0
DllCall("GetRawInputDeviceInfo", "Ptr", hDevice, "UInt", 0x2000000b, "Ptr", 0, "UInt*", &iLength)
if (iLength > 0) {
uInfo := Buffer(iLength)
NumPut("UInt", iLength, uInfo)
DllCall("GetRawInputDeviceInfo", "Ptr", hDevice, "UInt", 0x2000000b, "Ptr", uInfo, "UInt*", &iLength)
if (Type = 0) { ; Mouse
deviceInfo.ID := NumGet(uInfo, 8, "UInt")
deviceInfo.Buttons := NumGet(uInfo, 12, "UInt")
} else if (Type = 1) { ; Keyboard
deviceInfo.KBType := NumGet(uInfo, 8, "UInt")
deviceInfo.KeysTotal := NumGet(uInfo, 28, "UInt")
} else if (Type = 2) { ; HID
deviceInfo.VendorID := NumGet(uInfo, 8, "UInt")
deviceInfo.ProductID := NumGet(uInfo, 12, "UInt")
}
}
F.%TypeName%.Push(deviceInfo)
}
return F
}
Bsp. 3: Defekte Taste “reparieren”
Im Lauf der Jahre hat die Backspace-Taste meiner Laptop-Tastatur etwas gelitten. Sie hat angefangen, nicht nur ein einziges Zeichen zu löschen, wenn man sie drückt, sondern sie hat mehrfach ausgelöst. Durch ein “Debouncing” hat sich das leicht reparieren lassen:
; Backspace Fix für defekte Taste:
$BackSpace:: {
Send("{BackSpace Down}")
Sleep(70)
Send("{BackSpace Up}")
}
Was hier passiert: Beim Drücken der Backspace-Taste wird zunächst das Herunterdrücken der Taste gesendet, dann wird für 70ms gewartet, und danach wird das Loslassen der Taste gesendet. Das hat geholfen, um das Problem zu beheben. Definitiv günstiger als eine neue Tastatur.
Eine Alternative wäre, einfach statt der Backspace-Taste eine andere Taste zu verwenden, z.B. die “Druck”- bzw. “Print”-Taste, die bei meinem Laptop praktischerweise direkt darüber liegt:
PrintScreen::BackSpace
Bsp. 4: Steuern von Heimautomation
Wenn du Dinge in deinem Zuhause automatisiert hast und dafür z.B. MQTT nutzt, dann könnte so etwas interessant sein. Du installierst dir lokal Mosquitto und kannst dann ganz einfach per AutoHotkey und Tastenkombinationen bestimmte Aktionen auslösen. Das könnte z.B. so aussehen, um eine Lampe ein- und auszuschalten:
^!l:: ; Strg+Alt+L
{
RunWait '"C:\Tools\mosquitto\mosquitto_pub.exe"'
. ' -h 192.168.1.10'
. ' -p 1883'
. ' -u "deinUser"'
. ' -P "deinPasswort"'
. ' -t "home/schreibtisch/licht"'
. ' -m "TOGGLE"'
, , "Hide"
}
Bsp. 4: AutoHotkey selbst automatisieren
Bei mir sind die AutoHotkey-Sachen in zwei Skripte aufgeteilt. Jedes davon muss beim Systemstart gestartet werden. Das macht AutoHotkey nicht von sich aus, man muss da selbst eine Autostart-Verknüpfung anlegen. Das meinte ich oben damit, dass die Benutzung etwas holprig ist.
Wenn man diesen Code oben in jedes Skript packt spart man sich das. Denn der Code erzeugt automatisch einen Autostart-Link zu dem jeweiligen Skript, wenn noch keiner vorhanden ist:
; --- Autostart-Verknüpfung erstellen ---
; Erstellt automatisch eine Verknüpfung im Autostart-Ordner für das aktuelle Skript
A_StartupShortcut := A_Startup "\" StrReplace(A_ScriptName, ".ahk", ".lnk")
if !FileExist(A_StartupShortcut) {
FileCreateShortcut(A_ScriptFullPath, A_StartupShortcut)
MsgBox("Autostart-Verknüpfung für " A_ScriptName " wurde erstellt!", "Autostart", "Iconi")
}
So, das waren ein paar Anwendungsideen für AutoHotkey von mir. Vielleicht inspiriert es dich ja, auch bei dir ein paar Arbeitsabläufe eleganter zu lösen und auf dem Weg dahin noch ein bisschen Spaß beim Basteln mit Code zu haben.
Keine Ahnung, warum ich das mit dem "Bloggen"* jetzt wieder angefangen habe, aber irgendwie muss es.
*Die Anführungszeichen müssen sein, denn ich das ist egtl. ein zu großes Wort dafür.
#blog #bloggen #wordpress
Remote-Antwort
Ursprüngliche Kommentar-URL
Dein Profil
Warum muss ich mein Profil eingeben?
Diese Website ist Teil des ⁂ Open Social Web, einem Netzwerk miteinander verbundener sozialer Plattformen (wie beispielsweise Mastodon, Pixelfed, Friendica und andere). Im Gegensatz zu zentralisierten sozialen Medien befindet sich dein Profil auf einer Plattform deiner Wahl, und du kannst mit Menschen auf verschiedenen Plattformen interagieren.
Wenn du dein Profil eingibst, können wir an dein Profil senden, wo du diese Aktion abschließen kannst.