CProgressCtrl hängt hinterher
-
Hallo Forum,
ich bin zum wiederholten mal über das Problem gestolpert, dass ein CProgressCtrl der aktuell gesetzten Position jeweils um einen Schritt hinterherhängt.
Ich habe zum Test eine dialogbasierte Minianwendung geschrieben. Der Dialog enhält einen Button und ein CProgressCtrl.
Folgender Code wird beim Click auf den Button ausgeführt.
void CMFCApplication1Dlg::OnBnClickedButton1() { m_progressbar.SetPos(0); m_progressbar.SetPos(50); m_progressbar.SetPos(100); }
Wenn ich mir das mit dem Debugger anschaue, passiert nach "SetPos(50)" noch gar nichts. Nach "SetPos(100)" wird ein Progress von 50 angezeigt und erst nach dem Verlassen der Methode steigt der Progress auf 100.
Wenn ich nach dem Thema suche, stolpere ich immer wieder über Hinweise, dass das eine Design-Entscheidung sei und damit zu tun habe, dass der Progress nicht zum nächsten Schritt "springt" sondern "animiert langsam dorthin fortschreitet" (http://stackoverflow.com/questions/2217688/windows-7-aero-theme-progress-bar-bug). Außer irgendwelchen abstrusen Workarounds wie auf der verlinkten Seite beschrieben, habe ich allerdings keine wirkliche Lösunge gefunden bzw. weiß nach wie vor nicht, wie man das richtig macht.
Ich habe kurz getestet, ob bei einer Wartezeit ich etwas von dieser Animation sehe, aber auch das ändert nichts:
void CMFCApplication1Dlg::OnBnClickedButton1() { m_progressbar.SetPos(0); m_progressbar.SetPos(50); std::thread t([] { Sleep(5000); }); t.join(); m_progressbar.SetPos(100); }
Vielleicht kann mir irgendjemand einen Tipp geben...
Vielen Dank vorab.
-
Fortschritt schrieb:
Ich habe kurz getestet, ob bei einer Wartezeit ich etwas von dieser Animation sehe, aber auch das ändert nichts:
Wie soll dein Programm irgendetwas animieren, wenn es im join feststeckt?
-
Sorry, das join sollte eigentlich hinter den SetPos(100).
void CMFCApplication1Dlg::OnBnClickedButton1() { m_progressbar.SetPos(0); m_progressbar.SetPos(50); std::thread t([] { Sleep(5000); }); m_progressbar.SetPos(100); t.join(); }
Das ändert das Verhalten aber nicht. Der Progress bleibt bei 0 hängen, bis join ausgeführt wurde und die Methode verlassen wird. Dann sehe ich direkt den Progress von 100.
-
...noch eine Ergänzung:
Wenn ich die "Visual Styles" deaktiviere (https://social.msdn.microsoft.com/Forums/en-US/41b69474-5ce7-48bc-a079-843953115175/cprogressctrlsetpos-not-updating-to-set-position?forum=vcmfcatl), die offensichtlich dieses animierte Verhalten gebracht haben, verhält sich das genau so, wie ich es erwarten würde.Die Deaktivierung ist aber leider keine Option und auch grundsätzlich wüsste ich einfach gerne, wie das gedacht ist.
-
Fortschritt schrieb:
Das ändert das Verhalten aber nicht. Der Progress bleibt bei 0 hängen, bis join ausgeführt wurde und die Methode verlassen wird. Dann sehe ich direkt den Progress von 100.
Das ist das erwartete Verhalten.
Solange du in diesem OnClicked-Handler steckst, wird nichts neu gezeichnet. Du blockierst die Aktualisierung selbst.
-
MFK schrieb:
Solange du in diesem OnClicked-Handler steckst, wird nichts neu gezeichnet.
Das ist schlicht und ergreifend falsch!
Wie schon in meinem ersten Post beschrieben, wird sehr wohl etwas neu gezeichnet, solange ich in diesem Handler stecke, nur eben entsprechend verzögert.
Völlig verzögerungsfrei erfolgt die Darstellung wenn diese "Visual Styles" (siehe ebenfalls vorheriger Post) deaktiviert sind. Was es genau damit auf sich hat, weiß ich zugegebenermaßen nicht. Trotzdem würde mich interessieren wie ich das zuvor bekannte Verhalten erzielen kann.
Wenn dazu jemand noch konstruktive Vorschläge machen kann, wäre ich sehr dankbar.
-
Es wird nichts gezeichnet wenn Du in dem Sleep steckst. Punkt!
Du kannst evtl. durch ein UpdateWindow ein Zeichnen erzwingen, aber grundsätzlich kann "während" einem Sleep kein Fenster, dass durch Deinen Thread erzeugt wurde neu gezeichnet werden.