Dialog in extra Thread anzeigen
-
hallo zusammen,
ich hab wieder mal ein kleines problem.
ich habe eine anwendung in welcher ich auf tastenklick ein paar aktionen nacheinander ausführe. während dieser aüsführungen ist jeder klick auf andere controls ohne funktion, was auch so sein soll. soweit alles ok
nun hatte ich den gedanken während dessen einen extra dialog anzuzeigen, welcher nix weiter tun soll, als einen progressbar in einer definierten zeit zu zeichnen und sich dann wieder selber zu schließen.
soweit so gut, wenn ich den cdialog direkt zu beginn meiner aufgaben modal anzeige, wird er komplett angezeigt, funktioniert auch schön, und wieder geschlossen. allerdings, wie es ja logisch ist, bleibt die abarbeitung der weiteren aufgaben stehen, bis der modale dialog geschlossen ist.
nun hatte ich die idee den dialog in einem cwinthread anzuzeigen, um nebenbei weiter arbeiten zu können. ich hab als am anfang meiner aufgabenliste folgendes eingefügt://button betätigt... CWinThread* WaitThread; WaitThread = AfxBeginThread( ShowWaitDlg, 0, THREAD_PRIORITY_NORMAL, 0, 0, NULL); ProcessMessages(); //restliche arbeit läuft...die Funktion zum anzeigen habe ich global hinzugefügt:
UINT ShowWaitDlg(LPVOID pParam) { //WaitDlg anzeigen CWaitDialog wdlg; wdlg.m_iTime=5; wdlg.DoModal(); return true; }nun habe ich aber das Problem, das der dialog erst angezeigt wird, wenn alle anderen arbeiten vorüber sind, also zu spät

ich habe auch probiert direkt nach dem erzeugen des threads die windowsmessages zu verarbeiten:
//button betätigt... CWinThread* WaitThread; WaitThread = AfxBeginThread( ShowWaitDlg, 0, THREAD_PRIORITY_NORMAL, 0, 0, NULL); ProcessMessages(); MSG msg; while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } //restliche arbeit läuft...leider auch ohne erfolg.
kann mir noch jemand einen tipp geben wie ich dies bewerkstelligen kann?danke ks
-
Ich seh da zwei Möglichkeiten:
1. Du erstellt deinen Dialog in dem Thread mit Create (also ebend nicht Modal) was die einfachste Variante is
2. Du erstellt den Dialog außerhalb deines Thread und sendest den aktuellen Status aus deinem Thread zu deinem Dialog mit PostMessage oder SendMessage je nachdem wie wichtig dir die Anzeige des Status is.
UINT ShowWaitDlg(LPVOID pParam) { //WaitDlg anzeigen CWaitDialog wdlg; wdlg.m_iTime=5; wdlg.Create(IDD_WaitDlg,this); //eventuell eine Schleife { //mach was wdlg.SetStatus(x); //Progressbar neu setzen } wdlg.Destroy(); return true; }Gruß Matthias
-
diese idee hatte ich auch schon. leider sehe ich da gar nichts.
ich habewdlg.Create(IDD_WAIT_DIALOG,AfxGetMainWnd());geschrieben, da es keinen globalen this zeiger gibt. aber für den thread brauch ich ja ne globale funktion von bestimmten eigenschaften, sonst geht es gar nicht.
oder ich versuch nochmal den zeiger in ne globale variable zu schreiben, vielleicht geht das...
komisch war nur, das er wohl in die oninitdialog rein kam, als ich es noch modal anzeigen wollte, aber angezeigt hat er es dann erst mit allen funktionen ganz am ende.
ich werd das mit dem zeiger nochmal probieren...
-
ich habe es jetzt auf folgendes geändert:
UINT ShowWaitDlg(LPVOID pParam) { //WaitDlg anzeigen CWaitDialog wdlg; wdlg.Create(IDD_WAIT_DIALOG,NULL); wdlg.ShowWindow(SW_SHOW); wdlg.Invalidate(); for(int i=0;i<10;i++) { MSG msg; while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(1000); } return true; }leider wird es immer noch, erst angezeigt, wenn der rest abgearbeitet wurde.
ich nehme fast an es liegt an dem thread. da ich nur einen workerthread erstelle.
kann es sein, das alle grafischen funktionen nur funktionieren, wenn ich eine neue klasse von cwinthread ableite und in dieser dann den dialog anzeige?
würde ja heißen das man in einem workerthread gar nicht zeichen kannn oder sowas?
hm, ich werd noch etwas rumtesten
-
Du mußt schon alles was ich da geschrieben habe in deinen Thread packen und in der for-Schleife das machen was du eben machen willst. Oder zeig mal wie du deinen Thread startest und die Funktion die du aufrufst. Oder anders gesagt Du mußt schon das was du ausführen willst (zeitaufwendige Arbeiten) IN der Thread legen.
Gruß Matthias
-
das einzige was ich nicht drin habe, aus deinem beispielcode, ist doch das .destroy. alles andere hab ich doch drin?!
den thread starten mach ich wie schon oben beschrieben, daran hab ich nichts geändert. und in AfxBeginThread rufe ich die ShowWaitDlg auf, wie ich sie gepostet habe.
der thread soll ja nicht die zeitaufwendigen dinge machen, das soll ja das hauptprogramm tun. ich wollte den thread ja nur haben, um einen fortschritt anzeigen zu können. deshalb wollte ich ihn ja in einem extra thread starten, das er auf alle fälle läuft.
-
Hallo,
klsc schrieb:
der thread soll ja nicht die zeitaufwendigen dinge machen, das soll ja das hauptprogramm tun.
Das ist unüblich, und nicht der geeignete Weg, um so etwas zu realisieren. Die rechenintensiven Arbeiten sollten in den Thread verlagert werden, der vom "Hauptprogramm" abgespalten wird.
MfG,
Probe-Nutzer
-
Lies mal
http://www.microsoft.com/msj/0798/c0798.aspxDa werden zwei Methoden diskutiert!
Zudem solltest Du immer AfxPumpMessage verwenden!