Nein – ControlClick in AutoHotkey v2 ist nicht einfach „ein SendMessage“. Es nutzt je nach Situation mehrere Windows-Mechanismen; wenn du es per Nachricht nachbauen willst, sind meis...
Wie kann ich in AHK v2 das Control-M eines fremden Win32-Fensters auslesen?
Antwort vom**Am direktesten geht das in AHK v2 über `ControlGetText`, `ControlGetItems`, `ControlGetChecked` oder notfalls per `SendMessage` an das fremde Control; entscheidend ist: Du musst das konkrete Child-Control ansprechen, nicht nur das Fenster.** ## Der praktische Weg Wenn du den Text eines fremden Win32-Controls lesen willst, brauchst du meist einen dieser Selektoren: - `ClassNN` wie `Edit1`, `Button2`, `Static3` - die `HWND` des Controls - alternativ Mausposition + `MouseGetPos` Ein einfaches Beispiel für ein Edit-Control: ```ahk #Requires AutoHotkey v2.0 title := "Unbenannt - Editor" text := ControlGetText("Edit1", title) MsgBox text ``` Das funktioniert gut bei klassischen Win32-Fenstern wie Notepad, alten Dialogen, vielen Tools mit echten Standard-Controls. ## Erst die Controls herausfinden Der häufigste Fehler ist, das falsche Control anzusprechen. Nimm deshalb zuerst den Window Spy aus AHK und prüfe: - Fenstertitel - `ahk_class` - `ClassNN` des Child-Controls - ggf. `ahk_id` Wenn du lieber per Skript suchst: ```ahk #Requires AutoHotkey v2.0 title := "Unbenannt - Editor" controls := WinGetControls(title) out := "" for c in controls out .= c "`n" MsgBox out ``` Damit siehst du, welche Controls das Fenster überhaupt hat. Das ist oft hilfreicher als blind `Edit1` zu raten. ## Wenn du die HWND des Controls hast Das ist robuster als `ClassNN`, weil sich `Edit1`/`Edit2` ändern kann, wenn sich der Dialogaufbau ändert. ```ahk #Requires AutoHotkey v2.0 hwndCtrl := ControlGetHwnd("Edit1", "Unbenannt - Editor") text := ControlGetText(hwndCtrl) MsgBox text ``` Der wichtige Unterschied: `ClassNN` ist bequem, `HWND` ist stabiler. ## Spezialfälle: ListBox, ComboBox, Checkbox Nicht jedes Control liefert sinnvollen Text über `ControlGetText`. Beispiele: ```ahk #Requires AutoHotkey v2.0 items := ControlGetItems("ListBox1", "Mein Fenster") MsgBox items.Join("`n") ``` ```ahk #Requires AutoHotkey v2.0 state := ControlGetChecked("Button1", "Mein Fenster") MsgBox state "aktiv" : "nicht aktiv" ``` Das ist der entscheidende Praxisunterschied: Ein `Edit` liest du meist mit `ControlGetText`, eine Liste eher mit `ControlGetItems`, einen Haken mit `ControlGetChecked`. ## Wenn `ControlGetText` leer bleibt Dann liegt es meistens an einem dieser Punkte: 1. **Es ist kein echtes Win32-Standard-Control.** Viele moderne Programme nutzen Chromium, WPF, Java, Qt oder eigene Custom Controls. Dann sieht es zwar wie ein Eingabefeld aus, ist aber für AHK nicht normal auslesbar. 2. **Das Control reagiert nur auf Windows-Nachrichten.** Dann musst du mit `SendMessage` arbeiten, z. B. `WM_GETTEXT`. 3. **32/64-Bit, Rechte oder UIPI blockieren den Zugriff.** Wenn das Zielprogramm als Admin läuft und dein Skript nicht, scheitert der Zugriff oft direkt. ## Beispiel mit `WM_GETTEXT` Das ist nützlich, wenn du gezielt ein klassisches Text-Control abfragen willst: ```ahk #Requires AutoHotkey v2.0 WM_GETTEXT := 0x000D WM_GETTEXTLENGTH := 0x000E hwnd := ControlGetHwnd("Edit1", "Unbenannt - Editor") len := SendMessage(WM_GETTEXTLENGTH, 0, 0, hwnd) buf := Buffer((len + 1) * 2, 0) SendMessage(WM_GETTEXT, len + 1, buf.Ptr, hwnd) text := StrGet(buf, "UTF-16") MsgBox text ``` Das ist technischer, aber bei echten Win32-Controls oft der zuverlässigste Weg. ## Der wichtigste Unterschied, den viele übersehen `WinGetText()` liest Fenstertext. `ControlGetText()` liest den Inhalt eines bestimmten Child-Controls. Wenn du also den Inhalt eines Eingabefelds, einer Liste oder eines Buttons willst, ist `WinGetText()` meistens die falsche Ebene. ## Klare Einordnung Wenn es wirklich ein **fremdes Win32-Control** ist, klappt das in AHK v2 meist problemlos. Wenn es ein **Custom/UIA-basiertes modernes UI** ist, bringt klassisches Control-Reading oft nichts. Dann brauchst du eher UI Automation statt normaler AHK-Control-Funktionen. Genau daran scheitern viele Skripte: nicht am Code, sondern daran, dass das Ziel gar kein klassisches Win32-Control mehr ist.