dynamische Label



  • 😃

    Manchmal fühle ich mich sooo müde...

    😃



  • Christian2111 schrieb:

    😃

    Manchmal fühle ich mich sooo müde...

    😃

    Ja, das ist nunmal so, wenn man denn Sinn für die einfachsten und sinnvollsten Lösungsansätze verloren hat ....



  • zufaulzumeinloggen schrieb:

    Du übersiehst nur eine Kleinigkeit: Ohne von Zeit zu Zeit ein Application->ProcessMessages() einzufügen, wird nur eine einzige 'Nachricht' angezeigt.

    Wieso sollte dem so sein? Wenns ist, weil irgendwo in nem Button-Click ne Schleife abläuft, dann habe ich dazu bereits Stellung bezogen:

    UnEinloggbar schrieb:

    Joe_M. schrieb:

    Ich kann Dir die Antwort auch direkt geben: Gar nicht! Zumindest solange nicht, wie Du aus der Schleife heraus nicht Application->ProsessMessages() aufrufst.

    Weshalb man ja auf intensive Schleiferei innerhalb eines Eventhandlers wie z.B. ButtonClick verzichten, und derlei Operationen in weitere Threads auslagern sollte...

    Application->ProcessMessages ist ja das was immer, ganz ohne dein Zutun, läuft wenn nicht grade ne Nachricht bearbeitet wird. Das ist ja der Witz daran. Alles und jedes (auch jeder ButtonClick) ist nichts weiter als eine von ProcessMessages() verarbeitete Nachricht. Kannst du auch ganz einfach testen: Mach nen Button der nur

    while(true)
    {
        Application->ProcessMessages();
        Sleep(1);
    }
    

    ausführt. Dazu ein anderer in dessen Eventhandler du nen Breakpoint setzt. Nun klickst du erst auf den ersten Button, dann auf den zweiten. Wenn die Applikation dann anhält, wirst du feststellen, dass im Callingstack zwei mal Application->ProcessMessages() aufgeführt wurde. Der tiefer liegende Aufruf hat die erste Eventhandler-Routine aufgerufen, die höher liegende die zweite mit dem Breakpoint. Das Spiel lässt sich so beliebig fortsetzen.

    @Sphy: DAS wiederum ist nun wirklich unsinnig!



  • 👍



  • remarker schrieb:

    Christian2111 schrieb:

    😃

    Manchmal fühle ich mich sooo müde...

    😃

    Ja, das ist nunmal so, wenn man denn Sinn für die einfachsten und sinnvollsten Lösungsansätze verloren hat ....

    das Joe hier der einzigste ist, der die sache nicht nur von der funktionalität betrachtet, ist schade, und das der einzig sinnvolle und richtige weg der vorgeschlagen wird, irgendwie ignoriert wird, ist auch schade!

    darum @ threadsteller: ließ einfach nur die posts von joe, die anderen wollen oder können es nicht richtig verstehen!



  • Da Joe und Fritz allerdings die Funktionalität nicht ganz verstanden haben können sie auch keine vernünftigen Lösungen hier anbieten.
    Hat ja niemand bestritten das es ab und zu sinnvoll ist, ein ProcessMessages aufzurufen.
    Das mit den Nachrichten im Label ist aber nunmal eleganter über einen Timer zu lösen. Nur um eine Nachricht in einem Label anzuzeigen, gleich seine komplette Anwendung über einen Sleep zu blockieren ist einfach nur schwachsinnig. Sleep ist in diesem Fall einfach nur dirty ...
    Aber naja. Da muss man dann halt mit verschiedenen Meinungen leben ...



  • darum @ threadsteller: Ignorier einfach die sturen Möchtenichtsbegreifer.
    Dont feed the Troll ...



  • teatimer schrieb:

    Da Joe und Fritz allerdings die Funktionalität nicht ganz verstanden haben können sie auch keine vernünftigen Lösungen hier anbieten.
    Hat ja niemand bestritten das es ab und zu sinnvoll ist, ein ProcessMessages aufzurufen.
    Das mit den Nachrichten im Label ist aber nunmal eleganter über einen Timer zu lösen. Nur um eine Nachricht in einem Label anzuzeigen, gleich seine komplette Anwendung über einen Sleep zu blockieren ist einfach nur schwachsinnig. Sleep ist in diesem Fall einfach nur dirty ...
    Aber naja. Da muss man dann halt mit verschiedenen Meinungen leben ...

    wer einen timer als elegant bezeichnet, um einfache "satusanzeigen" wiederzugeben, sollte das hobby wechseln!

    das sleep in anbetracht des problems sicher nciht gut ist, ist klar, aber ein timer....wie gesagt...



  • HINWEIS:
    Zwei mit Beleidigungen gespickte Beiträge von 'teatimer' gelöscht, dasselbe Schicksal wird alle weiteren unsachlichen bzw. OffTopic-Beiträge ereilen.



  • ser1al schrieb:

    remarker schrieb:

    Christian2111 schrieb:

    😃

    Manchmal fühle ich mich sooo müde...

    😃

    Ja, das ist nunmal so, wenn man denn Sinn für die einfachsten und sinnvollsten Lösungsansätze verloren hat ....

    das Joe hier der einzigste ist, der die sache nicht nur von der funktionalität betrachtet, ist schade,

    Funktionalität zu einem brauchbaren Ressourcen Aufwand ist die Devise.

    ser1al schrieb:

    und das der einzig sinnvolle und richtige weg der vorgeschlagen wird, irgendwie ignoriert wird, ist auch schade!

    Welcher? Direkt in das Label zu schreiben? und auf gut Glück etwas "ProcessMessages" aufzurufen? Ich bitte dich! Dann frage ich mich, wieso die Argumente ignoriert werden....

    ser1al schrieb:

    wer einen timer als elegant bezeichnet, um einfache "satusanzeigen" wiederzugeben, sollte das hobby wechseln!

    Ich glaube, in dem Fall sollte ich meinen Beruf wechseln, denn ich arbeite eigentlich nur so, dass die Ausgaben Zeitgetriggert und nicht Eventgetriggert "gerendert" (MAn kann eigentlich nicht immer von rendern sprechen, da irgendwelche LED auf Embeddedsystemen nicht unbedingt "gerendert" werden...) werden. Ihr seid einfach alle zuverwöhnt mit Rechenleistung und seid euch gar nicht bewusst, was es heisst, permanent ein Label neu zeichnen zu lassen.
    An meinem Letzten Arbeitsort wurden übrigens alle Panel Timergetrieben mit etwas zwischen 2 bis 5 Hz gerendert. Probiert doch einfach mal Aktualisierungen > 5Hz selbst mal aus und versucht dann zu urteilen ob ihr derart schnelle Wechsel an Statusanzeigen bevorzugt, geschweige denn erfassen könnt.

    Drehen wirs mal um: Nur weil ihr Hobbiisten keine Relation zur Geschwindigkeit mehr habt, ist das noch lange kein Grund, die wertvollste Ressource in einem PC: Die Rechenzeit sinnlos zu vergeuden.



  • Man erstelle ein neues Projekt.
    2 Button, 2 Label, 1 Memo, 1 Timer
    Man stelle den Timer auf disabled (Wir wollen ja nicht, dass während der gesamten Laufzeit des Programms einmal pro Sekunde, oder sogar noch öfter, das OnTimer-Ereignis durchlaufen wird).
    Die Ereignisfunktionen:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	Button1->Enabled = false;
    	Label1->Caption = "----";
    
    	unsigned int uiStart, uiEnde;
    	int iMax = 100000000;
    	uiStart = GetTickCount();
    
    	for (int j = 0; j < 4; ++j)
    	{
    		for (int i = 0; i < iMax; ++i)
    		{
    			int dummy = 1 * 2;
    		}
    		Label1->Caption = "Durchlauf " + AnsiString(j);
    		Application->ProcessMessages();
    	}
    	uiEnde = GetTickCount();
    	Memo1->Lines->Add("Eventgestuert: " + AnsiString(uiEnde - uiStart) + " ms");
    
    	Button1->Enabled = true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    	Button2->Enabled = false;
    	if (!Timer1->Enabled)
    		Timer1->Enabled = true;
    	Label2->Caption = "----";
    
    	unsigned int uiStart, uiEnde;
    	int iMax = 100000000;
    	uiStart = GetTickCount();
    
    	for (int j = 0; j < 4; ++j)
    	{
    		for (int i = 0; i < iMax; ++i)
    		{
    			int dummy = 1 * 2;
    		}
    		asMessage = "Durchlauf " + AnsiString(j);
    //		Application->ProcessMessages();
    	}
    	uiEnde = GetTickCount();
    	Memo1->Lines->Add("Timergesteuert: " + AnsiString(uiEnde - uiStart) + " ms");
    
    	if (Timer1->Enabled)
    		Timer1->Enabled = false;
    	Button2->Enabled = true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    	if (!asMessage.IsEmpty())
    	{
    		Label2->Caption = asMessage;
    		asMessage = EmptyStr;
    	}
    }
    //---------------------------------------------------------------------------
    

    Einfach mal ausprobieren so. Man wird schnell feststellen, dass bei Button2 keine einzige von den Nachrichten ausgeben wird. Erst wenn das auskommentierte Application->Messages(); (welches nach UnEinlogbars Aussage Glücksspiel ist) in der Button2Click aktiviert wird, wird überhaupt eine Nachricht im Label2 ausgegeben. Allerdings nur die letzte. Jetzt muß man anfangen, mit dem Timerintervall herumzuexperimentieren. Bei einem Intervall von 500 werden immer noch einzelne Nachrichten unterschlagen. Erst bei einem Intervall <= 200 (auf meinem Rechner) werden alle Nachrichten ausgeben. Manchmal wird jedoch auch hierbei noch die letzte Nachricht unterschlagen. Natürlich könnte man den Timer immer aktiviert lassen und dieses Problem damit umgehen, aber dann würde die Timerroutine während der gesamten Laufzeit des Programms 5 Mal in der Sekunde ausgeführt. Das betrachte ich dann allerdings nicht als Ressourcenschonend. Und über die gesamte Laufzeit einer Applikation gesehen, verbrät das garantiert mehr CPU-Zyklen.
    Auf Threads gehe ich hier nicht ein, weil der Fragesteller offensichtlich keine Threads verwendet. Es ist sicherlich sinnvoll, langwierige Berechnungen in Threads auszulagern, allerdings sollten hierbei so wenig grafische Ausgaben, wie irgend möglich getätigt werden, da das Synchronisieren zwischen Thread und Anwendung eine Menge Zeit kostet.

    Und noch einmal: Windows-Timer stehen nur in begrenzter Anzahl zur Verfügung. Wenn also jede Anwendung für jedes Fenster einen Timer zur Anzeige verwenden würde, wären wir bald wieder bei Windows 3.xx Fehlermeldungen a la: Für diese Anwendung stehen nicht genügend Ressourcen zur Verfügung. Schließen Sie eine oder mehrere Anwendungen.



  • Da du offensichtlich nicht gemerkt hast, dass hier ein Applikationsdesign-Problem angeschnitten wurde, gehe ich mal nicht näher auf dein Beispiel ein. Nur soviel: Du hast genau das was ich explizit ausgeschlossen habe gemacht, nämlich eine lange Operation dort hingepflanzt wo sie nicht hingehört: In die Bearbeitung einer Nachrichtenschleife.

    Ich muss dir recht geben: Grafische Ausgaben sollte man bei der Verwendung von Threads auf ein Minimum reduzieren. Ein weiterer Grund, wieso der Thread nicht die Ausgaben via Synchronize und direktem Labelschreiben triggern soll (da wären wir ja wieder soweit wie bei deinen Beispielen. Und da wollen wir ja wirklich nicht hin), sondern die Anzeige sich die nötigen Daten (Durchlauf x von y zum Beispiel) vom Thread über ein Attribut besorgen soll.

    Und noch was: Anzeigen welche mit > 5 Hz ihren Text ändern sind nunmal nichtmehr sinnvoll erfassbar. Klar, rauscht deine Zahl nun schön nach oben. Nur was bringts dir? Denn die einzelnen Zahlen kannst du gar nicht erst lesen.

    Auf Threads gehe ich hier nicht ein, weil der Fragesteller offensichtlich keine Threads verwendet.

    Das ist im Übrigen ein schlechtes Argument. Know why? Wenn man schon sieht dass jemand etwas sagen wir mal nicht allzu elegant löst, dann sollte man ihm die Möglichkeit geben, gleich was dazu zu lernen und ihm die besseren Möglichkeiten aufzeigen.

    Im Übrigen hab ich ProcessMessages() nicht als Glücksspiel bezeichnet. Nur bin ich ein Gegner von schlecht designten Applikationen in welche wahllos (denn sie wissen nicht, wie sies besser tun könnten) ProcessMessages() verteilt wird und man sich schlussendlich drüber wundert, wieso einem irgendwann plötzlich der Stack über geht.

    So Praktisch der BCB hald ist, so sehr verleitet er leider auch (wie VB und andere RAD-Umgebungen) zu vermurksten, ineffizienten Applikationsdesigns.



  • Ahja: ich konnte übrigens in der gesamtem MSDN keine limitation zur Nachricht WM_TIMER, auf welcher die TTimer offensichtlich basieren finden. Da würde ich mich noch über ne Quelle freuen.



  • UnEinloggbar schrieb:

    Da du offensichtlich nicht gemerkt hast, dass hier ein Applikationsdesign-Problem angeschnitten wurde, gehe ich mal nicht näher auf dein Beispiel ein. Nur soviel: Du hast genau das was ich explizit ausgeschlossen habe gemacht, nämlich eine lange Operation dort hingepflanzt wo sie nicht hingehört: In die Bearbeitung einer Nachrichtenschleife.

    Wieso mein Beispiel? Das ist eine leicht modifizierte Version Deines eigenen Beispiels. Ich habe es nur implementiert um Dir die Ineffiziens Deines Vorschlags zu verdeutlichen.

    UnEinloggbar schrieb:

    Ich muss dir recht geben: Grafische Ausgaben sollte man bei der Verwendung von Threads auf ein Minimum reduzieren. Ein weiterer Grund, wieso der Thread nicht die Ausgaben via Synchronize und direktem Labelschreiben triggern soll (da wären wir ja wieder soweit wie bei deinen Beispielen. Und da wollen wir ja wirklich nicht hin), sondern die Anzeige sich die nötigen Daten (Durchlauf x von y zum Beispiel) vom Thread über ein Attribut besorgen soll.

    Jede Übergabe von einem Thread in einen anderen muß zwangsläufige über z.B. eine CriticalSection abgesichert werden. Synchronize macht nichts anderes. Ein direktes Beschreiben von Variablen in anderen Threads führt zu undefiniertem Vrehalten. Also auch wenn man 'nur' die FStatus-Eigenschaft, wie Du sie so schön genannt hast, aktualisieren will, muß dieses über - schlußendlich - eine Synchronize-Funktion realisiert werden.

    UnEinloggbar schrieb:

    Und noch was: Anzeigen welche mit > 5 Hz ihren Text ändern sind nunmal nichtmehr sinnvoll erfassbar. Klar, rauscht deine Zahl nun schön nach oben. Nur was bringts dir? Denn die einzelnen Zahlen kannst du gar nicht erst lesen.

    Was mir nur zeigt, dass Du das Beispiel nicht ausprobiert hast. Da rauscht nichts vorbei. Es werden exakt vier Nachrichten deutlich lesbar ausgegeben. Bei der Eventgesteuerten Methode gezielt und zuverlässig, aber bei Deiner Timer-gesteuerten Variante unzuverlässig und nicht vorhersehbar. Hast Du zur Zeit überhaupt einen BCB um das auszuprobieren?

    UnEinloggbar schrieb:

    Im Übrigen hab ich ProcessMessages() nicht als Glücksspiel bezeichnet.

    Nicht?!?

    UnEinloggbar schrieb:

    Direkt in das Label zu schreiben? und auf gut Glück etwas "ProcessMessages" aufzurufen?

    UnEinloggbar schrieb:

    Nur bin ich ein Gegner von schlecht designten Applikationen in welche wahllos (denn sie wissen nicht, wie sies besser tun könnten) ProcessMessages() verteilt wird und man sich schlussendlich drüber wundert, wieso einem irgendwann plötzlich der Stack über geht.

    Komisch. Ich hab eine gute Handvoll kleiner Programme, bei denen sich mehr Aufwand nicht gelohnt hat. Die laufen, teilweise schon seit mehreren Jahren, bei rund 30 Usern täglich 8 Stunden ohne jegliche Probleme. Schon rein statistisch gesehen, hätten in dieser Betriebszeit etliche Anwendungsfehler auftreten müssen. Sind aber nicht.

    Grüße Joe_M.



  • UnEinloggbar schrieb:

    Ahja: ich konnte übrigens in der gesamtem MSDN keine limitation zur Nachricht WM_TIMER, auf welcher die TTimer offensichtlich basieren finden. Da würde ich mich noch über ne Quelle freuen.

    Schau mal hier
    http://www.opcware.com/XtraTimer/MultimediaTimers.html



  • also ich hab das Problem gelöst.

    aber wie es halt so immer ist,
    man löst das eine Problem und entdeckt dabei ein paar neue.... 😞

    jetzt funzen die Ausgaben im Thread nicht,
    habe das schon gepostet ^^



  • UnEinloggbar schrieb:

    Nun schreit der Schlaue webfritzi aber: Speicherverschwendung! Da kann ich ja grad so gut direkt in die Caption des anzeigenden Labels schreiben.

    Wo nimmst du das her??? Wo habe ich sowas geschrieben? Naja...Analphabeten...

    UnEinloggbar schrieb:

    Die Frage ist allerdings, was die Konsequenz eines Statuslabel->Caption = "neuer Status" ist: In diesem Fall wäre es zum Einen das Überschreiben der Variabel, sowie das anschliessende, rechenaufwendige neuzeichnen des Labels, wenn nicht sogar des ganzen Formulars.
    Dazu kommt, dass bei zu häufigem Statuswechsel (ich sagte ja >2 Hz oder anders ausgedrückt häufiger als alle 500ms) der Benutzer das angezeigte sowieso nicht lesen kann, daher also auch die Anzeige nonsens ist.

    Völlig überflüssig, was du hier schreibst, denn:

    WebFritzi schrieb:

    alles reinschreiben ins Label ist Quatsch, da zu schnell, um es zu lesen. Ich denke, da sind wir uns alle einig.

    Und dann schreibst DU sowas wie

    UnEinloggbar schrieb:

    Also nochmals zum mitzeichnen für Analphabeten:

    LOL 😃

    UnEinloggbar schrieb:

    Wozu nun also der Timer? Ganz einfach: In der Timer-Intervall-Routine steht nichts weiter als Statuslabel->Caption = FStatus. Dies führt dazu, dass das Formular nur alle 500ms damit b elästigt wird, sich neu zu zeichnen und ich mir die sonstigen unnötigen Rechenzyklen erspare.

    Die Idee ist natürlich richtig. Aber die Umsetzung ist falsch. Wieso? Weil ein TTimer ungenau ist und sich das ganze auch anders lösen lässt: GetTickCount:

    DWORD last_tickcount = GetTickCount();
    DWORD tick_count;
    schleife
    {
       //FStatus wird gesetzt
       tick_count = GetTickCount();
       if( tick_count - last_tickcount < 500 )
       {
          Label->Caption = FStatus;
          last_tickcount = tick_count;
       }
    }
    

    Mal ganz abgesehen davon, dass 500 ms viel zu kurz sind für eine Status-Anzeige. Zumindest, wenn die Status-Meldungen etwas länger sind.



  • Joe_M. schrieb:

    timerfreund schrieb:

    Einfach nen Timer nehmen ...

    Ja, man kann auch eine Three-Tier Datenbankanwendung schreiben, um ein einziges Textdokument zu verwalten...

    LOLLLLLL - der war gut 😡


Anmelden zum Antworten