WH_CBT Hook in MainThread und WH_JOURNALPLAYBACK in UnterThread



  • Ich starte und schließe einen Dialog automatisch (Dialogtest). Für die
    Dialogsteuerung verwende ich einen PlaybackHook, in einem extra Thread, der gestartet wird mit ::CreateThread. Mittels eines Cbt-Hooks (im MainThread) weiß ich, wann der Dialog aktiviert wird (HCBT_ACTIVATE) - in dem Cbt Hook starte ich dann den Thread. Dieser installiert den Playback Hook.

    Die Playbackfunktion des Hooks "drückt" dann auf verschiedene Knöpfe, zuletzt auf einen "Cancel"-Knopf. Wenn der Dialog geschlossen wird (HCBT_DESTROYWND) schicke ich dem Thread (aus der CBT-Hook Funktion) eine Nachricht, dass er den
    Playbackhook entfernen soll und warte (ewig mit Sleep 100), bis der ExitCode des Threads nicht mehr STILL_ACTIVE ist. Der Thread beendet auf die Nachricht hin den Hook und returned.

    Dieses Verhalten funktioniert.

    Ich wollte es nun symmetrisch machen. Ich wollte, dass der PlaybackHook in der Playbackfunktion entfernt wird. Das kann gehen - aber nicht in dieser Konstellation. Wenn ich in der Playbackfunktion alle meine Aktionen für den Dialog abgearbeitet habe und sie wieder aufgerufen wird, entferne ich in der Playbackfunktion den Playbackhook. Das geht, wenn ich das warten auf die Beendigung des UnterThreads auskommentiere.

    Aber: Wenn ich im Mainthread ewig mit Sleep 100 warte, wird die Playbackfunktion nicht mehr aufgerufen. (So kann sie nicht den Playbackhook deinstallieren - deswegen verwende ich in der funktionierenden Lösung
    vor der ewigen Schleife ein PostThreadMessage). Für das "Fehlverhalten" ist es egal, ob ich in der CBT-Hook Funktion oder direkt im Code nach "DoModal" warte.

    Wieso komme ich beim ewigen Warten (nach dem Drücken auf den Cancel
    Knopf) nicht mehr in die Playbackfunktion des anderen Threads?

    Ich habe keine großartigen Systemkenntnisse, ich habe mir das alles aus Beispielen und sonst dem Internet zusammengesucht. Es kann da also ein grober Fehler drin sein.


  • Mod

    MonikaH schrieb:

    Ich starte und schließe einen Dialog automatisch (Dialogtest). Für die
    Dialogsteuerung verwende ich einen PlaybackHook, in einem extra Thread, der gestartet wird mit ::CreateThread. Mittels eines Cbt-Hooks (im MainThread) weiß ich, wann der Dialog aktiviert wird (HCBT_ACTIVATE) - in dem Cbt Hook starte ich dann den Thread. Dieser installiert den Playback Hook.

    Die Playbackfunktion des Hooks "drückt" dann auf verschiedene Knöpfe, zuletzt auf einen "Cancel"-Knopf. Wenn der Dialog geschlossen wird (HCBT_DESTROYWND) schicke ich dem Thread (aus der CBT-Hook Funktion) eine Nachricht, dass er den
    Playbackhook entfernen soll und warte (ewig mit Sleep 100), bis der ExitCode des Threads nicht mehr STILL_ACTIVE ist. Der Thread beendet auf die Nachricht hin den Hook und returned.

    MonikaH schrieb:

    Das kannst Du aber auch einfach mit WaitForSingleObject machen!
    Oder was machst Du hier in der Ziwschenzeit? Auch noch einen Message Pump?

    Ich wollte es nun symmetrisch machen. Ich wollte, dass der PlaybackHook in der Playbackfunktion entfernt wird. Das kann gehen - aber nicht in dieser Konstellation. Wenn ich in der Playbackfunktion alle meine Aktionen für den Dialog abgearbeitet habe und sie wieder aufgerufen wird, entferne ich in der Playbackfunktion den Playbackhook. Das geht, wenn ich das warten auf die Beendigung des UnterThreads auskommentiere.

    Aber: Wenn ich im Mainthread ewig mit Sleep 100 warte, wird die Playbackfunktion nicht mehr aufgerufen. (So kann sie nicht den Playbackhook deinstallieren - deswegen verwende ich in der funktionierenden Lösung
    vor der ewigen Schleife ein PostThreadMessage). Für das "Fehlverhalten" ist es egal, ob ich in der CBT-Hook Funktion oder direkt im Code nach "DoModal" warte.

    Wieso komme ich beim ewigen Warten (nach dem Drücken auf den Cancel
    Knopf) nicht mehr in die Playbackfunktion des anderen Threads?

    Wie watest Du in der Schleife? Wenn an Deinen Thread, evtl. noch per SendMessage eine Nachricht gesendet werden soll, dann wartet das System nachtürlich ewig wnn Du keine Nachricten mehr abholst. Du hast einen Deadlock.

    Um genaueres zu wissen solltest Du uns mal den Code Deiner "Warteschleife" zeigen!

    Führe mal einenBreak All durch und schau Dir an, was jeder Thread in diesem Moment tut. Analysiere genau den Callstack jedes Threads.


Log in to reply