Problem mit SendMessage/PostMessage



  • Ich habe das Fenster nun einfach anzeigen lassen und alles klappt nach einem Show()-Aufruf. Nun blende ich das einfach aus und es stört nicht in der Anzeige.

    Es wird also irgendetwas mit der Show()-Methode ausgelöst, was erst das Empfangen der Nachrichten möglich macht. Kann mir hier jemand sagen, was das sein könnte? Dann kann ich meinen Code evtl. so umbauen, dass ich das Show() nicht aufrufen brauche. Zwar stört es nicht, aber beim Starten der SW flackert die Anzeige kurz. Das könnte dann auch weg sein.



  • DarkGuardian schrieb:

    Sorry, aber ich bin gestern nicht mehr dazu gekommen.

    Mich würde ja ein NULL beim Konstruktor von TForm schon stutzig machen.

    Wie kann ich denn sonst eine Klasse erstellen, die Windowsnachrichten empfangen kann? Es handelt sich dabei um kein GUI-Element.

    Mit etwas WinAPI... PostThreadMessage wäre wohl dein Freund... Ausserdem hab ich noch was im Usenet gefunden:

    Gambit (TeamB schrieb:

    Inside your Execute() method, you need to use the Win32 API function
    Get/PeekMessage() in a loop. Call PeekMessage() before entering the loop,
    so that the message queue will get created (it's not created by default) and
    be ready for use inside the loop.

    Kann es sein, dass dein Thread loslegt, bevor das Fenster vorhanden ist?
    Kann es sein, dass dein Fenster weg ist, bevor der Thread zu Ende gelaufen ist?



  • Hier noch ne ausführliche Usenet-Diskussion zum Thema Threads mit Message-Queue. Remy Lebeau (Gambit) ist einer der kompetentesten Teilnehmer in den Borland Newsforen und ein Mitentwickler der Winshoes / Indy-Komponenten von TeamB. Es gibt da jemanden der ihm widerspricht. Dabei handelt es sich aber - wie sich im Verlauf der Diskussion rausstellt - um ein Misverständnis des Widersprechenden.



  • Kann es sein, dass dein Thread loslegt, bevor das Fenster vorhanden ist?
    Kann es sein, dass dein Fenster weg ist, bevor der Thread zu Ende gelaufen ist?

    Der Thread wird im Konstruktor des Fensters erzeugt. Daher sollte es da unproblematisch sein. Zudem löscht sich der Thread selbst, nachdem die Execute-Methode beendet wurde. Im Destruktor wird der Thread beendet und dann auf das Ende gewartet.
    Seitdem ich das Fenster zur Anzeige bringe (wenn auch versteckt), treten die Probleme nicht mehr auf.

    Zum Rest werde ich erst mal die Diskussion lesen müssen.



  • Also so wie ich das lese, muss ich bei PostThreadMessage auf eine eingehende Nachricht beim Empfänger pollen. Da dieser in meinem Fall aber Teil des Hauptthreads ist, kommt das nicht in Frage (genauso wie PostMessage).
    Ich sehe zumindest momentan keinen anderen Weg, als die Nachrichten mit SendMessage zu senden.



  • Das Selbe machst du auch bei SendMessage. Da besteht absolut kein Unterschied, ausser das SendMessage auf die Bearbeitung der Nachricht wartet, während PostMessage einfach weiter geht.



  • Bei SendMessage übernimmt Windows das Pollen intern. Ich brauche nirgendwo eine Schleife, die mit GetMessage o.Ä. aufruft. Und aus diesem Grund kann ich auch SendMessage und nicht PostMessage einsetzen.



  • Du hast da was nicht verstanden:

    Post und SendMessage tun beide exakt das Selbe: Sie setzen beim Empfänger eine Nachricht in die Queue. Einziger Unterschied: Sendmessage wartet, bis die versandte Nachricht vom Empfänger aus der Queue geholt wurde.

    Der Empfänger wiederum muss egal mit welcher Methode die Nachricht versandt wurde immer die Queue mit z.B. GetMessage pollen und anfallende Nachrichten verarbeiten.



  • Dann frage ich mich nur, warum Nachrichten mit SendMessage ankommen und verarbeitet werden. Mit PostMessage passiert das nicht.

    Daher gehe ich davon aus, dass bei SendMessage etwas im System ausgelöst wird, was die Verarbeitung der Nachricht auslöst.
    Ursprünglich hatte ich es so verstanden, dass beide Methoden eine Nachricht in der Queue ablegen und nur SendMessage auf eine Rückmeldung wartet. Wenn ich aber nun von den Erfahrungen in meinem Projekt ausgehe, scheint SendMessage eine Verarbeitung anzustoßen und PostMessage nicht (wobei ich PostMessage noch nicht mit GetMessage getestet habe (es passt nicht ins Konzept)).



  • DarkGuardian schrieb:

    Dann frage ich mich nur, warum Nachrichten mit SendMessage ankommen und verarbeitet werden. Mit PostMessage passiert das nicht.

    Weil offenbar SendMessage irgend einen Effekt auf die Laufzeit deines Threads hat und PostMessage nicht? - Btw: Wer löscht eigentlich deine Message-Objekte die du erstellst?

    DarkGuardian schrieb:

    Ursprünglich hatte ich es so verstanden, dass beide Methoden eine Nachricht in der Queue ablegen und nur SendMessage auf eine Rückmeldung wartet.

    Exakt so ist es auch.

    DarkGuardian schrieb:

    Wenn ich aber nun von den Erfahrungen in meinem Projekt ausgehe, scheint SendMessage eine Verarbeitung anzustoßen und PostMessage nicht

    Nur weil vermurkste Software merkwürdige Nebeneffekte erzielt, muss das noch lange nicht für alle gelten. Ich hatte nie probleme mit PostMessage. Ausser ich hab die Queue überfüllt mit zuvielen Nachrichten.

    DarkGuardian schrieb:

    (wobei ich PostMessage noch nicht mit GetMessage getestet habe (es passt nicht ins Konzept)).

    Klar... denn Weder Post- noch SendMessage haben was mit GetMessage zu tun.



  • Weil offenbar SendMessage irgend einen Effekt auf die Laufzeit deines Threads hat und PostMessage nicht?

    Der Unterschied ist der, dass mein Thread auf eine Rückmeldung wartet. Bei PostMessage macht er das natürlich nicht. Aber selbst wenn mein Thread nur ein SendMessage aufruft und danach beendet wird, wird die Nachricht verarbeitet und mit PostMessage geht das nicht.

    Btw: Wer löscht eigentlich deine Message-Objekte die du erstellst?

    Die werden vom empfangenen Objekt gelöscht. Speicherlecks konnte ich auch noch nicht feststellen (zumindest sagt CodeGuard dazu nichts).

    Ich hatte nie probleme mit PostMessage. Ausser ich hab die Queue überfüllt mit zuvielen Nachrichten.

    Wie ich schon einmal erklärt habe, kann ich nicht auf eingehende Nachrichten pollen. Und laut API müsse diese Nachrichten mit GetMessage oder PeekMessage abgerufen werden. Zumindest sagt mir das die Hilfe vom C++Builder. Ich weiß nicht woher du deine Informationen hast, aber die stehen im Gegensatz zu meinen aus der Hilfe.



  • DarkGuardian schrieb:

    Wie ich schon einmal erklärt habe, kann ich nicht auf eingehende Nachrichten pollen.

    Tust du doch sowieso schon... nur merkst dus nicht.

    DarkGuardian schrieb:

    Und laut API müsse diese Nachrichten mit GetMessage oder PeekMessage abgerufen werden. Zumindest sagt mir das die Hilfe vom C++Builder. Ich weiß nicht woher du deine Informationen hast, aber die stehen im Gegensatz zu meinen aus der Hilfe.

    Äh. Was genau führt dich zu der irrigen Annahme, dass zwischen Post- und SendMessage ein Unterschied in der Verarbeitung besteht?

    Nochmal zum Mitschreiben für Analphabeten:
    Funktionen die vom Sender aufgerufen werden
    SendMessage setzt eine Nachricht in die Queue und wartet, bis sie verarbeitet wurde.
    PeekMessage setzt eine Nachricht in die Queue und kehrt gleich danach zurück.

    Funktionen die vom Empfänger aufgerufen werden
    Um die MessageQueue zu leeren, führt der Empfänger zyklisch die Funktion GetMessage aus, welche die Nachrichten aus der Queue lädt und verarbeitet diese zyklisch. Dabei ist der Versandweg schlicht wurst.


Anmelden zum Antworten