ApplicationEvents + SendMessage



  • Ach so, natürlich. Du kannst die Message auch ganz normal an Form1 schicken und dann in Application->OnMessage auswerten. Diese Behandlungsroutine fängt alle Messages ab, die an irgendwelche Forms gesendet werden. Fazit: du brauchst die WindowProc deiner Form nicht zu überschreiben.



  • Das geht eben nicht.
    Ich komm an die, mit SendMessage verschickten Nachrichten nur, wenn ich die WndProc überschreibe. Das ist es ja, was ich nicht so ganz verstehe, so rein nach dem Lesen der Doku, hätte ich behauptet, dass es egal ist, ob ich PostMessage oder SendMessage verwende.



  • Würde ich jetzt auch so denken. Du hast oben aber geschrieben

    SendMessage(Application->Handle, MTESTMESSAGE, 0, 0);
    

    und hast gesagt, dass da nichts ankommt. Das ist dann bei folgendem auch so, ja?

    SendMessage(Form1->Handle, MTESTMESSAGE, 0, 0);
    

    Vielleicht liegt es ja auch irgendwie an deiner Message...



  • Korrekt, weder bei

    SendMessage(Application->Handle, MTESTMESSAGE, 0, 0);
    

    noch bei

    SendMessage(Form1->Handle, MTESTMESSAGE, 0, 0);
    

    kommt die Nachricht bei den App-Events an.
    Sobald PostMessage verwendet wird, funktioniert es mit beiden Handles.
    An der Nachricht kann es nicht liegen, definiert ist sie als

    #define MTESTMESSAGE (WM_APP + 400)
    

    Wenn es weder bei PostMessage, noch bei SendMessage funktionieren würde...

    Mit den Nachrichten möchte ich verschiedene Threads durch die Application koordinieren. Bei PostMessage können Nachrichten verloren gehen, ohne dass ich eine Möglichkeit habe das zu prüfen. Bei den maximal alle 5 Sekunden abgesetzen Statusmeldungen ist mir das egal. Aber ich muß gesichert feststellen können, ob ein Thread beendet wurde, oder ein neuer erzeugt wurde.
    Nun gut, werde ich eben die WndProc überschreiben... Kann ich durchaus mit leben. Ich hatte nur gehofft, dass das Problem schon mal jemand hatte und mit vielleicht die Hintergründe für dieses Verhalten erklären kann. Vielleicht versuche ich auch die Koordination in einen eigenen Thread zu verlagern, sofern es mir gelingt, in TThread Nachrichten abzufragen. Ich werde mich nachher mal kurz mit GetMessage und PeekMessage beschäftigen.

    Vielen Dank für Deine Hilfe, WebFritzi.



  • Wie wärs, wenn du die Koordination nicht über Messages, sondern mit Hilfe von Callback-Funktionen machst?



  • Öh. Du hast mich hängen. Ich wüßte nicht, wie mir eine Callback-Funktion hier helfen könnte.



  • Ich weiß nun nicht genau was du machen willst.
    Ich hab mir das so gedacht.
    Du definierst im Hauptthread eine CallBackfunktion, die du deinem Nebenthrad übergibst. Das könnte eine externe Funktion oder auch eine statische Memberfunktion einer Klasse sein. Diese Funktion benötigt evtl noch einen Pointer auf die Hauptthreadklasse und/oder die nebenthreadklasse (kann auch auf dessen Basisklasse sein). Dann rufst du diese Funktion im Nebenthread bei Bedarf einfach auf.
    Ich mach das bei mir zumindest so um das Schliessen des Nebenthreads zu signalisieren (in OnClose oder im Destruktor des Nebenthreads).



  • Ich sehe schon, in Punkto Threads brauch ich wohl noch ein bißchen Nachhilfe.
    Bisher habe ich so etwas mittels TThread::Synchronize() und TThread::OnTerminate() gemacht. Wobei beides als recht inperformant einzustufen ist. Die Idee mit den Messages hatte ich, als ich nach einer Möglichkeit gesucht habe, das Synchronize für das UI-Update zu ersetzen. Und da das mit den Nachrichten sehr gut funktioniert hat, hab ich ein bißchen weiter experimentiert. Dabei habe ich dann festgestellt, dass leider Nachrichten verloren gehen können, wenn der Application-Thread ausgelastet ist und hab versucht die wichtigen Nachrichten per SendMessage zu versenden...

    Werd ich mal ausprobieren. Diese Woche aber nicht mehr, da ich eben noch eine Änderung für ein anderes Projekt aufgedrückt bekommen habe...



  • Das mit dem Callback hat nur eine grosse Nase: Du hälst dir damit den Thread wieder auf. Die Callbacks müssten also so kurz wie möglich sein, während du mit der Nachrichtenverarbeitung und z.B. PostMessage eine sehr lose Kopplung erreichen würdest.

    Was mir spontan auffällt ist, dass deine Testnachricht nicht 400 über WM_USER sondern über WM_APP liegt. Ich habe bisher immer nur mit WM_USER gearbeitet... Wobei ich grade gelesen habe, dass WM_APP auch für Custom-Nachrichten wäre. Mit welcher VCL-Version arbeitetst du? Version 6?



  • UnEinloggbar schrieb:

    Das mit dem Callback hat nur eine grosse Nase: Du hälst dir damit den Thread wieder auf.

    Ja, das muß ich wohl in Kauf nehmen, da bei PostMessage Nachrichten verloren gehen können. Praktisch ist für meine Anwendung nur wichtig, zu erfahren, wann ein Thread beendet ist. Ob ich das nun über SendMessage, oder eine Callback-Funktion mache, dürfte keinen großen Unterschied machen, da der Thread bei beiden Varianten wartet. Die anderen Nachrichten werde ich weiterhin über PostMessage absetzen. Die können auch ruhig verloren gehen, da sie nur Statusmeldungen sind (Thread gestartet, Thread angehalten, Prozent fertig) und nur für das UI verwendet werden.
    Aber ich werde noch testen, ob in einem Controller-Thread die mit PostMessage vesendeten Nachrichten auch verloren gehen. Die Nachrichten gehen nämlich immer dann verloren, wenn ich in der MainForm, welche auch die Nachrichten verarbeitet, irgendetwas mache (das Form verschieben, in den ListBoxen scrollen...).

    UnEinloggbar schrieb:

    Was mir spontan auffällt ist, dass deine Testnachricht nicht 400 über WM_USER sondern über WM_APP liegt.

    Ob WM_APP, oder WM_USER dürfte keine Rolle spielen, solange ich die Nachrichten nur Anwendungsintern versende.

    UnEinloggbar schrieb:

    Mit welcher VCL-Version arbeitetst du? Version 6?

    Ja, ich hab noch den BCB 6.


Anmelden zum Antworten