Topmost entfernen bei nicht-antwortendem Fenster



  • Hi!

    Angenommen, ich habe einen fremden Prozess, der ein Topmost-Fullscreen-Fenster hat. Ich hooke mich in den Prozess, sodass er, während er in meiner Prozedur steckt, nicht mehr auf die Nachrichtenschleife reagiert. Blöderweise führt das dazu, dass ein Aufruf wie SetWindowPos(HWND_NOTOPMOST) wirkungslos bleibt. Nun möchte ich aber gerne, dass das Fenster nicht mehr topmost ist, während mein Hook läuft. Kann ich das irgendwie vom Hook aus bewerkstelligen?



  • ist das mit absicht, das er seine messages nicht mehr abrufen kann ?



  • Nein, es ist ein mehr oder weniger unerwünschter Seiteneffekt.



  • Kannst Du Deinen injizierten Code in einem eigenen Thread laufen lassen?



  • SG1 schrieb:

    Kannst Du Deinen injizierten Code in einem eigenen Thread laufen lassen?

    Leider nicht, mein Hook muss symmetrisch mit dem Prozess laufen, da der Prozess mit Ergebnissen des Hooks arbeitet.

    Gibt es keinen Weg, extern das Fensterverhalten zu beeinflussen, ohne dass man die Kooperation des Fensters braucht?



  • dann aendere halt TOPMOST bevor du ihm blockierst. dann kann das fenster noch mitmachen.
    oder du gibst dem fenster eine neue WindowProc von dir und du reichst an die alte WindowProc die notwendigen messages weiter.



  • Ich hatte vor kurzem auch ein Problem mit einem Fenster das nicht auf Z-Order Changes reagiert hat, weil "sein" Thread zu diesem Zeitpunkt mit WaitForSingleObject blockiert war.
    Wir haben das dann gelöst indem wir den Thread statt dessen mit MsgWaitForMultipleObjects(QS_SENDMESSAGE) warten liessen, und im Falle des Falles dann diese Messages bearbeitet haben ( while (PeekMessage(PM_QS_SENDMESSAGE)) ... ).

    In unserem Fall ging das, da es OK war an der Stelle wo ursprünglich das WaitForSingleObject stand sämtliche gesendeten Messages abzuarbeiten.

    Falls das bei dir auch OK wäre, wäre das eine Möglichkeit.

    Ansonsten könnte man vielleicht noch versuchen mit wMsgFilterMin/wMsgFilterMax zu arbeiten. Wobei ich keine Ahnung habe welche Messages man da alle erlauben müsste damit das funktioniert.

    Bzw. ... wenn du sowieso schon in dem Prozess bist, in dem Thread der für das Fenster zuständig ist, dann kannst du ja gleich direkt dort SetWindowPos(HWND_NOTOPMOST) aufrufen.



  • hustbaer schrieb:

    Bzw. ... wenn du sowieso schon in dem Prozess bist, in dem Thread der für das Fenster zuständig ist, dann kannst du ja gleich direkt dort SetWindowPos(HWND_NOTOPMOST) aufrufen.

    Jodocus schrieb:

    Blöderweise führt das dazu, dass ein Aufruf wie SetWindowPos(HWND_NOTOPMOST) wirkungslos bleibt.

    Wenn ich so einen Call durchführe, bekomme ich einen Deadlock, da der Nachrichtenschleifen-Thread vermutlich in einer Synchronisation steckt und SetWindowPos wiederum auf die WndProc wartet. Ich habe es auch schon mit SWP_ASYNCWINDOWPOS probiert - dann lockt es zwar nicht mehr, dafür bleibt es wirkungslos, da vermutlich trotzdem eine Window-Message bearbeitet werden muss, bevor das Fenster nicht mehr topmost ist.
    Ich muss vermutlich noch mehr Hooks einbauen, nur damit das funktioniert. Ich wollte das eigentlich vermeiden, da das recht aufwändig ist. Für die Hooks benutze ich Detours, ich habe leider keinen Quellcode.



  • Ich verstehe nicht...
    Wie blockierst du bitte den Window-Thread, ohne im Window-Thread selbst zu laufen 😕
    Und wenn du im Window-Thread selbst läufst, dann kannst du auch jederzeit SetWindowPos sagen.

    ps:

    Jodocus schrieb:

    da der Nachrichtenschleifen-Thread vermutlich in einer Synchronisation steckt

    Wieso vermuten? Guck doch nach (Spy++ => Thread ID, Debugger/Pause/Callstack => was dieser Thread macht).



  • hustbaer schrieb:

    Ich verstehe nicht...
    Wie blockierst du bitte den Window-Thread, ohne im Window-Thread selbst zu laufen 😕
    Und wenn du im Window-Thread selbst läufst, dann kannst du auch jederzeit SetWindowPos sagen.

    Die genaue Thread-Situation ist mir leider nicht so klar. Ich vermute, es sieht so aus:

    GUI-Thread: Bearbeitet WndProc, startet einen Worker Thread, wartet auf Ergebnis des Threads
    Worker-Thread: Wird von mir gehookt, Hook ruft SetWindowPos auf --> Call blockiert, da er auf die Behandlung im GUI-Thread zu warten scheint, der wiederum auf das Ergebnis eben dieses Threads wartet --> Deadlock
    

    Oder verstehe ich SetWindowPos falsch?

    Edit: Ja, ich muss mal die Thread-Situation klären. Der Prozess ist für mich im Großen und Ganzen eine Black Box.



  • Zwischenfrage: Hab ich bei den Hooks irgendwas nicht richtig verstanden? Ist es nicht so, dass sich ein WH_CALLWNDPROC Hook in die WNDPROC des Targets zwischenschaltet, dort irgenwas macht und dann eigentlich die originale WNDPROC wieder aufruft und so der ganze originale Käs normal wie gehabt abgearbeitet wird?



  • Jodocus schrieb:

    Edit: Ja, ich muss mal die Thread-Situation klären. Der Prozess ist für mich im Großen und Ganzen eine Black Box.

    Ja, ich denke das wäre von Vorteil 🙂


Anmelden zum Antworten