Einfach ausgedrückt?
Windows kommuniziert intern mit Messages, von denen selbst in Ruhe irgendwas um die 3.000 pro Sekunde erzeugt werden.
Mit dem, was SKAN da ausgetüftelt hat, wird ein leeres unsichtbares GUI erzeugt, was als "Empfänger" für hauptsächlich die Messages arbeitet, die anzeigen, dass ein Fenster erzeugt, verändert oder geschlossen wurde. Es werden zwar auch andere Nachrichten empfangen, die kann man ja ausfiltern.
Fake-Fenster (Empfänger) am Anfang des Scriptes erzeugen
Gui, New, +HwndFakeWinHwnd
DllCall( "RegisterShellHookWindow", UInt, FakeWinHwnd)
OnMessage( DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ), "ShellMessage" )
Nun wird beim Eintreffen einer der Messages die Funktion ShellMessage() aufgerufen
ShellMessage(wParam,lParam) {
; Code zur Auswertung der Message
}
Aus dem wParam erfährst du, was mit dem Fenster passiert ist und aus dem lParam (in aller Regel) erfährst du das Handle (entspricht der ahk_id).
vgl. dazu die Liste im Thread.
Wenn z.B. wParam = 1 ist, wurde ein Fenster erzeugt und das Handle aus lParam kann direkt in den meisten AHK-Befehlen benutzt werden.
Bei mir sieht das so aus:
WinHWND := lParam ; Windows-Handle
WinGetPos , WinX, WinY, WinWidth, WinHeight, ahk_id %WinHWND% ; Koordinaten, Höhe und Breite
WinGetTitle, WinTitle, ahk_id %WinHWND% ; Fenstertitel
WinGetText, WinText, ahk_id %WinHWND% ; Textinhalt
WinGetClass, WinClass, ahk_id %WinHWND% ; Klasse (ahk_class)
WinGet, WinControlList, ControlList, ahk_id %WinHWND% ; Liste der Controls
WinGet, WinStyle, Style, ahk_id %WinHWND% ; Style
WinGet, WinExStyle, ExStyle, ahk_id %WinHWND% ; Extended Style
WinGet, WinPID, PID, ahk_id %WinHWND% ; Prozess-ID
Damit hast du in dem Augenblick, in dem ein Fenster erzeugt wird, alle relevanten Informationen.
Da die Funktion jedes Mal aufgerufen wird, wenn sich etwas an einem Fenster ändert (z.B. auch beim einem Redraw, weil sich die Anzeige in der TitleBar des Browsers geändert hat), kannst du so eigentlich so gut wie alles im Blick behalten, was du willst.
Der Ressourcenverbrauch eines solchen Scriptes bewegt sich übrigens in der Nähe von NULL.
Einfaches Beispiel, um zu sehen, auf welche sichtbaren und unsichtbaren Fenster ein Redraw ausgeführt wurde (z.B. weil sich der Titel geändert hat):
; ===============================================================================================================================
; AHK Version ...: AHK_L 1.1.12.00 x64 Unicode
; Win Version ...: Windows 7 Ultimate x64 SP1
; ===============================================================================================================================
#NoEnv ; Nicht nachsehen, ob leere Varibalen evtl. Umgebungsvariablen sind
#SingleInstance force ; Bei Neustart des Scriptes die alte Instanz ohne Nachfrage ersetzen
SetBatchLines -1 ; Das Script läuft ohne Zwangspausen. (nur für schnelle Rechner empfohlen)
SetControlDelay, -1 ; Wartezeit beim Zugriff auf langsame Controls abschalten. (nur für schnelle Rechner empfohlen)
SetWinDelay, -1 ; Verzögerung bei allen Fensteroperationen abschalten. (nur für schnelle Rechner empfohlen)
; =='AUTOEXEC-SEKTION'===========================================================================================================
Gui, New, +HwndFakeWinHwnd
DllCall( "RegisterShellHookWindow", UInt, FakeWinHwnd)
OnMessage( DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ), "ShellMessage" )
; =='ENDE DER AUTOEXEC-SEKTION'==================================================================================================
Return
ShellMessage(wParam,lParam) {
If ( wParam = 6 ) {
HiddenWinState := A_DetectHiddenWindows
HiddenTextState := A_DetectHiddenText
DetectHiddenText, On
DetectHiddenWindows, On
; ----------------------------------------
WinGet, ProzessID, PID, ahk_id %lParam%
For Process In ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process where Handle=" . ProzessID)
ExePath := Process.ExecutablePath
WinGetTitle, WinTitle, ahk_id %lParam%
ToolTip % "Programm: " ExePath "`n"
. "Fenstertitel: " WinTitle
; ----------------------------------------
DetectHiddenWindows, %HiddenWinState%
DetectHiddenText, %HiddenTextState%
}
}
; Beenden des Scriptes
Escape::
ExitApp
Return
Ich hoffe, das war jetzt nicht nur wirres Zeug und es hilft ein Bisschen, den Beitrag von SKAN besser zu verstehen.