PostMessage / SendMessage Tutorial von Rajat

Diese Seite beschreibt, wie mit PostMessage oder SendMessage Meldungen an ein Fenster oder Steuerelement gesendet werden können, und beantwortet einige Fragen wie:

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

Beginnen wir mit dem ersten Beispiel: 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, 0x0111, 40239, 0, , Neue Nachricht

Das klappt hervorragend! Aber was zum Teufel ist das? 0x0111 ist der hexadezimale Code für die Meldung WM_COMMAND. 40239 ist der Code, den dieses bestimmte Fenster als Menüpunkt 'Bild einfügen' versteht. Lassen Sie mich Ihnen nun erklären, wie man den Code 40239 findet:

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

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

Was werden Sie tun? Wahrscheinlich auf die Symbolleistenschaltfläche klicken, oder? Aber Symbolleisten können verschoben und versteckt werden! Das gilt auch für Paint. Wenn der Zielbenutzer dies getan hat, wird Ihr Skript an dieser Stelle fehlschlagen. Aber der folgende Befehl wird immer funktionieren:

PostMessage, 0x0111, 639,,, Unbenannt - Paint

PostMessage hat auch den Vorteil, dass das Fenster im Hintergrund sein kann, während beim Senden von Mausklicks das Fenster aktiv sein muss.

Hier einige weitere Beispiele. Hinweis: Ich benutze WinXP Pro (SP1) ... Wenn Sie ein anderes System verwenden, können Ihre Parameter abweichen (gilt nur für Windows-Anwendungen wie Wordpad und Notepad, bei anderen sollten sich die Parameter nicht ändern):

; Macht die Schriftfarbe in Wordpad türkis
PostMessage, 0x0111, 32788, 0, , Dokument - WordPad
; Öffnet das Info-Fenster in Notepad
PostMessage, 0x0111, 65, 0, , Unbenannt - Editor
; Aktiviert/Deaktiviert Zeilenumbruch in Notepad
PostMessage, 0x0111, 32, 0, , Unbenannt - Editor
; Wiedergabe/Anhalten im Windows Media Player
PostMessage, 0x0111, 32808, 0, , Windows Media Player
; Suspendiert 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, 0x0111, 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)  ; Ignoriert das aktuelle Fenster bzgl. Neuladen
        {
            continue
        }
        PostMessage, 0x0111, 65303,,, % "ahk_id" . hwnd
    }
    Reload
}

Die obigen Angaben beziehen sich auf PostMessage. SendMessage funktioniert auf die gleiche Weise, wartet aber zusätzlich auf einen Rückgabewert, der z.B. dazu verwendet werden kann, den aktuell gespielten Titel in Winamp abzurufen (siehe Winamp automatisieren für ein Beispiel).

Hier noch einige Hinweise:

Hinweis: Es gibt Anwendungen, bei denen diese Technik nicht funktioniert. Ich hatte gemischte Erfahrungen mit VB- und Delphi-Anwendungen. Diese Technik sollte am besten für Anwendungen verwendet 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 kann es vorkommen, dass die GUI überhaupt kein WM_COMMAND verwendet. Die GUI verwendet wahrscheinlich Mauspositionen und Mausklicks.

Finden Sie es selbst heraus.... und teilen Sie Ihre Erfahrungen mit der AutoHotkey-Community. Feedback ist willkommen!

Diese Einführung ist nicht für blutige Anfänger gedacht (nichts für ungut), da es sich bei diesen Befehlen um fortgeschrittene Features handelt. Wenn Sie also nach dem Lesen nichts verstanden haben, vergessen Sie es bitte.

-Rajat