Grafikausgabe verursacht "keine Rückmeldung" in der Title-Bar der Anwendung
-
Es ist echt traurig, daß auf diese Art (professionelle) Software entwickelt wird...
Dann scheint auch eure gesamte Anwendungsarchitektur nicht zu stimmen (wenn ihr mit solchen Hacks arbeitet - darum verstehe ich auch nicht den Aufruf von SB_SIMPLE ?!).
-
wieso wie macht man das denn sonst?
-
@Th69
Es gibt Verbesserungspotential!Wegen SB_SIMPLE ...
Ich habe einfach nach etwas gesucht, das den geringsten Einfluss hat.Dass ich bald was Besseres brauch, weiss ich auch.
Nur im Moment arbeiten wir an einer Testanlage und der entsprechende Prozess läuft gerade.Bisher war die Ausgabe auch ok, da die Datenmenge meist nur ein paar hundert Daten enthält.
Nur plötzlich die Zwickmühle...
-
Der einfachste Weg ist die Synchronisierung per
SendMessage
Nebenläufiger Thread:
- erhält das Fensterhandle des Fensters, in dem das Diagramm angezeigt wird.
- liest die Daten ein und bereitet sie auf.
- meldet dem Zielfenster per
SendMessage
, dass die Daten zur Anzeige bereit sind. In welcher Form auch immer, ob das jetzt schon eine fertige Bitmap ist oder sonstwas. Hier bietet sich eine Kapselung der Daten in einemunique_ptr
an. - zurück zur Datenaufbereitung
Hauptfenster:
- startet den nebenläufigen Thread zur Datenaufbereitung
- stellt eine Behandlungsfunktion für benutzerdefinierte Fensternachrichten zur Verfügung
- in dieser Behandlungsfunktion übernimmt es die Daten des nebenläufigen Threads und kümmert sich um die Anzeige. Dazu kann es notwendig sein, dass die Daten zwischengespeichert werden müssen, weil sie erst während der Behandlung einer
WM_PAINT
Fensternachricht benötigt werden. Da sollte man sich überlegen, ob die Daten perunique_ptr
gekapselt werden können und das Hauptfenster sie dem Thread einfach wegnimmt, indem derunique_ptr
den Besitz über die Daten übernimmt.
Der Vorteil bei
SendMessage
ist, dass der Aufruf erst zurückkehrt, wenn die Fensternachricht im Erstellerthread des Fensters behandelt wurde. Das heisst, dass der Thread so lange wartet, bis die Nachricht im Hauptfenster der Anwendung behandelt wurde und macht dann erst weiter. Die Synchronisierung wird einem also vom Betriebssystem geschenkt, da muss man sich um nichts mehr selber kümmern.
-
@DocShoe
Vielen Dank DocShoe.
Das werde ich auch in die Änderungen einfliessen lassen.
-
Nochmal zur Schnelllösung:
Das mit dem "SendMessage(..)" hatte leider nur scheinbar ausgereicht.
Das mit dem "PeekMessage(..)" + REMOVE + Translate..() + Dispatch.. ginge zwar, macht aber TeamViewer Sitzung unbrauchbar.Eine "ordentliche" Lösung ist in der Kürze nicht machbar!!!
Was gäbe es noch, um dem Windows eine Rückmeldung zu geben,
damit die Meldung: "keine Rückmeldung" nicht kommt?Denn durch diese Meldung komme ich in eine Endlosschleife!
Gäbe es eine bestimmte Message von Windows, auf die ich mit "PeekMessage(..)" reagieren könnte,
die den Teamviewer, etc. nicht stört?
Aber eine, die auch sicher öfter gesendet wird.
-
Also...
Alle Windows Anwendungen mit Fenstern sind nachrichtengesteuert, d.h. iwo in deiner Anwendung muss es einen Funktionsblock geben, der Nachrichten aus der Nachrichtenqueue holt und verarbeitet. Normalerweise macht man das perGetMessage()
, man kann sich aber auch was mitPeekMessage()
undPM_REMOVE
basteln. Die Benutzung der Funktionen erzeugt per se keine Endlosschleife bzw. Stillstand des Programms. Und dass die Benutzung vonPeekMessage()
den TeamViewer stört kann ich mir auch nicht vorstellen. Es sei denn, man baut in seiner Anwendung Mist.
-
also eigentlich gibt es in der winmain eine endlosschleife, die die ganzen nachrichten verarbeitet und die callbackfunktion aufruft. man kann das aber auch alles weglassen und ohne nachrichten arbeiten, wenn man das denn unbedingt will.
ich weiß jetzt nicht, warum das so schwer ist, die berechnungen in einen thread auszulagern und von dort aus die entsprechenden nachrichten zum neuzeichnen auszulösen.
-
Das grundsätzliche Problem ist eben, dass du in den DC des Fensters zeichnest:
case WM_PAINT: BeginPaint(...); Sleep(10000); // langer Zeichenvorgang EndPaint(...);
Wenn dieser Zeichenvorgang abgeschlossen ist, kann es sein (bzw. ist es, nachdem Windows Inaktivität festgestellt hat, sehr wahrscheinlich), dass direkt die nächste Paint-Nachricht reinkommt und das Spiel beginnt von vorne.
Darum kam eben der Vorschlag mit dem double-buffering. Nur, wenn es nötig ist, in eine Bitmap zeichnen und diese im Paint-Zweig blitten (und keinesfalls dabei neu hineinzeichnen).Das kann (und sollte eigentlich auch) natürlich auch noch beliebig erweitert werden: Ein eigenes Control für die Bitmap, das vom Scrollen (über Scrollbars und Mausziehen) bis Zoomen selbst alles übernehmen kann, einen anderen Thread fürs Zeichnen verwenden, für eine bessere Navigation den Zeichenvorgang aufteilen (bspw. erst das Koordinatensystem zeichnen und wenn das Navigieren abgeschlossen ist, die Messwerte einzeichnen), ...
Am grundsätzlichen Problem ändert das allerdings nichts.
-
Das mit dem Teamviewer und "PeekMessage" berichtet mir mein Kollege,
der die Testanlage betreut.
Ich konnte es mir auch nicht vorstellen.
Aber wahrscheinlich sendet der dauernd was und meine Anwendung nimmt diese Nachrichten weg.
Auf meinem Entwicklungsrechner passiert nichts weiter, wenn ich das PeekMessage auf alle Handles und alle Messages anwende.
Wenn ich allerdings den Filter auf WM_TIMER setze, wird die Toolbar nicht mehr refreshed.Seltsamerweise passieren die Effekte mit dem endlosen Neuzeichnen der Grafik nicht auf meinem Entwicklungsrechner
In das Thema mit dem Thread muss ich mich für den speziellen Fall erst einarbeiten.
Ihr habt zwar ein paar Einstiegsgedanken gegeben, aber probieren muss sich das halt.