Anfängerfrage zu Anwendung mit mehreren Dialogfeldern



  • Hallo C++Community,

    ich habe eine dialogfeldbasierende Anwendung, die nacheinander weitere Dialogfelder öffnet [xxx.DoModal()].

    Während ein solches Dialogfeld aktiv ist, tritt folgendes Verhalten auf:

    - Wenn ich den Fokus auf ein Fenster eines anderen Programmes wechsele und dann wieder zurück, wird der Inhalt meines Dialogfeldes nicht mehr korrekt angezeigt, sonder bleibt dort, wo sich die Fenster überlappten weiß.

    - Manchmal - leider nicht 100%ig reproduzierbar - wenn ich, während ein zweiter Dialog offen ist, auf das "Haupt"-Dialogfeld dahinter klicke, dann bekommen beide ein "Not Responding" bis der zweite Dialog seine Arbeit beendet hat.

    Die Dialogfelder reichen von Statusanzeigen, bei denen viel gerechnet wird, über Dialoge, in denen Bilder angezeigt werden, bis hin zu Threads, die über den Status von Vorgängen im Hauptprogramm informieren.

    Vielen Dank im Voraus für Eure Anregungen,
    ..Kyer



  • Wenn dein zweites modales Fenster noch arbeitet, stellt sich mir die
    Frage, ob du da auch Threads für verwendest?!

    Damit sollten eigentlich die weißen Ränder nicht erzeugt werden.
    Ggf. mal im Thread das Fenster updaten/refreshen?

    Was passiert, wenn du ein nicht modales Fenster verwendest und die
    Hauptanwendung solange sperrst, bis das nicht modale mit seiner
    Arbeit fertig ist?



  • - Wenn ich den Fokus auf ein Fenster eines anderen Programmes wechsele und dann wieder zurück, wird der Inhalt meines Dialogfeldes nicht mehr korrekt angezeigt, sonder bleibt dort, wo sich die Fenster überlappten weiß.

    Dialoge haben im gegensatz zu "normalen" fenster oft die eigenschaft das es nicht stets neu gezeichnet wird, erklaere einfach die gesammte ansicht als ungueltig, dann erzwingst du ein neu zeichnen (this->InvalidateRect)

    - Manchmal - leider nicht 100%ig reproduzierbar - wenn ich, während ein zweiter Dialog offen ist, auf das "Haupt"-Dialogfeld dahinter klicke, dann bekommen beide ein "Not Responding" bis der zweite Dialog seine Arbeit beendet hat.

    wenn ich dich richtig verstehe moechtest du wenn ein dialog offen ist in einen anderen dialog arbeiten,
    wenn dem so ist darfst du das dialog nicht mit "DoModal" generieren sondern mit "Create" und dann anzeigen wenn gebraucht

    da du fuer alles ein eigenen dialog hast musst du schon alle dialoge mit Create erstellen, bei DoModal ist immer nur das eine benutzbar



  • Vielen Dank für Eure schnellen Antworten.

    Xyz12 schrieb:

    ... die Hauptanwendung solange sperrst, ...

    Wie mache ich das?

    Mr Evil schrieb:

    ..., erklaere einfach die gesammte ansicht als ungueltig, dann erzwingst du ein neu zeichnen (this->InvalidateRect)

    Leider ändert das nichts, das Fenster bleibt weiß. Außerdem bringt der häufige Aufruf meine Statusanzeige zum flackern.

    wenn ich dich richtig verstehe moechtest du wenn ein dialog offen ist in einen anderen dialog arbeiten

    Nein, das möchte ich nicht. Ich möchte nur das "Not responding" vermeiden, wenn man unsinnig herumklickt.

    Der Einzige Thread, den ich verwende, dient lediglich zur Statusanzeige, den erzeuge ich so:

    {
    	int status=1;
    	AfxBeginThread(HeaderStatusThread,(LPVOID) &status);
    
    	while (status<=22)
    	{
    		// do stuff
    		status++;
    	}
    }
    
    UINT CFlight2dbDlg::HeaderStatusThread(LPVOID param)
    {
    	int *pos=(int*)param;
    	CStatusHeaderDlg* pStatus;
    	pStatus = new CStatusHeaderDlg;
    	CWnd window;
    	pStatus->Create(IDD_DIALOG_STATUSDIALOG, &window);
    	pStatus->ShowWindow(SW_SHOW);
    	pStatus->m_status.SetRange(0,22);
    	while(*pos<22)
    	{
    		pStatus->m_status.SetPos(*pos);
    		window.RedrawWindow();
    		Sleep(100);
    	}
    
    	return 0;
    }
    

    Hier kommen ja schon ein paar Eurer Vorschläge zur Anwendung, leider ist das Verhalten wie beschrieben.

    Noch ein Hinweis:
    Wenn ich als weiteren Dialog einen öffne (mit DoModal), der nur Eingabefelder und Buttons enthält, ist alles kein Problem: klicke ich dann aufs Hauptfenster im Hintergrund, gibt es einen Sound und der Fokus bleibt auf dem neuen Dialog. Auch wenn ich kurz ein anderes Fenster darüberschiebe, zeichnet es sich beim Zurückwechseln perfekt neu.

    Habt Ihr noch weitere Ideen?

    ..Kyer



  • Hat noch jemand eine Idee hierzu?



  • Du solltest eher die Statusanzeigen etc. im Hauptprogramm erledigen und für deine langwierigen Berechnungen Zusatzthreads anlegen, die im Hintergrund arbeiten (und irgendwann melden, daß sie fertig sind). Damit reduzieren sich die Nachrichtenhandler im Hauptprogramm darauf, den entsprechenden Thread zu starten (danach ist das Programm wieder bereit für weitere Nachrichten - inklusive WM_PAINT (sagt dem Fenster, daß es sich neu zeichnen soll) und der "bist du noch da?"-Nachricht vom Task-Manager).



  • Danke für Deine Antwort.

    CStoll schrieb:

    Du solltest eher die Statusanzeigen etc. im Hauptprogramm erledigen und für deine langwierigen Berechnungen Zusatzthreads anlegen, die im Hintergrund arbeiten (und irgendwann melden, daß sie fertig sind). Damit reduzieren sich die Nachrichtenhandler im Hauptprogramm darauf, den entsprechenden Thread zu starten (danach ist das Programm wieder bereit für weitere Nachrichten - inklusive WM_PAINT (sagt dem Fenster, daß es sich neu zeichnen soll) und der "bist du noch da?"-Nachricht vom Task-Manager).

    Das macht Sinn, nur habe ich verschiedene Anzeigen bei den Rechenvorgängen (eine Statusanzeige, eine zeigt Bilder, eine Text ...), und die alle im Hauptdialogfenster unterzubringen, in dem ganz andere Dinge passieren und das schon voll von Editboxes und Buttons ist, sieht sehr sehr unschön aus.

    Außerdem wird mit hundert Variablen gerechnet, diese mit einer LPVOID an die static Thread-Funktion zu übergeben wäre umständlich, und ein Auslagern der Variablen in eine Datei zwar simpel aber auch nicht gerade sauber. Ist das Standard bei visueller Programmierung mit Dialogen? (wie man merkt, komme ich von der Konsole)

    Wenn ich Dich richtig verstehe, ist das Programm während es nicht idle ist, nicht empfänglich für Nachrichten? (Dann gäbe es wohl keine Lösung, was mich wundert, da mir die Anforderung garnicht als so speziell erscheint.)

    Hast Du vielleicht doch noch eine Idee, das Programm in seiner jetzigen Struktur zu retten?


Anmelden zum Antworten