Alternate 1

C++ Variablenwert dauerhaft aktualisieren

TheShooter

Lt. Junior Grade
Registriert
Juni 2011
Beiträge
370
Hi,
ich möchte gerne den Wert einer sich ständg verändernden Variable anzeigen lassen.
Die Variable wird folgendermaßen verändert:
Code:
while(finish == 0)
				 {
                                         ...
					 i = i + 1;
					 textBox2->Text = System::Convert::ToString(i);
                                         ...
                                 }
Das Problem ist, dass während die while-Schleife läuft, also die Variable "finish" auf 0 steht, das Programm einfach nicht mehr reagiert. Sobald allerdings "finish" = 1 ist, und die while-Schleife nicht mehr aktiv ist, funktioniert alles wieder. Nun möchte ich, dass textBox2 dauernd mit dem Wert i aktualisiert wird, auch während die While-Schleife läuft. Dies sollte dann natürlich auch auf der Ausgabe aktualisiert werden. Wie realisiere ich das?
Wäre dankbar für Hilfe!

Beste Grüße,
TheShooter
 
Zuletzt bearbeitet:
Deine UI, also deine Anzeige, aktualisiert nicht selbstständig, wenn du in deiner While-Schleife bist. Es gibt einen Befehl, der deiner UI sagt, dass sie updaten soll. Ich weiß allerdings nicht, wie der in C++ heißt.
 
In der While-Schleife fehlt ja auch die Abbruch-Bedingung. Es ist quasi eine Endlos-Schleife. Was Du suchst sind Events(-Handler) bzw. Listener.
 
schau mal ob du im web ein snippet findest, indem gezeigt wird wie man das mit progressbars darstellt. die haben das selbe problem.
 
Ich habe zuerst an Multithreading gedacht, würde es vielleicht so gehen?
Eine Abbruch-Bedingung habe ich natürlich auch:
Code:
while(finish == 0)
				 {
					   if(i == password)
					  {
						  finish = 1;
						  label5->Visible = false;
						  label4->Text = L"Password found";

					  }
					 i = i + 1;
					 textBox2->Text = System::Convert::ToString(i);

				 }
 
Womit machst du deine UI?

Ich weiß nur dass MFC es dir übel nimmt wenn du in einem anderen Thread direkt per Pointer eine MessageBox aktualisierst.

Schick im 2. Thread BEI AKTUALISIERUNG eine Message an das Parent Window, welches daraufhin alle betroffenen Felder updated. Warum BEI AKTUALISIERUNG: Man sollte keine Message-Flug auslösen, denn dann gehen auch mal Messages verloren.

Alternative wäre ein Timer, der alle 500ms ein Update macht.
 
Das Problem ist, dass i mehrere hundert mal pro Sekunde aktualisiert wird. Wie checke ich denn, ob i aktualisiert wurde?
 
Das hier:
TheShooter schrieb:
Code:
	 i = i + 1;
	 textBox2->Text = System::Convert::ToString(i);
sieht mir sehr nach .NET bzw. C++/CLI aus (also nix mit MFC oder so). Erst einmal solltest du, wenn du in .NET proggst, lieber C# nehmen, das ist um Längen einfacher als C++/CLI und für jemanden, der aus der C++ Ecke kommt, auch sehr leicht zu lernen. Da sähe dein Code dann so aus:
Code:
	 i = i + 1;
	 textBox2.Text = System.Convert.ToString(i);
Zu deinem eigentlichen Problem: du willst in einer GUI-Anwendung einen Code ausführen, dessen Ausführung sehr lange dauert. Im Prinzip gibt es dafür zwei Wege:

  1. Du unterbrichst die Ausführung des Codes in regelmäßigen Abständen, um die Ereigniswarteschlange des Programmfensters abzufragen, in .NET geht das AFAIK mit Application.DoMessages(). Natürlich solltest du das nicht zu oft tun, nicht öfter als etwa 10 mal pro Sekunde. Wenn deine Schleife also mehrere 100 mal pro Sekunden durchlaufen wird, ist es sinnvoll, es nur bei z.B. jedem 50. Durchlauf zu machen. Das sähe dann so aus (in C++/CLI):
    Code:
    while(finish == 0)
    {
        ...
        i = i + 1;
        if (i % 50 == 0)
        {
            textBox2->Text = System::Convert::ToString(i);
            Application::DoMessages();
        }
        ...
    }
  2. Multithreading. Du startest einen eigenen Thread, in dem der Code ausgeführt wird. Wenn du allerdings Zwischenergebnisse des Codes - hier: Änderungen von i - in der GUI ausgeben willst, musst du dafür sorgen, dass die Ausgabe im Hauptthread erfolgt (gerade .NET ist da sehr pingelig), und es gilt auch da wieder, dass die Ausgabe nicht zu oft gemacht werden sollte, da der Code sonst ausgebremst wird. Das könnte dann z.B. so aussehen:
    Code:
    while(finish == 0)
    {
        ...
        i = i + 1;
        if (i % 50 == 0)
        {
            Changed(i);
        }
        ...
    }
    Dabei ist Changed() ein Event, der von einem Delegate abonniert werden muss, der für die Darstellung in der GUI sorgt (Stichwort: Delegates und Events in .NET). Um die Ausführung im Hauptthread zu erreichen, muss die Delegate-Methode noch ein Invoke() machen, siehe hierzu Form.Invoke() und Form.InvokeRequired. Wohlgemerkt gilt das nur für eine Windows Forms-GUI, für eine WPF-GUI ist es noch anders.
In deinem Fall würde ich allerdings den ersteren Weg (ohne Multithreading) für den praktikableren halten.
 

Ähnliche Themen

Zurück
Oben