Ruft eine Funktion innerhalb einer DLL auf, wie z.B. die Windows API-Funktionen.
Result := DllCall("[DllFile\]Function" [, Type1, Arg1, Type2, Arg2, "Cdecl ReturnType"])
| Result | Der Rückgabewert der Funktion. Wenn die Funktion keinen Wert zurückgibt, enthält Result eine unbestimmte Ganzzahl. Wenn der Funktionsaufruf wegen eines Fehlers scheitert, wird Result geleert. |
| [DllFile\]Function |
Der Dateiname der DLL- oder EXE-Datei, gefolgt von einem Backslash (\) und dem Namen der Funktion. Beispiel: MeineDLL\MeineFunction Wenn keine Dateiendung angegeben wird, wird ".dll" angenommen. Wenn kein absoluter Pfad angegeben wird, wird DllFile in A_WorkingDir und im Systempfad "PATH" gesucht. DllFile kann beim Aufruf einer Funktion aus User32.dll, Kernel32.dll, ComCtl32.dll oder Gdi32.dll weggelassen werden. Beispiel: Der Aufruf User32\IsWindowVisible führt zum selben Ergebnis wie IsWindowVisible allein. Bei diesen Standard-DLL's kann das Suffix "A", das manchen API-Funktionen angehängt ist, ebenfalls weggelassen werden. Beispiel: MessageBox ist identisch mit MessageBoxA. Für wiederholte Aufrufe einer DLL-Funktion kann die Ausführungsgeschwindigkeit drastisch erhöht werden, wenn die DLL vorher explizit geladen wird. Ab v1.0.46.08+ kann dieser Parameter auch ein Integerwert sein, der dann als Adresse der Funktion verarbeitet wird. COM und RegisterCallback() liefern solche Adressen. |
| Type1, Arg1 | Jedes dieser Paare beschreibt einen einzelnen Parameter, der an die Funktion übergeben wird. Die Anzahl der Paare (Parameter) ist unbegrenzt. Die möglichen Angaben für Type sind unten in der Typentabelle beschrieben. In Arg wird der zu übergebende Wert angegeben. |
| Cdecl ReturnType |
Der Parameter Cdecl wird normalerweise nicht benötigt, weil die meisten Funktionen die Standardaufrufkonventionen und nicht die C-Aufrufkonventionen unterstützen. Funktionen wie wsprintf, die eine variable Anzahl von Parametern entgegennehmen, sind eine Ausnahme davon. Wenn ein Funktionsaufruf ohne Cdecl ErrorLevel An liefert, wobei n der Gesamtgröße der übergebenden Parameter entspricht, kann Cdecl benötigt werden. Wenn vorhanden, muss Cdecl vor Returntype angegeben werden und beide Parameter müssen ggf. durch ein Leerzeichen oder einen Tabulatorsprung getrennt werden. Beispiel: Cdecl Str ReturnType: Wenn die Funktion eine 32-bittige Ganzzahl (Int), einen booleschen Wert oder nichts zurückgibt, kann ReturnType weggelassen werden. Anderenfalls muss ein Typ aus der u.a. Typentabelle angegeben werden. Das *-suffix ist zulässig. |
| Str |
Eine Zeichenfolge (String) wie "Blau" oder MeineVar. Wenn die aufgerufene Funktion die Zeichenfolge modifiziert und das Argument der Name einer Variablen ist, wird deren Inhalt verändert. Der folgende DllCall konvertiert z.B. den Inhalt von MeineVar in Großbuchstaben: DllCall("CharUpper", "str", MeineVar) Wenn die Funktion eine längere als die aktuell in der Variablen enthaltene Zeichenfolge zurückgeben kann, muss vor dem Funktionsaufruf sichergestellt werden, dass für die Variable genügend Speicherplatz reserviert ist. Das geschieht durch Aufruf von VarSetCapacity(MeineVar, 123), wobei 123 der maximalen Länge der Zeichenfolge entspricht, die MyVar aufnehmen können soll. Ein Str-Argument darf kein Ausdruck sein, dessen Ergebnis eine Zahl ist (wie z.B. i+1). Wenn doch, wird die Funktion nicht aufgerufen und ErrorLevel auf -2 gesetzt. Der Str-Typ wird generell für Funktionen verwendet, die Parameter vom Typ "LPSTR", "LPCSTR", "LPTSTR" oder vergleichbare Typen erwarten. Das *-Suffix str * ist zulässig, wird aber sehr selten benötigt. Es kann für Funktionen verwendet werden, die Parameter wie "char **" oder "LPSTR *" erwarten. |
| Int64 | Eine 64-bittige Ganzzahl (Integer) im Bereich von -9223372036854775808 (-0x8000000000000000) bis 9223372036854775807 (0x7FFFFFFFFFFFFFFF). |
| Int |
Eine 32-bittige Ganzzahl (der übliche Integertyp) im Bereich von -2147483648 (-0x80000000) bis 2147483647 (0x7FFFFFFF). Ein Int-Argument wir manchmal auch als "Long" bezeichnet. Int
sollte auch für boolesche Werte (BOOL) verwendet werden, die von einer
Funktion erwartet werden. Ein boolescher Wert sollte immer 1 (wahr/true)
oder 0 (falsch/false) enthalten. Hinweis: Eine leere (NULL) ID-Nummer oder ein leerer Zeiger (pointer) wird als Int mit Inhalt 0 übergeben. |
| Short | Eine 16-bittige Ganzzahl im Bereich von -32768 (-0x8000) bis 32767 (0x7FFF). Vorzeichenlose (unsigned) Short-Argumente (UShort) können für Funktionen verwendet werden, die einen "WORD"-Parameter erwarten. |
| Char | Eine 8-bittige Ganzzahl im Bereich von -128 (-0x80) bis 127 (0x7F). Vorzeichenlose (unsigned) Char-Argumente (UChar) können für Funktionen verwendet werden, die einen "BYTE"-Parameter erwarten. |
| Float | Eine 32-bittige Gleitkommazahl (floating point number) mit 6-stelliger Genauigkeit. |
| Double | Eine 64-bittige Gleitkommazahl (floating point number) mit 15-stelliger Genauigkeit. |
| * oder P (Suffix) |
Das Anhängen eines * (Sternzeichen) (mit einem optionalen führendem Leerzeichen) oder des Buchstaben "P" an die o.a. Argumenttypen bewirkt, dass statt des Inhalts des Arguments seine Speicheradresse (Zeiger / pointer) an die Funktion übergeben wird. Die Funktion muss dann auch eine Adresse erwarten. Wenn die Funktion den Inhalt des Arguments verändert, wird der neue Inhalt in der Variablen abgelegt, deren Name als Argument verwendet wurde. Mit dem folgenden DllCall wird z.B. der Funktion MeineFunktion durch Übergabe der Speicheradresse der Variablen MeineVar der Zugriff auf den aktuellen Inhalt der Variablen und auch die Änderung des Inhalts ermöglicht: DllCall("MeineDll\MeineFunktion", "int *", MeineVar) Das *-Suffix wird generell dann verwendet, wenn eine Funktion ein Argument oder einen Rückgabewert eines Typs verwendet, dessen Bezeichner mit "LP" (long pointer) beginnt. Ausnahme ist der str-Typ wie "LPSTR", für den immer "str" verwendet werden sollte. Das meistgebrauchte Beispiel ist "LPDWORD", ein Zeiger (Speicheradresse) auf ein "DWORD". Weil "DWORD" eine vorzeichenlose 32-bittige Ganzzahl ist, verwendet man "UInt *" oder "UintP" für Argumente des Typs "LPDWORD". Hinweis: "char *" ist nicht identisch mit "str" , weil "char *" die Adresse eines 8-bittigen Werts übergibt, "str" dagegen die Adresse einer Zeichenfolge. Außerdem muss VarSetCapacity für *-Variablen nicht aufgerufen werden, wenn die Funktion in der Variablen nur Zahlen speichert. |
| U (Präfix) |
Das Voranstellen des Buchstaben U bewirkt bei den o.a. Ganzzahltypen, dass sie als vorzeichenlose (unsigned) Ganzzahlen interpretiert werden (UInt64, UInt, UShort und UChar). Genau genommen wird das nur für *-Suffix Argumente und Rückgabewerte benötigt, weil es bei Argumenten, die als Wert übergeben werden, mit Ausnahme von Int64 nicht von Belang ist, ob der Argumenttyp als mit oder ohne Vorzeichen deklariert wird. Eine 32-bittige vorzeichenlose Ganzzahl (UInt) ist der adäquater Typ für alle "DWORD", "HWND" oder ähnliche Argumente einer Funktion. Ein "HWND" (handle of a window) ist die eindeutige ID eines Fensters. Wenn ein vorzeichenloses Argument eine negative Zahl enthält, wird der Inhalt als vorzeichenlose positive Zahl behandelt. Wenn z.B. -1 als UInt übergeben wird, wird tatsächlich der Wert 0xFFFFFFFF übergeben. Das gilt aber nicht für 64-bittige Ganzzahlen (UInt64). Vorzeichenlose 64-bittige Ganzzahlen werden nicht vollständig unterstützt. Deshalb muss man für die Verarbeitung von Zahlen größer oder gleich 0x8000000000000000 das U Präfix weglassen und alle von der Funktion als negative Zahlen zurückgelieferten Werte als große positive Ganzzahlen behandeln. Wenn eine Funktion z.B. -1 als Int64 Rückgabewert liefert, tatsächlich aber einen UInt64-Wert zurückgibt, ist das in Wirklichkeit der Wert 0xFFFFFFFFFFFFFFFF. |
Hinweis Bei Argument- oder Rückgabetypen, die weder ein Leerzeichen noch einen * enthalten, können die umschließenden Anführungszeichen weggelassen werden. str kann z.B. anstelle von "str" und CDecl anstelle von "CDecl" verwendet werden. Darüber hinaus können die Anführungszeichen bei Verwendung des Buchstaben P anstelle des Zeichens * ebenfalls weggelassen werden. Beispiel: UIntP.
ErrorLevel wird auf einen der folgenden Werte gesetzt, die anzeigen ob der Funktionsaufruf erfolgreich war oder fehlschlug:
0: Erfolgreich.
-1 (Minus 1): Der [DllFile\]Function Parameter ist eine Gleitkommazahl, es wird aber eine Zeichenfolge oder eine positive Ganzzahl erwartet.
-2: Der Typ des Rückgabewerts oder einer der angegebenen Argumenttypen ist ungültig. Dieser Fehler kann dann entstehen, wenn einem str Argument ein Ausdruck übergeben wird, dessen Ergebnis eine Zahl ist.
-3: Auf die angegebene DllFile konnte nicht zugegriffen werden. Wenn in DllFile kein expliziter Pfad angegeben wurde, muss sich die Datei in A_WorkingDir oder im Systempfad (PATH) befinden. Dieser Fehler tritt auch auf, wenn dem Benutzer die Zugriffsrechte für die DLL-Datei fehlen.
-4: Die angegebene Funktion konnte in der DLL nicht gefunden werden.
N (eine positive Zahl): Die Funktion wurde aufgerufen, aber mit dem schweren Ausnahmefehler (fatal exception) Nummer N abgebrochen (0xC0000005 z.B. bedeutet "Zugriffsverletzung"). In diesen Fällen liefert die Funktion eine leere Zeichenfolge, die *-Suffix Variablen können aber trotzdem verändert sein. Ein Beispiel für einen schweren Ausnahmefehler ist die Verwendung eines ungültigen Zeigers wie NULL. Weil eine Cdecl Funktion den im folgenden Absatz beschriebenen "An" Fehler nicht liefern kann, kann sie einen Ausnahmefehler generieren, wenn ihr zu wenige Argumente übergeben werden.
An (Der Buchstabe A gefolgt von einer Ganzzahl n): Die Funktion wurde aufgerufen, es wurden aber zu viele oder zu wenige Argumente übergeben. "n" ist die Anzahl der Bytes, die in der Argumentenliste fehlerhaft sind. Wenn n positiv ist, wurden zu viele oder zu große Argumente übergeben oder die Funktion benötigt das Argument CDecl. Wenn n negativ ist, wurden zu wenige Argumente übergeben. Der Funktionsaufruf sollte bei diesen Fehlern korrigiert werden, um zuverlässige Ergebnisse zu gewährleisten. Bei diesen Fehlern kann zusätzlich ein Ausnahmefehler aufgetreten sein und die Funktion deshalb eine leere Zeichenfolge zurückgeben.
Trotz der internen Ausnahmefehlerbehandlung ist es möglich, ein Skript durch einen DllCall abstürzen zu lassen. Das kann geschehen, wenn eine Funktion nicht direkt einen Ausnahmefehler erzeugt aber unkorrekte Werte wie eine ungültige Adresse oder eine nicht mit 0x00 abgeschlossenen Zeichenfolge zurückgibt. Das muss kein Fehler der Funktion sein, wenn das Skript fehlerhafte Argumente wie ungültige Adressen oder ein "str" Argument mit unzureichender Kapazität übergibt. Ein Skript kann auch abstürzen, wenn für ein Argument oder den Rückgabewert ein falscher Typ angegeben wird, z.B. ein von einer Funktion zurückgegebene normale Ganzzahl als *-Suffix oder str Wert behandelt wird.
Ab v1.0.42.03+ enthält die interne Variable A_LastError das Ergebnis der Systemfunktion GetLastError(), die unmittelbar nach dem Aufruf der Funktion aufgerufen wird. (Das hat keine messbaren Auswirkungen auf die Ausführungsgeschwindigkeit). A_LastError ist eine Zahl zwischen 0 und 4294967295 (immer im Dezimalformat, nicht hexadezimal). Wie ErrorLevel ist auch A_LastError threadbezogen, d.h. eine Unterbrechung durch andere Threads verändert den Inhalt nicht. A_LastError wird aber auch von Run/RunWait gesetzt.
Wenn Funktionen einer DLL wiederholt aufgerufen werden, kann die Ausführungsgeschwindigkeit drastisch verbessert werden, wenn man die DLL vorher explizit in den Hauptspeicher lädt (für Standard-DLL's wie User32 ist das nicht nötig, weil sie immer im Hauptspeicher gehalten werden). Damit wird vermieden, dass bei der Ausführung von DllCall jedesmal ein interner Aufruf von LoadLibrary und FreeLibrary erfolgt. Beispiel:
hModule := DllCall("LoadLibrary", "str", "MyFunctions.dll") ; Vermeidet, dass DllCall() in der Schleife die DLL immer wieder laden muss.
Loop, C:\My Documents\*.*, , 1
result := DllCall("MyFunctions\BackupFile", "str", A_LoopFileFullPath)
DllCall("FreeLibrary", "UInt", hModule) ; Um den Speicherplatz freizugeben, wird die DLL nach Gebrauch wieder entladen.
Letztlich kann die Ausführungsgeschwindigkeit verbessert werden, wenn man einer Funktion, die die Länge einer Zeichenfolge nicht verändert, statt eines "str" Arguments die Adresse der Variablen (z.B. &MeineVar) übergibt, besonders dann, wenn die Zeichenfolge sehr lang ist. Im folgenden Beispiel wird auf diese Art eine Zeichenfolge in Großbuchstaben konvertiert: DllCall("CharUpper", uint, &MeineVar)
Eine Struktur (structure) ist eine Sammlung von Elementen (Feldern), die zusammenhängend im Speicher abgelegt sind. Die einzelnen Elemente sind häufig Ganzzahlen.
Funktionen, die die Adresse einer Struktur (oder eines Arrays von Hauptspeicheradressen) erwarten, können aufgerufen werden, wenn man vorher die binären Rohdaten der Struktur in einer normalen Variablen ablegt. Normalerweise erfolgt das in folgenden Schritten:
1) Mit VarSetCapacity(MyStruct, 123, 0) wird dafür gesorgt, dass für die Variable genügend Speicherplatz reserviert wird, um die Strukturdaten aufnehmen zu können. 123 muss zumindest durch die Anzahl von Bytes der tatsächlichen Strukturgröße ersetzt werden. Die Angabe von 0 als letztem Parameter ist optional. Damit werden alle reservierten Bytes mit binär Null initialisiert und die Funktion NumPut() im folgenden Absatz muss weniger oft aufgerufen werden.
2) Wenn die Funktion bestimmte Werte in der übergebenen Struktur erwartet, können diese mit NumPut(123, MeineStruktur, 4) in die Elemente übertragen werden, die nicht Null sein sollen. 123 muss dabei durch die Ganzzahl ersetzt werden, die in das Zielelement übertragen werden soll, oder durch &Var, wenn die Adresse einer Variablen verwendet werden soll. 4 muss durch die Distanz (Offset) des Zielelements zum Beginn der Variablen ersetzt werden (siehe auch Schritt #4).
3) Aufruf der Zielfunktion mit Übergabe der Adresse
von MeineStruktur als UInt-Argument. Beispiel: DllCall("MeineDll\MeineFunktion", UInt, &MeineStruktur).
Die Funktion kann dann einige der Strukturelemente auswerten und/oder
ändern.
4) Mit MeineInteger := NumGet(MeineStruktur, 4) können Ganzzahlen aus der Struktur ausgelesen werden. 4 muss durch den Offset des Zielelements innerhalb der Struktur ersetzt werden. Das erste Element hat immer den Offset 0 (Beginn der Struktur). Das zweite Element hat den Offset 0 zuzüglich der Länge des ersten Elements (normalerweise 4). Für die folgenden Elemente errechnet sich der Offset aus dem Offset des Vorelements zuzüglich der Länge des Vorelements. Die meisten Elemente wie DWORD, Int und andere Arten von 32-bittigen Ganzzahlen sind 4 Byte lang.
Siehe auch Beispiele für die Verwendung von Strukturen.
Wenn einer Funktion die Adresse einer
Variablen übergeben wird (z.B. &MeineVar) und die
Funktion die Länge des Inhalts der Variablen verändert, können spätere Zugriffe auf
die Variable unkorrekte Ergebnisse liefern. Das kann durch eine der
folgenden Maßnahmen verhindert werden:
1) MeineVar
als "str"
Argument statt als Uint/Adresse übergeben.
2) Ab v1.0.44.03+ die intern
gespeicherte Länge der Variablen nach dem DllCall mit VarSetCapacity(MeineVar, -1) aktualisieren.
Wenn eine Funktion binäre Nullen in einer Variablen speichert, können die meisten Anweisungen und Funktionen auf dahinterliegende Daten nicht zugreifen. Sie können aber noch mit Hilfe des Adress- bzw. Dereferenzoperators (& und *) bearbeitet werden und auch mit einem weiteren DllCall.
Eine Funktion, die die Adresse eines übergebenen "str" Arguments zurückgibt, kann eine identische Kopie der Zeichenfolge mit einer anderen als der ursprünglichen Adresse zurückliefern. Ein Aufruf wie CharLower(CharUpper(MeineVar)) in einer Programmiersprache würde z.B. den Inhalt von MeineVar in Kleinbuchstaben konvertieren. Wenn man dasselbe aber mit DllCall() versucht, besteht MeineVar nach dem folgenden Aufruf aus Großbuchstaben, weil CharLower von CharUpper eine temporären Kopie des Inhalts von MeineVar mit einer anderen Adresse erhält:
MeineVar = ABC
result := DllCall("CharLower", str, DllCall("CharUpper", str, MeineVar, str), str)
Das kann umgangen werden, indem man die zwei unterstrichenen "str" Werte in "UInt" ändert. Damit wird der Rückgabewert von CharUpper als reine Adresse interpretiert und als Ganzahl (int) an CharLower übergeben.
VBScript, JScript und der Zugriff auf COM-Objekte können mit Windows Scripting für AutoHotkey in ein Skript eingebettet werden.
Auf COM kann auch direkt mit DllCall zugegriffen werden, wie es in www.autohotkey.com/wiki/index.php?title=COM_Wrappers gezeigt wird.
PostMessage, OnMessage(), RegisterCallback(), Run, VarSetCapacity, Functions, SysGet, MSDN Library
; Beispiel: Aufruf der Windows API Funktion "MessageBox" und Ausgabe des betätigten Buttons.
WhichButton := DllCall("MessageBox", "int", "0", "str", "Ja or Nein drücken", "str", "Titel der Box", "int", 4)
MsgBox, Sie haben den Button #%WhichButton% betätigt.
; Beispiel: Änderung des Desktophintergrundbildes auf die angegebene Bitmapdatei (.bmp).
DllCall("SystemParametersInfo", UInt, 0x14, UInt, 0, Str, A_WinDir . "\winnt.bmp", UInt, 2)
; Beispiel: Aufruf der API Funktion "IsWindowVisible" um festzustellen, ob das Editorfenster sichtbar ist.
DetectHiddenWindows On
if not DllCall("IsWindowVisible", "UInt", WinExist("Unbenannt - Editor")) ; WinExist() liefert eine ID (HWND).
MsgBox Das Fenster ist nicht sichtbar.
; Beispiel: Aufruf der API Funktion wsprintf(), um die Zahl 432 mit führenden Nullen auf zehn Stellen aufzufüllen (0000000432).
VarSetCapacity(ZeroPaddedNumber, 20) ; Ausreichenden Speicherplatz für die neue Zeichenfolge reservieren.
DllCall("wsprintf", "str", ZeroPaddedNumber, "str", "%010d", "int", 432, "Cdecl") ; Benötigt die Cdecl Aufrufkonvention.
MsgBox %ZeroPaddedNumber%
; Beispiel: Demonstriert die Funktion QueryPerformanceCounter(), die genauere Werte als A_TickCount's 10ms liefert.
DllCall("QueryPerformanceCounter", "Int64 *", Start)
Sleep 1000
DllCall("QueryPerformanceCounter", "Int64 *", Ende)
MsgBox % "Die verstrichene QPC Zeit ist " . Ende - Start
; Beispiel: Dieser Hotkey reduziert temporär die Mausgeschwindigkeit für eine präzisere Positionierung.
; F1 gedrückt halten, um die Geschwindigkeit zu verringern. Beim Loslassen wird die Originalgeschwindigkeit wiederhergestellt.
F1::
SPI_GETMOUSESPEED = 0x70
SPI_SETMOUSESPEED = 0x71
; Abfrage der aktuellen Geschwindigkeit für die spätere Wiederherstellung:
DllCall("SystemParametersInfo", UInt, SPI_GETMOUSESPEED, UInt, 0, UIntP, OrigMouseSpeed, UInt, 0)
; Neue Mausgeschwindigkeit setzen, hier 3 (Bereich: 1 - 20, Standard: 10):
DllCall("SystemParametersInfo", UInt, SPI_SETMOUSESPEED, UInt, 0, UInt, 3, UInt, 0)
KeyWait F1 ; Verhindert wiederholte Aufrufe durch die Autowiederholungsfunktion der Tastatur.
return
F1 up::DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, OrigMouseSpeed, UInt, 0) ; Wiederherstellen der Originalgeschwindigkeit.
; Beispiel: Wenn der folgenden Funktion die eindeutige ID eines Fensters und der Text oder die ClassNN eines seiner
; Controls übergeben werden, liefert sie die HWND (eindeutige ID) dieses Controls.
; Mit v1.0.43.06 wurde die hier dargestellte Funktion durch die folgende Anweisung abgelöst, die zuverlässiger arbeitet:
ControlGet, OutputVar, Hwnd,, ClassNN, WinTitle
; Beispiel: Überwachung des aktiven Fensters und Anzeige der Position der vertikalen Scrollleiste im Control
; mit dem Eingabefokus (mit Echtzeit Updates). V1.0.43.06+ wird benötigt wegen ControlGet Hwnd.
#Persistent
SetTimer, WatchScrollBar, 100
return
WatchScrollBar:
ActiveWindow := WinExist("A")
if not ActiveWindow ; Kein aktives Fenster.
return
ControlGetFocus, FocusedControl, ahk_id %ActiveWindow%
if not FocusedControl ; Kein Control hat den Eingabefokus.
return
; Anzeige der Position der vertikalen oder horizontalen Scrollleiste mit einem ToolTip:
ControlGet, ChildHWND, Hwnd,, %FocusedControl%, ahk_id %ActiveWindow%
ToolTip % DllCall("GetScrollPos", "UInt", ChildHWND, "Int", 1) ; Der letzte Parameter ist 1 für SB_VERT oder 0 für SB_HORZ.
return
; Beispiel: Dieses Skript schreibt Text in eine Datei und liest ihn dann wieder ein (benötigt v1.0.34+).
; Durch die Verwendung von DllCall() kann auch die Ausführungsgeschwindigkeit gesteigert werden,
; wenn mehrere Dateien gleichzeitig gelesen und/oder geschrieben werden.
FileSelectFile, FileName, S16,, Neue Datei erzeugen:
if FileName =
return
GENERIC_WRITE = 0x40000000 ; Datei zum Schreiben öffnen.
CREATE_ALWAYS = 2 ; Ggf. existierende Datei überschreiben
hFile := DllCall("CreateFile", str, FileName, Uint, GENERIC_WRITE, Uint, 0, UInt, 0, UInt, CREATE_ALWAYS, Uint, 0, UInt, 0)
if not hFile
{
MsgBox Kann Datei "%FileName%" nicht schreibend öffnen.
return
}
TestString = Das ist ein Teststring.`r`n ; Wenn man so in die Datei schreibt, barucht man `r`n um eine neue Zeile zu erzeugen.
DllCall("WriteFile", UInt, hFile, str, TestString, UInt, StrLen(TestString), UIntP, BytesActuallyWritten, UInt, 0)
DllCall("CloseHandle", UInt, hFile) ; Datei schließen
; Nachdem die Datei geschrieben wurde, wird der Inhalt wieder eingelesen.
GENERIC_READ = 0x80000000 ; Datei zum Lesen öffnen.
OPEN_EXISTING = 3 ; Die Datei muss bereits existieren.
FILE_SHARE_READ = 0x1 ; Andere Prozesse können die Datei zum Lesen öfnen
FILE_SHARE_WRITE = 0x2 ; Andere Prozesse können die Datei zum Schreiben öffnen
hFile := DllCall("CreateFile", str, FileName, UInt, GENERIC_READ, UInt, FILE_SHARE_READ|FILE_SHARE_WRITE, UInt, 0, UInt, OPEN_EXISTING, Uint, 0, UInt, 0)
if not hFile
{
MsgBox Kann Datei "%FileName%" nicht lesend öffnen.
return
}
; Variable BytesToRead leeren und ausreichend Speicherplatz reservieren:
BytesToRead := VarSetCapacity(TestString, StrLen(TestString))
DllCall("ReadFile", UInt, hFile, str, TestString, UInt, BytesToRead, UIntP, BytesActuallyRead, UInt, 0)
DllCall("CloseHandle", UInt, hFile) ; Datei schließen.
MsgBox Folgendes wurde aus der Datei gelesen:`n %TestString%
; Beispiel: Verbirgt den Mauszeiger beim Drücken von Win+C. Erneutes Drücken von Win+C zeigt ihn wieder an.
; Dieses Skript stammt von www.autohotkey.com/forum/topic6107.html
OnExit, ShowCursor ; Absichern, dass der Mauszeiger bei Beendigung des Skripts wieder angezeigt wird.
return
ShowCursor:
SystemCursor("On")
ExitApp
#c::SystemCursor("Toggle") ; Win+C Hotkey : Mauszeiger an/aus.
SystemCursor(OnOff=1) ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = andere Werte
{
static AndMask, XorMask, $, h_cursor
,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; Systemzeiger
, b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13 ; Leerer Zeiger
, h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13 ; ID des Standardzeigers
if (OnOff = "Init" or OnOff = "I" or $ = "") ; Initialisieren auf Wunsch und beim ersten Aufruf
{
$ = h ; Aktiver Standardzeiger
VarSetCapacity( h_cursor,4444, 1 )
VarSetCapacity( AndMask, 32*4, 0xFF )
VarSetCapacity( XorMask, 32*4, 0 )
system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650
StringSplit c, system_cursors, `,
Loop %c0%
{
h_cursor := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% )
h%A_Index% := DllCall( "CopyImage", "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 )
b%A_Index% := DllCall("CreateCursor","uint",0, "int",0, "int",0
, "int",32, "int",32, "uint",&AndMask, "uint",&XorMask )
}
}
if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T"))
$ = b ; Leerer Zeiger
else
$ = h ; Gesicherter Zeiger
Loop %c0%
{
h_cursor := DllCall( "CopyImage", "uint",%$%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 )
DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% )
}
}
; Strukturbeispiel: Übergibt eine RECT-Struktur an GetWindowRect(), die die Strukturelemente mit den
; Positionen der linken, oberen, rechten und unteren Ränder eines Fensters relativ zum Bildschirm füllt
Run Notepad
WinWait Untitled - Notepad ; Damit wird auch das LastFoundWindow für das folgende WinExist() gesetzt.
VarSetCapacity(Rect, 16) ; Eine RECT-Struktur besteht aus vier 32-bittigen Ganzzahlen (d.h. 4*4=16).
DllCall("GetWindowRect", UInt, WinExist(), UInt, &Rect) ; WinExist() liefert eine ID (HWND).
MsgBox % "Links " . NumGet(Rect, 0, true) . " Oben " . NumGet(Rect, 4, true)
. " Rechts " . NumGet(Rect, 8, true) . " Unten " . NumGet(Rect, 12, true)
; Strukturbeispiel: Übergibt die Adresse einer RECT-Struktur an FillRect(), die einem Teil des Bildschirms
; entspricht, der vorübergehend mit Rot gefüllt wird.
VarSetCapacity(Rect, 16, 0) ; Reserviert Speicheplatz für vier 4-Byte Ganzzahlen und initialisiert ihn mit 0.
NumPut(A_ScreenWidth//2, Rect, 8) ; Das dritte Strukturelement ist "rect.right" (rechte Seite)
NumPut(A_ScreenHeight//2, Rect, 12) ; Das vierte Strukturelement ist "rect.bottom" (untere Seite).
hDC := DllCall("GetDC", UInt, 0) ; Null liefert den Gerätekontext (device context) des Desktops.
hBrush := DllCall("CreateSolidBrush", UInt, 0x0000FF) ; Erzeugt einen roten Pinsel (0x0000FF ist BGR-Format).
DllCall("FillRect", UInt, hDC, Str, Rect, UInt, hBrush) ; Fülle das gegebenen Rechteck auf dem Dektop mit diesem Pinsel.
DllCall("ReleaseDC", UInt, 0, UInt, hDC) ; Aufräumen (Ressourcen freigeben).
DllCall("DeleteObject", UInt, hBrush) ; Aufräumen.
; Strukturbeispiel: Setzt die Systemzeit auf das angegebene Datum und die angegebene Zeit.
; Achtung: Bei Verstellen in die Zukunft können geplante Tasts vorzeitig starten!
SetSystemTime("20051008142211") ; Übergibt einen Zeitstempel (lokal, nicht UTC).
SetSystemTime(YYYYMMDDHHMISS)
; Setzt die Systemzeit gemäß Zeitstempel.
; Der Aufrufer muss absichern, dass ein gültiger Zeitstempel (lokale Zeit) übergeben wird.
; Gibt im Fehlerfall Null zurück, sonst einen Wert ungleich Null.
{
; Lokale Zeit für die Verendung mit SetSystemTime() in UTC konvertieren.
UTC_Delta -= %A_NowUTC%, Seconds ; Für die folgende Rundung in Sekunden umrechnen.
UTC_Delta := Round(-UTC_Delta/60) ; Auf die nächste Minute runden.
YYYYMMDDHHMISS += %UTC_Delta%, Minutes ; Mit dem Offset nach UTC konvertieren.
VarSetCapacity(SystemTime, 16, 0) ; Diese Struktur besteht aus 8 UShorts (d.h. 8*2=16).
StringLeft, Int, YYYYMMDDHHMISS, 4 ; YYYY (Jahr)
NumPut(Int, SystemTime, 0, 2)
StringMid, Int, YYYYMMDDHHMISS, 5, 2 ; MM (lfd. Monat im Jahr, 01-12)
NumPut(Int, SystemTime, 2, 2)
StringMid, Int, YYYYMMDDHHMISS, 7, 2 ; DD (lfd. Tag im Monat)
NumPut(Int, SystemTime, 6, 2)
StringMid, Int, YYYYMMDDHHMISS, 9, 2 ; HH (Stunde im 24-Stundenformat)
NumPut(Int, SystemTime, 8, 2)
StringMid, Int, YYYYMMDDHHMISS, 11, 2 ; MI (Minute)
NumPut(Int, SystemTime, 10, 2)
StringMid, Int, YYYYMMDDHHMISS, 13, 2 ; SS (Sekunde)
NumPut(Int, SystemTime, 12, 2)
return DllCall("SetSystemTime", UInt, &SystemTime)
}
Mehr Strukturbeispiele:
1) Im WinLIRC Client Skript wird gezeigt, wie man mit DllCall()s eine Netzwerkverbindung
zu einem TCP/IP-Server herstellt und Daten abruft.
2) Das Betriebssystem bietet Standarddialoge für die Auswahl von Zeichensätzen, Farben und Icons.
Diese Dialoge verwenden Strukturen and werden hier www.autohotkey.com/forum/topic17230.html beschrieben.