Suche einfaches Beispiel für AfxBeginTheard
-
Ich frage mich nur ob es für mein Problem nicht eine einfachere Lösung gibt, da ich nur auf eine Button eine Stop Funktion setzten, womit die aktualisierung der Grafik in meinem Dialogfeld aufhört. Brauch ich dazu wirklich theards oder geht's auch anders. Da ich noch nicht so tief in C++ auskenne, empfinde ich das ganze doch als relativ schwierig.
-
Hi,
wenn ich dich richtig verstehe, dann hast du eine zeitraubende Funktion, die eine Grafik aufbaut, und die möchtest du abbrechen können.
Falls das in einer Schleife läuft (der Aufbau der Grafik) dann würde es reichen, wenn du in der Schleife eine Messageverarbeitung einbaust. Ob das einfacher ist als ein Thread, ist wohl Ansichtssache.
Falls du nicht weißt wie das geht, kann ich dir ein Beispiel posten.
Stichworte hierfür sind:
GetMessage
TranslateMessage
DispatchMessageSoweit ich weiß, gibt es auch hier im Forum irgendwo ein Beispiel dafür. Ansonsten frag nochmal nach, wenn du das so realisieren willst.
Grüße, Volle.
-
ein Beispiel wäre super. Ich bin mir nämlich nicht sicher ob ich das richtig verstehe. Hab wirklich erst mit C++ angefangen, und eher alles in einem Crashkurs kurz angeguckt.
Vielen Dank!
-
Hi,
hier, das habe ich bei mir auf die Schnelle gefunden:
MSG msg; for (int i = 0; i < 100; i++) { /*macht irgendwas Zeitaufweniges*/; /*CString*/ sBuf.Format("%u", i); SetDlgItemText(IDC_MY_EDIT, sBuf); if (GetMessage(&msg, this->m_hWnd, WM_PAINT, WM_PAINT)) //hier kannst du filtern, welche Messages durchkommen sollen, //siehe auch MSDN { TranslateMessage(&msg); DispatchMessage(&msg); } }
Das Problem ist bei der for- Schleife ja gleich. Der Prozess ist während der Ausführung blockiert und es werden keine Messages mehr verarbeitet. Durch die Sachen in der if- Verzweigung wird die Verarbeitung gewährleistet.
Hilft das?
Grüße, Volle.
-
ok ich das das ganze mal leicht angepasst und eingesetzt, aber bei mir friert das ganze Dialogfeld ein vereinzelt sehe ich dann auf dem Button "IDC_MESSEN", eine Zahl 0, 20, 86 usw. Ist ja auch klar warum, nur ich kann es nicht abrechen... ich brauche ja diesen Button um die Grafik stoppen zu können zZ stellt sie zwar nichts vernüftiges dar(später soll der balken sich bewegen, aber hab ich schon)
Ich seh' nur nicht ganz wie kann die das Steuerelement filtern, wenn alles einfriert..???
das sind elemten IDC_MESSEN sollte dann Stop sein
void Csm091Dlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Radio(pDX, IDC_SKALA_AUTO, m_select_skala); DDX_Control(pDX, IDC_FREQ, m_freq); DDX_CBString(pDX, IDC_FREQ, m_rfreq); DDX_Text(pDX, IDC_NUMBER_FREQ, m_number_freq); DDX_Text(pDX, IDC_EDIT3, m_current_dbm);//noch anpassen DDX_Text(pDX, IDC_EDIT4, m_current_p);//noch anpassen DDX_Text(pDX, IDC_EDIT5, m_current_pmax);//noch anpassen DDX_Text(pDX, IDC_ACTUAL_FREQ, m_current_freq); DDX_Text(pDX, IDC_EDIT6, m_current_k);//noch anpassen BEGIN_MESSAGE_MAP(Csm091Dlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_MESSEN, OnBnClickedMessen) ON_BN_CLICKED(IDC_SKALA_AUTO, OnBnClickedSelectSkala) ON_BN_CLICKED(IDC_SKALA_DEFINE, OnBnClickedSelectSkala) ON_EN_CHANGE(IDC_NUMBER_FREQ, OnEnChangeNumberFreq) ON_BN_CLICKED(IDC_SET, OnSET) ON_BN_CLICKED(IDC_POS, OnSelect) END_MESSAGE_MAP() // Csm091Dlg Meldungshandler
hier der leicht angepasste code
void Csm091Dlg::OnBnClickedMessen() { for (int i = 0; i < 100; i++) { CDC* pDC = GetDC(); CPen lSolidPen(PS_SOLID,1,RGB(0, 0, 0)); pDC->SelectObject(&lSolidPen); CBrush lSolidBrush(RGB(255, 0, 0)); pDC->SelectObject(&lSolidBrush); pDC->Rectangle(90,0,10,425); MSG msg; /*macht irgendwas Zeitaufweniges*/; /*CString*/ CString sBuf; sBuf.Format("%u", i); SetDlgItemText(IDC_MESSEN, sBuf); if (GetMessage(&msg, this->m_hWnd, WM_PAINT, WM_PAINT)) { TranslateMessage(&msg); DispatchMessage(&msg); } UpdateWindow(); } }
-
hab es nun auf so korrigiert und ich glaub es funktinoiert. der zäler ist auf 1000 und ich kann logischerweise immer unterbrechen und erneut wieder starten, bevor ich bei 1000 bin.
for (int i = 0; i < 1000; i++) { CDC* pDC = GetDC(); CPen lSolidPen(PS_SOLID,1,RGB(0, 0, 0)); pDC->SelectObject(&lSolidPen); CBrush lSolidBrush(RGB(255, 0, 0)); pDC->SelectObject(&lSolidBrush); pDC->Rectangle(90,i,10,425); MSG msg; /*macht irgendwas Zeitaufweniges*/; /*CString*/ CString sBuf; sBuf.Format("%u", i); SetDlgItemText(IDC_MESSEN, sBuf); if (GetMessage(&msg, this->m_hWnd, WM_PAINT, IDC_MESSEN)) //hier kannst du filtern, welche Messages durchkommen sollen, { TranslateMessage(&msg); DispatchMessage(&msg); } UpdateWindow(); UpdateData(FALSE); }
-
wie bringe ich nun meinem Button dazu bei zweiten Mal klick zu stoppen und dann bei ersten wieder erneut anzufangen?!?
Danke!
-
Stop stop
...
probiers mal so
for (int i = 0; i < 1000; i++) { CDC* pDC = GetDC(); CPen lSolidPen(PS_SOLID,1,RGB(0, 0, 0)); pDC->SelectObject(&lSolidPen); CBrush lSolidBrush(RGB(255, 0, 0)); pDC->SelectObject(&lSolidBrush); pDC->Rectangle(90,i,10,425); MSG msg; //das war nur Zeug von mir... //!!!deine GetMessage sollte so aussehen s. u. a. MSDN... //GetMessage(&msg, handle deines Abbrechen- Buttons, BN_CLICKED, BN_CLICKED) sollte klappen... if (GetMessage(&msg, this->m_hWnd, WM_PAINT, IDC_MESSEN)) //hier kannst du filtern, welche Messages durchkommen sollen, { TranslateMessage(&msg); DispatchMessage(&msg); } //für was sind die beiden folgenden Zeilen gut? UpdateWindow();//hier weiß ichs nicht UpdateData(FALSE);//aber das brauchst du nicht, oder? }
Grundsätzlich sollte die for Schleife deine zeitraubende Funktion widerspiegeln. Du brauchst eigentlich nur die Zeilen ab GetMessage
...
Aber der Code den Du gepostet hast, dürfte in ein paar Sekundenbruchteilen ausgeführt sein, oder habe ich was übersehen? Was gibts es da abzubrechen??
Aber wenns geht, dann ist gut
...
Grüße, Volle.
[ Dieser Beitrag wurde am 18.02.2003 um 13:28 Uhr von Volle editiert. ]
-
der balken welcher mit rect zeichnet wird soll eine skala darstellen. Ich hab nur im moment noch hardcoded werte drin, später werden die durch variabeln ersetzte. Diese Balken soll solange tanzen bis der user die darstellung abbricht.
Danke Du hast mir sehr geholfen!
-
mir ist im moment nur ein rätsel wie ich beim zweiten klick aus der schlaufe rauskommen...
-
Hi,
Denkanstoß:
Setze dir ein Flag (z.B. BOOL), mit dem du die Klicks auf den Button zählst. Bei Schleifenabbruch, setzt du das Flag wieder auf Null. Dieses Flag darfst natürlich nicht im lokalen Scope der Funktion definieren.
Das wäre eine Möglichkeit. Da gibt es unzählige Spielarten. Das hängt vom konkreten Kontext ab. Aber das bekommt man hin, wenn man eine Weile drüber nachdenkt...
Grüße, Volle.
-
darauf bin ich auch gekommen.
trotzdem danke!
-
Mano !
Ist da so schwierig einen Thread zu erstellen. Willst du ordnetlich Programmieren oder herumpfuschen.
Für solche Sachen nimmt man Threads und die paar Codezeilen für einen Thread sind ja nun wirklich nicht zuviel verlangt.
-
Das Problem ist das mir die Zeit im Nacken hängt. Mir ist auch klar dass die Theard-Lösung eleganter wäre, bin ja auch zuerst drauf losgegangen, aber in erste Linie solles schnell fertig sein. Und wenn ich später Zeit habe, werde ich mir das alles nocheinmal in Ruhe angucken. Ich sollte auch dringend C/C++ Buch mal lesen, aber aus zeitlich Gründen bin ich da wirklich quer durchgegangen. Aber sicherlich hast Du recht, und es ist keine saubere Lösung!
-
Hi zusammen,
ich hätte ja nichts mehr geschrieben, wenn ihr gesagt hättet, dass man vom Design her besser einen Thread hätte nehmen sollen. Das Programm also grundsätzlich überdenken sollte. Das zu entscheiden, ist bei diesem Informationsstand aber nicht wirklich möglich. Den anderen Weg als "Pfusch" zu bezeichnen, halte ich allerdings für unangebracht.
Wenn das Hauptprogramm nebenher noch Aufgaben zu erfüllen hätte, würde ich mir das ja gefallen lassen. Aber wenn es wirklich nur darum geht, eine Abbruchmöglichkeit zur Verfügung zu stellen, halte ich das für einen klassischen Anwendungsfall dieser Methode. "Keep it simple" ist auch eine Prämisse bei der Programmierung! Ich hätte keine Lust dem Auftraggeber erklären zu müssen, dass ein paar PT für einen "schönen Programmierstil" - oder sollte man sagen, "zur Selbstverwirklichung des Entwicklers" - draufgegangen sind. Das verkauft sich verdammt schlecht.
Grüße, Volle.
-
So nicht richtig.
Ein Dialog ist nichts anderes als ein Thread.
Sollte man jetzt lange Berechnungen in diesem Thread machen reagiert die GUI nicht mehr. Jetzt kann man eine eigene Messageschleife machen wie o.a.Jetzt ist noch das Problem, daß dieser Thread fast die gesamten Resource des Prozessors braucht. Dies löst man in einem Thread indem man ihn für 0 ms schlafen legt. Dh er soll eine Zwangspause einlegen.
Somit werden andere Threads aus anderen Programme auch Zeitfenster zugeteilt und die CPU-Auslastung sinkt.
Dies müsste man nun im GUI-Thread machen. Normalerweise kein problem da es nur ein Sleep(0) ist.
Normalerweise kümmert sich das BS darum dem einzelnen Threads Zeitfenster zuzuteilen. Sollte jetzt aber ein Programm schlecht gecodet worden sein und viel CPU-Zeit benötigen hat mein ein Problem mit o.a. Programm das hier die GUI im sleep hängt.Und Grundsätzlich trennt man GUI immer von Rechenoperationen.
Un keiner kann mir jetzt sagen, daß eine eigene Messageschleife kürzer zum Proggen ist als meine Beschreibung von CWinThread.
-
Ich wusste, dass das Argument kommen würde, dass die GUI grundsätzlich zu trennen ist
...
Aber es besteht durchaus die Möglichkeit, dass das Verhalten so gewollt sein kann. Vielleicht will man sich der Einfachheit halber nicht mit der Synchronisation rumschlagen. Die kostet meist mehr Mühe, wie einen Thread loszutreten. Und sag jetzt nicht, da nehmen wir halt einen boolean. Das ist dann nämlich wirklich "Pfusch". Sicher ist das grundsätzlich nicht der Fall. Aber das hat auch niemand behauptet. Und grundsätzlich ist so ein Design natürlich zu hinterfragen, da gebe ich Dir recht.
Und das Problem mit dem Sleep kann er auch so in der Schleife lösen, wenn er das möchte. Schließlich hängt die ja auch am Hauptthread.
Es geht mir nicht drum, eine Lösung zu favorisieren, aber man sollte die Sache auch nicht zu dogmatisch betrachten.Grüße, Volle.