Obwohl viele Skripte, die für AutoHotkey v1.0 geschrieben wurden, für AutoHotkey v1.1 nicht geändert werden müssen, kann es vorkommen, dass einige Skripte nicht richtig funktionieren, weil beide Versionen notwendige Unterschiede aufweisen. Die meisten Benutzer müssen sich keine Sorgen machen, da die problematischen Unterschiede nur erweiterte Funktionalitäten wie DllCall() betreffen.
AutoHotkey v1.1 ist auch unter den Namen "AutoHotkey_L" bekannt. AutoHotkey v1.0 trägt seit einiger Zeit den Namen "AutoHotkey Basic". Es gibt einige ältere Versionen von AutoHotkey_L, die eine Versionsnummer im Format 1.0.* haben, daher verwendet dieses Dokument die Namen der beiden AutoHotkey-Zweige, um Missverständnissen vorzubeugen.
Hinweis: Einige der am häufigsten auftretenden Probleme sind auf Änderungen bzgl. der Unterstützung von Unicode-Text zurückzuführen. Mit der ANSI-Version von AutoHotkey_L können solche Probleme umgangen werden.
Hohe Auswirkung:
Mittlere Auswirkung:
x & y::
bewirkt, dass x::
und x up::
ausgelöst werden, sobald x losgelassen wirdGeringe Auswirkung:
Bestimmte Syntaxfehler, die bei AutoHotkey Basic toleriert wurden, sind bei AutoHotkey_L nicht mehr erlaubt. Viele dieser Fehler können leicht korrigiert werden, sobald sie entdeckt werden. In AutoHotkey_L werden die folgenden Fehler sofort nach dem Start eines Skripts erkannt - solche Fehler müssen korrigiert werden, damit das Skript lauffähig ist:
MsgBox< foo
und If!foo
keine gültigen Angaben.Hotkey, IfIrgendetwas
, wobei Irgendetwas ungültig ist, wird nicht toleriert.Einige Syntaxfehler werden während der Skriptausführung erkannt. Das Skript wird eine Fehlermeldung anzeigen, bevor es den aktuellen Thread verlässt:
Andere Syntaxfehler werden aktuell nicht erkannt, aber verursachen Probleme mit AutoHotkey_L:
(
ist selektiver, damit einige ungültige Ausdrücke wie 12(34)
nicht mehr funktionieren.In bestimmten Fällen übersetzt FileRead den Text in eine andere Codepage und kann daher fehlerhafte Binärdaten ausgeben. Um das zu verhindern, fügen Sie die *c
-Option hinzu oder nutzen Sie stattdessen FileOpen().
Die Zeichen [
, ]
und ?
sind für die Nutzung in Ausdrücken reserviert und daher nicht mehr in Variablennamen gültig. Folglich benötigt ?
(das in ternären Operationen benutzt wird) kein Leerzeichen mehr auf beiden Seiten. Siehe auch Objektsyntax.
Fehler werden oder werden nicht automatisch erkannt:
Array%n%
, wobei n eines der oben genannten Zeichen enthält), wird bei der Auswertung der Doppeldereferenz während der Skriptausführung eine Fehlermeldung angezeigt.Die DPI-Skalierung ist standardmäßig für Skript-GUIs aktiviert, um sicherzustellen, dass sie gemäß den systeminternen DPI-Einstellungen skaliert werden. Wenn sie aktiviert ist und die systeminterne DPI-Einstellung ungleich 96 (100 %) ist, sind Positionen und Größen, die von Gui-Befehlen akzeptiert oder zurückgegeben werden, nicht mit anderen Befehlen kompatibel. Die DPI-Skalierung kann mit Gui -DPIScale
deaktiviert werden.
Einige Transform-Unterbefehle wurden in den Unicode-Versionen von AutoHotkey_L geändert oder deaktiviert:
Startet man AutoHotkey_L ohne Angabe eines Skripts, wird standardmäßig eine AHK-Datei anstelle einer INI-Datei geladen. Der Name dieser Datei basiert auf dem Dateinamen der aktuellen EXE-Datei. Weitere Informationen finden Sie unter Befehlszeilenparameter an ein Skript übergeben.
Verwendet man ein großes H, werden die Hexadezimalzeichen A-F auch in Großbuchstaben sein. AutoHotkey Basic verwendet hingegen immer Kleinbuchstaben. Siehe SetFormat.
Die folgenden Befehle setzen nun A_LastError, um das Debuggen zu unterstützen: FileAppend, FileRead, FileReadLine, FileDelete, FileCopy, FileMove, FileGetAttrib/Time/Size/Version, FileSetAttrib/Time, FileCreateDir, RegRead, RegWrite, RegDelete. Sobald man einen dieser Befehle benutzt, wird der vorherige Wert von A_LastError überschrieben.
Die smarte Kommabehandlung des MsgBox-Befehls wurde geändert, um ihn flexibler und konsistenter mit anderen Befehlen zu machen. In den meisten Fällen wird sich der MsgBox-Befehl wie vorgesehen verhalten. In einigen seltenen Fällen kann es vorkommen, dass sich Skripte, die noch auf das alte, sonderbare Verhalten angewiesen sind, anders als sonst verhalten werden. Zum Beispiel:
; Dies wird nun getrennt als Ausdruck (Optionen) gefolgt von Text (Titel) interpretiert, ; anstatt als einzelner Ausdruck (Text) mit mehreren Teilausdrücken: MsgBox % x, y ; Mit runden Klammern kann die alte Interpretation erzwungen werden: MsgBox % (x, y) ; Dies wird nun ein leeres Dialogfenster anzeigen, anstatt den Text "0, Titel": MsgBox 0, Titel ; Diese verhalten sich in AutoHotkey_L und AutoHotkey Basic wie erwartet: MsgBox 0, Titel, % "" ; Zeigt ein leeres Dialogfenster an MsgBox 0`, Titel ; Zeigt den Text "0, Titel" an ; Dies wird nun ein leeres Dialogfenster anzeigen, anstatt den Text ", Titel": MsgBox,, Titel
Wendet man die +Owner-Option auf eine GUI an, wird zusätzlich der WS_CHILD-Style entfernt und der WS_POPUP-Style gesetzt. Diese Änderung kann dazu führen, dass Skripte, die das übergeordnete Fenster einer GUI mit +Owner
setzen, nachdem die Styles gesetzt wurden, nicht mehr ordnungsgemäß funktionieren.
SoundSet, SoundGet, SoundSetWaveVolume und SoundGetWaveVolume werden in Windows Vista oder höher besser unterstützt. Folgende Änderungen treten dabei in Kraft:
In [v1.1.14+] beeinflusst das Tilde-Präfix das Verhalten einer Taste, die als Modifikatortaste in einer benutzerdefinierten Tastenkombination verwendet wird.
Wenn sowohl ein Taste-Unten- als auch Taste-Oben-Hotkey für eine benutzerdefinierte Modifikatortaste ohne Tilde-Präfix definiert sind, werden beide beim Loslassen der Taste ausgelöst. Zum Beispiel würde x & y::
bewirken, dass x::
und x up::
ausgelöst werden, wenn x losgelassen wird. Früher wurde x::
dabei nie ausgelöst.
If Var is [not] Typ ignoriert die Sprach- und Regionseinstellungen des Systems, es sei denn, StringCaseSense Locale wurde verwendet.
GroupActivate setzt ErrorLevel auf 1, wenn kein einziges Fenster aktiviert werden konnte, andernfalls auf 0. Früher blieb ErrorLevel unverändert.
Der Label-Parameter von GroupAdd gilt für die gesamte Fenstergruppe, nicht nur für eine bestimmte Fensterspezifikation innerhalb der Gruppe. Eine Diskussion zu dieser Änderung kann im Forum gefunden werden. Allerdings wird dieser Parameter nicht empfohlen; überprüfen Sie stattdessen ErrorLevel nach dem Aufruf von GroupActivate.
AutoHotkey_L enthält Verbesserungen hinsichtlich dessen, wie Run und RunWait ihren Ziel-Parameter interpretieren. Diese Verbesserungen bieten neue Möglichkeiten, die früher nicht möglich waren, können aber bestehende Skripte beeinträchtigen, die unter AutoHotkey Basic liefen. Das neue Verhalten äußert sich wie folgt:
Loop Read und FileReadLine interpretieren das Zeichen Strg+Z (0x1A) nicht länger als Dateiendemarke (end-of-file marker). Jedes Strg+Z wird unverändert geladen, selbst wenn es ganz am Ende einer Datei steht. FileRead ignoriert dieses Zeichen bereits und ist daher von diesem Problem nicht betroffen.
Wenn Sie im Eigenschaftsfenster der EXE-Datei, mit der das Skript ausgeführt werden soll, den Kompatibilitätsmodus auf Windows 95, NT4 oder 98/ME setzen, kann es vorkommen, dass sich das Skript je nach Inhalt falsch verhält. Das liegt daran, dass der Kompatibilitätsmodus dem Programm eine bestimmte Version von Windows meldet, die AutoHotkey_L nicht unterstützt. Setzt man bspw. den Kompatibilitätsmodus auf Windows 95 oder 98/ME, würde MsgBox %A_OSVersion%
die Version WIN_NT4
melden.
A_IsCompiled enthält eine leere Zeichenkette, wenn das Skript nicht kompiliert ist. Früher blieb sie undefiniert, wodurch Zuweisungen wie A_IsCompiled := 1
in einem unkompilierten Skript möglich waren. Nun wird sie in jedem Fall als schreibgeschützte interne Variable behandelt.
Escapezeichenversehene Leerraumzeichen wie `t
und `
werden nicht länger am Anfang oder am Ende eines Arguments verworfen. Zum Beispiel ist StringReplace s, s, `t
nun gültig und wird alle Tabulatorzeichen aus s entfernen.
Hinweis: Dieser Abschnitt baut auf Themen auf, die in anderen Teilen der Dokumentation behandelt werden: Zeichenketten (Strings), Zeichenkettenkodierung.
Innerhalb einer Zeichenkette (Textwert) ist der numerische Zeichencode und die Größe (in Bytes) jedes einzelnen Zeichens von der nativen Kodierung des Skripts und von der AutoHotkey-EXE-Datei abhängig; also Unicode oder ANSI. Solche Details sind in der Regel nur für Skripte interessant, die folgende Aktionen durchführen:
Skripte, die nur für ein bestimmtes Format gedacht waren, werden oft auf Probleme stoßen, wenn sie mit der falschen AutoHotkey-Version laufen. Zum Beispiel werden einige Skripte, die für AutoHotkey Basic geschrieben wurden, mit der ANSI-Version von AutoHotkey_L korrekt funktionieren, aber nicht mit der Unicode-Version. Mit dem folgenden Skript kann man herausfinden, welche Version gerade verwendet wird:
MsgBox % A_IsUnicode ? "Unicode" : "ANSI"
ANSI: Jedes Zeichen ist ein Byte groß (8 Bits). Zeichencodes über 127 sind von den Spracheinstellungen Ihres Systems abhängig.
Unicode: Jedes Zeichen ist zwei Bytes groß (16 Bits). Zeichencodes sind durch das UTF-16-Format definiert.
Semantischer Hinweis: Technisch gesehen sind einige Unicode-Zeichen durch zwei 16-Bit-Codeeinheiten vertreten, ugs. "Ersatzzeichenpaar" (surrogate pair). Ebenso enthalten einige ANSI-Codepages (ugs. Doppelbyte-Zeichensätze) einige Doppelbyte-Zeichen. Aus praktischen Gründen werden diese jedoch fast immer als zwei einzelne Einheiten behandelt (der Einfachheit halber als "Zeichen" bezeichnet).
VarSetCapacity bestimmt die Kapazität einer Variable in Bytes. Um die Kapazität einer Variable in Bezug auf die Anzahl der Zeichen zu setzen, muss die Größe eines Zeichens berücksichtigt werden. Zum Beispiel:
VarSetCapacity(ansi_var, capacity_in_chars) VarSetCapacity(unicode_var, capacity_in_chars * 2) VarSetCapacity(native_var, capacity_in_chars * (A_IsUnicode ? 2 : 1)) VarSetCapacity(native_var, t_size(capacity_in_chars)) ; siehe unten
Es gibt zwei Anwendungsmöglichkeiten für VarSetCapacity:
VarSetCapacity(var, 1000)
eine Kapazität von 1000 Bytes, die in den Unicode-Versionen von AutoHotkey_L nur für 500 Zeichen ausreichen würde. Das könnte Einfluss auf die Performanz haben, aber das Skript selbst sollte weiterhin normal funktionieren.Verwendet man den "Str"-Typ, handelt es sich um eine Zeichenkette im nativen Format des aktuellen Builds. Da einige Funktionen möglicherweise Zeichenketten in einem bestimmten Format benötigen oder zurückgeben müssen, stehen folgende Zeichenkettentypen zur Verfügung:
Zeichengröße | C / Win32-Typen | Kodierung | |
---|---|---|---|
WStr | 16-Bit | wchar_t*, WCHAR*, LPWSTR, LPCWSTR | UTF-16 |
AStr | 8-Bit | char*, CHAR*, LPSTR, LPCSTR | ANSI (die Standard-ANSI-Codepage des Systems) |
Str | -- | TCHAR*, LPTSTR, LPCTSTR | Äquivalent zu WStr in Unicode-Builds und AStr in ANSI-Builds. |
Verwendet man "Str" oder den äquivalenten Typ des aktuellen Builds als Parameter, wird die Adresse der Zeichenkette oder Variable an die Funktion übergeben, andernfalls wird stattdessen eine temporäre Kopie der Zeichenkette im gewünschten Format erstellt und übergeben. In der Regel sollten "AStr" und "WStr" nicht verwendet werden, wenn die Funktion einen Wert in diesen Parameter schreibt.
Hinweis: "AStr" und "WStr" können sowohl für die Parameter als auch für den Rückgabewert der Funktion verwendet werden.
Wenn ein Skript eine Funktion via DllCall() aufruft, die eine Zeichenkette als Parameter akzeptiert, muss eine der folgenden Vorgehensweisen verwendet werden:
DllCall("DeleteFile", "Ptr", &DateiName) DllCall("DeleteFile", "Str", DateiName)
In diesem Beispiel übergibt &DateiName
die Adresse der Zeichenkette, so dass die Funktion eine Zeichenkette im gleichen Format wie der "Str"-Typ erwarten muss. Beachten Sie, dass in AutoHotkey Basic "UInt" statt "Ptr" verwendet werden muss, aber der resultierende Code möglicherweise nicht 64-Bit-kompatibel ist.
Hinweis: Wenn der Name der Funktion nicht gefunden werden kann, fügt AutoHotkey_L das Suffix "A" oder "W" an, egal welche DLL angegeben ist. AutoHotkey Basic hingegen fügt das Suffix "A" nur bei Funktionen in User32.dll, Kernel32.dll, ComCtl32.dll oder Gdi32.dll an.
DllCall("DeleteFileA", "AStr", DateiName) DllCall("DeleteFileW", "WStr", DateiName)
Verwendet man NumPut() oder NumGet() mit Zeichenketten, muss der korrekte Offset und Typ für den angegebenen Zeichenkettentyp angegeben werden. Folgendes kann Ihnen dabei helfen:
; 8-Bit/ANSI Zeichenketten: size_of_char=1 type_of_char="Char" ; 16-Bit/UTF-16 Zeichenketten: size_of_char=2 type_of_char="UShort" nth_char := NumGet(var, (n-1)*size_of_char, type_of_char) NumPut(nth_char, var, (n-1)*size_of_char, type_of_char)
Wenn var
eine Zeichenkette im nativen Format enthält, können die passenden Werte auf Basis von A_IsUnicode
bestimmt werden:
nth_char := NumGet(var, t_size(n-1), t_char()) NumPut(nth_char, var, t_size(n-1), t_char()) ; Definieren Sie Funktionen für Komfort und Übersichtlichkeit: t_char() { return A_IsUnicode ? "UShort" : "Char" } t_size(char_count=1) { return A_IsUnicode ? char_count*2 : char_count }
Pointer sind in 32-Bit-Builds (einschließlich AutoHotkey Basic) 4 Bytes und in 64-Bit-Builds 8 Bytes groß. Skripte, die Strukturen oder DllCalls verwenden, sollten das berücksichtigen, um eine korrekte Ausführung auf beiden Plattformen zu gewährleisten. Bestimmte Bereiche, die auch betroffen sind:
Für Größen- und Offset-Berechnungen kann A_PtrSize verwendet werden. Für DllCall(), NumPut() und NumGet() kann je nach Bedarf der Ptr-Typ verwendet werden.
Beachten Sie, dass der Offset eines Feldes üblicherweise die Gesamtgröße aller vorherigen Felder ist. Beachten Sie auch, dass Handles (einschließlich Typen wie HWND und HBITMAP) prinzipiell Pointer-Typen sind.
/* typedef struct _PROCESS_INFORMATION { HANDLE hProcess; // Ptr HANDLE hThread; DWORD dwProcessId; // UInt (4 Bytes) DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; */ VarSetCapacity(pi, A_PtrSize*2 + 8) ; Ptr + Ptr + UInt + UInt DllCall("CreateProcess", <gekürzt>, "Ptr", &pi, <gekürzt>) hProcess := NumGet(pi, 0) ; Standardmäßig "Ptr". hThread := NumGet(pi, A_PtrSize) ; dwProcessId := NumGet(pi, A_PtrSize*2, "UInt") dwProcessId := NumGet(pi, A_PtrSize*2 + 4, "UInt")