Dialog wird nicht angezeigt



  • Hallo zusammen!

    Hab ein kleines Problem:

    Ich hab mir für meine MDI-Anwendung einen kleinen Splashscreen erstellt, der wie üblich ein paar Registrierungs-, Copyright- und Versions-Informationen anzeigt.

    Von der CSplashDlg-Klasse habe ich in meiner Main-App eine Member-Variable m_splashDlg, welche ich in InitInstance mittels

    m_splashDlg.Create(IDD_SPLASH);
    

    anzeigen lasse. Im OnInitDialog des Splash-Dialogs starte ich nun einen Timer, der 5 Sekunden rennt.

    Der Dialog wird also entweder beendet, wenn der Timer abgelaufen ist, oder der User mit der Maus auf diesen klickt. In OnTimer, OnLButtonDown, OnRButtonDown, OnMButtonDown wird jeweils die Methode DestroyWindow() aufgerufen.

    Weiters habe ich OnDestroy nun folgendermaßen überschrieben damit der Timer auch wieder gestoppt wird (wahrscheinlich nicht nötig, wenn ich den Dialog sowieso mit DestroyWindow() abschieße?):

    void CSplashDlg::OnDestroy()
      {
      CDialog::OnDestroy();
    
      if (m_bAutoHide)
        KillTimer(m_nTimer);
      }
    

    Jetzt mein Problem:

    Ich will den selben Dialog als Info-Dialog anzeigen lassen, also steht in meiner Main-App in OnAppAbout() nun folgendes:

    m_splashDlg.SetAutoHide(false);
    m_splashDlg.DoModal();
    

    Durch SetAutoHide(false) wird im Splash-Dialog ein Flag gesetzt, durch welches der Timer nicht gestartet und natürlich beim schließen auch nicht gelöscht wird (siehe OnDestroy() oben).

    Das Problem ist nun, dass der Dialog zwar gestartet wird und auch für einen Bruchteil einer Sekunde sichtbar ist, danach aber sofort wieder unsichtbar wird. Wenn ich nun zB. ins Visual Studio wechsle ist er wieder für einen ganz kurzen Moment sichtbar und verschwindet wieder.
    Das Programm ist nicht bedienbar (dh. der Dialog existiert) und wenn ich in etwa auf den Bereich klicke, wo der Dialog eigentlich sein sollte "verschwindet" er auch wieder, dh. die OnLButtonDown-Überschreibung wird aufgerufen (mittels Breakpoint getestet).

    Wo kann nun das Problem liegen und wie kann ich das umgehen? Hab auch schon versucht im OnAppAbout() eine neue Dialog-Instanz anzulegen und diese anzuzeigen (mit DoModal(), Create(...) oder ShowWindow(SW_SHOW)), allerdings verhält sich das ganze dann ziemlich ähnlich bzw. gleich.

    danke, mfg


  • Mod

    Fensterspezifische Timer brauchst Du nicht "killen"!

    Setz doch mal Spy++ ein und schau was für Meldungen gesendet werden.
    Wird irgendwo EndDialog bei Dir in Deinem Code aufgerufen?

    Setz einen Breakpoint in OnDestroy und schau in den Callstack wer die Funktion aufgerufen hat!



  • Ok, dachte ich mir schon, dass das killen nicht nötig ist.

    OnDestroy wird "immer" von OnLButtonDown aufgerufen soweit ich das überblicken kann. Also auch wenn der Splash-Dialog nicht sichtbar war und ich im Hauptfenster der Anwendung auf den "eigentlichen" Bereich des Splash-Dialogs klicke.

    Übrigens verschwindet der Splash dann doch nicht anstandslos sondern löst ein Assert aus, wie in diesem Screenshot ersichtlich. Woran kann das liegen, dass IsWindow hier das Assert auslöst bzw. warum handelt es sich bei meinem Dialog um kein Fenster?

    Mit Spy++ habe ich noch nicht soviel Erfahrung und weiß nicht genau, worauf ich dabei achten soll, aber ich werds mal ausprobieren und schauen, ob ich dabei was rausfinden kann.


  • Mod

    Es ist anders. Dein Dialog existiert nicht mehr, wenn Du das SendMessage ausführst.

    Wenn Du den Dialog mit DoModal erzeugst, dann darfst Du nicht mehr DestroyWindow verwenden, sondern musst EndDialog verwenden!



  • Ok danke für die Berichtigung, allerdings erklärt das noch immer nicht, warum der Dialog nie wirklich sichtbar ist. Hast du dazu vielleicht auch noch eine Idee?

    Den Umgang mit Spy++ hab ich noch nicht ganz kapiert, bei meinem Versuch vorhin die Messages ein wenig zu verfolgen hab ich es geschafft das ganze Programm samt Visual Studio und Explorer zum Stillstand zu zwingen 😉 (Spy++ war als einziges Programm noch bedienbar).

    Vielleicht kannst du mir ein paar Tips geben, wie ich Spy++ anwenden soll und worauf ich achten muss?

    danke, mfg


  • Mod

    1. Spy++ nie mit dem Debugger zusammen laufen lassen.
    2. Einfach mal alles protokollieren lassen und versuchen rauszubekommen was mit Deinem Fenster passiert.

    Ich vermute mal, dass Deine Nachrichtenschleifenicht verlassen wird, weil EndDialog nicht aufgerufen wird.
    Theoretisch darf OnDestroy gar nicht aufgerufen werden wenn Du den Dialog anzeigst. Also was passiert im Callstack? Wer ruft DestroyWindow auf? Das kannst Du doch rausbekommen im Debugger!



  • Problem gelöst:

    Der Dialog war auf Transparent gestellt. aaaaaaaaaaaahhhhhhhhhhhhhhhh
    Keine Ahnung, warum er beim Programmstart korrekt angezeigt wurde...

    Danke für die zahlreiche Hilfe. Irgendwie ist heute nicht mein Tag...

    ps.: Danke für den Tipp mit Spy++ und Debuggen. Werde ich mir bestimmt merken 😉


Anmelden zum Antworten