PostMessage / SendMessage Tutorial von Rajat

Diese Seite beschreibt, wie man PostMessage oder SendMessage nutzen kann, um Meldungen an ein Fenster oder an den darin enthaltenen Steuerelementen zu senden, und beantwortet einige Fragen wie:

"Wie kann ich eine Schaltfläche auf einem minimierten Fenster drücken?"
"Wie kann ich einen Menüpunkt auswählen, falls WinMenuSelectItem nicht funktioniert?!"
"Dies ist ein Fenster mit anpassbarem Look ... wie sende ich einen Befehl, der immer funktioniert?"
"und was ist mit versteckten Fenstern?!"


Anforderungen: [AutoHotkey v1.0.09+] und Winspector Spy (kann hier gefunden werden)

Gehen wir das erste Beispiel an: WinMenuSelectItem funktioniert nicht mit der Menüleiste innerhalb des Outlook-Fensters "Neue Nachricht". Das heißt, dass dieser Code nicht funktionieren wird:

WinMenuSelectItem, Neue Nachricht,, E&infügen, &Bild...

Aber PostMessage könnte diese Aufgabe erledigen:

PostMessage, 0x111, 40239, 0, , Neue Nachricht

Das klappt hervorragend! Aber was zum Teufel ist das? 0x111 ist der hexadezimale Code für die Meldung WM_COMMAND. 40239 ist der Code, den dieses bestimmte Fenster als Menüpunkt 'Einfügen Bild' versteht. Nun lassen Sie mich Ihnen sagen, wie so ein Wert gefunden werden kann:

  1. Öffnen Sie 'Winspector Spy' und das Fenster "Neue Nachricht".
  2. Ziehen Sie das Fadenkreuz aus dem Fenster 'Winspector Spy' auf die Titelleiste des Fensters 'Neue Nachricht'.
  3. Klicken Sie mit der rechten Maustaste auf das ausgewählte Fenster in der linken Liste und wählen Sie 'Messages' aus.
  4. Klicken Sie mit der rechten Maustaste auf das leere Fenster und wählen Sie 'Edit message filter' aus.
  5. Drücken Sie die Schaltfläche 'filter all' und klicken Sie zweimal auf 'WM_COMMAND' in der linken Liste. Auf diese Weise werden Sie nur diese Meldung überwachen.
  6. Gehen Sie nun zu das Fenster 'Neue Nachricht' und wählen Sie den folgenden Menüpunkt aus: Einfügen -> Bild.
  7. Kehren Sie zum 'Winspector Spy' zurück und drücken Sie die Ampel, um die Überwachung zu pausieren.
  8. Klappen Sie die angesammelten WM_COMMAND-Meldungen auf (alle anderen ignorieren, falls vorhanden).
  9. Das, was Sie (üblicherweise) suchen sollten, ist eine Code-0-Meldung. Manchmal gibt es WM_COMMAND-Meldungen wie 'win activated' oder 'win destroyed', die Sie getrost ignorieren können. Irgendwo finden Sie eine Meldung, die 'Control ID: 40239' enthält ... Das war's!
  10. Fügen Sie den Wert nun in den obigen Befehl ein. So einfach ist das! Es ist der wParam-Wert.

Für das nächste Beispiel habe ich Paint genommen, weil das wahrscheinlich jeder haben wird. Nehmen wir mal an, dass Sie in dieser Anwendung ein Tool aus der Toolbar per AutoHotkey auswählen müssen, wie z. B. die Farbauswahl.

Was werden Sie tun? Höchstwahrscheinlich per Mausklick auf die Toolbar-Schaltfläche, richtig? Aber Toolbars können verschoben und versteckt werden! Das trifft auch auf Paint zu. Wenn der Zielbenutzer so etwas getan hat, wird Ihr Skript an dieser Stelle fehlschlagen. Der folgende Befehl würde weiterhin funktionieren:

PostMessage, 0x111, 639,,, Unbenannt - Paint

Ein weiterer Vorteil von PostMessage ist, dass das Fenster im Hintergrund sein kann; dagegen müsste beim Senden von Mausklicks das Fenster aktiv sein.

Hier ein paar weitere Beispiele. Hinweis: Ich verwende WinXP Pro (SP1) ... Falls sich Ihr Betriebssystem von meinem unterscheidet, könnten Ihre Parameter anders sein (gilt nur für Windows-Anwendungen wie Wordpad und Editor, bei anderen Anwendungen sollten die Parameter nicht abweichen):

; Macht die Schreibfarbe in Wordpad türkis
PostMessage, 0x111, 32788, 0, , Dokument - WordPad
; Öffnet das Info-Fenster im Texteditor
PostMessage, 0x111, 65, 0, , Unbenannt - Editor
; Aktiviert/Deaktiviert Zeilenumbruch im Texteditor
PostMessage, 0x111, 32, 0, , Unbenannt - Editor
; Wiedergabe/Anhalten im Windows Media Player
PostMessage, 0x111, 32808, 0, , Windows Media Player
; Sperrt die Hotkeys eines laufenden AHK-Skripts
DetectHiddenWindows, On
SetTitleMatchMode, 2
; Verwenden Sie 65306 für Pause oder 65303 für Reload anstelle von Suspend. (siehe FAQ).
PostMessage, 0x111, 65305,,, MeinSkript.ahk - AutoHotkey
; Drücken Sie FESTSTELL+NUMPAD2, um alle AutoHotkey-Skripte neu zu laden
CapsLock & Numpad2::
AlleAhkSkripteNeuladen() {
    DetectHiddenWindows, On
    SetTitleMatchMode, 2
    WinGet, allAhkExe, List, ahk_class AutoHotkey
    Loop, % allAhkExe {
        hwnd := allAhkExe%A_Index%
        if (hwnd = A_ScriptHwnd)  ; Verhindert das Neuladen des aktuellen Fensters
        {
            continue
        }
        PostMessage, 0x111, 65303,,, % "ahk_id" . hwnd
    }
    Reload
}

Das oben war für PostMessage. SendMessage funktioniert genauso und wartet zusätzlich auf einen Rückgabewert, mit dem beispielsweise der aktuelle Track von Winamp abgerufen werden kann (siehe Winamp automatisieren als Beispiel).

Hier ein paar weitere Hinweise:

Hinweis: Es gibt Anwendungen, bei denen diese Technik nicht funktioniert. Ich hatte gemischtes Glück bei VB- und Delphi-Anwendungen. Diese Technik sollte am besten bei Anwendungen benutzt werden, die mit C oder C++ programmiert wurden. Bei VB-Anwendungen ist der "LParam" des gleichnamigen Befehls jedes Mal ein anderer. Bei einigen Delphi-Anwendungen verwendet die GUI einiger Anwendungen überhaupt kein WM_COMMAND. Die GUI greift vermutlich auf Positionen und Klicks der Maus zurück.

Gehen Sie auf Entdeckungsreise.... und teilen Sie Ihre Erfahrungen mit der AutoHotkey-Community. Feedbacks sind erwünscht!

Diese Einführung ist nicht für totale Anfänger gedacht (nichts für ungut), da diese Befehle als erweiterte Features betrachtet werden. Also, wenn Sie daraus nicht schlau werden, vergessen Sie es.

-Rajat