MessageBox Probleme



  • Hallo zusammen,

    habe irgendwie Probleme mit MessageBoxen.
    Sobald man das Programm schließen will, kommt eine Sicherheitsabfrage ob man wirklich beenden will.
    Beispielsweise so :

    void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
    {
    	if(Application->MessageBox(L"Wirklich beenden ?",L"BEENDEN",MB_YESNO) == 6){
    		frmMain->Close();
    	}
    }
    

    oder so :

    void __fastcall TfrmMain::btnBeendenClick(TObject *Sender)
    {
    	if(Application->MessageBox(L"Wirklich beenden ?",L"BEENDEN",MB_YESNO) == IDYES){
    		frmMain->Close();
    	}
    }
    

    Normalerweise sollte nachdem man bei der MessageBox auf 'Ja' klickt das Programm beenden und bei 'Nein' einfach weiter laufen.
    Jedoch kommt die MessageBox nur wieder wenn man auf 'Ja' klickt und bei 'Nein' schließt das Programm.

    Danke & Gruß
    ITB



  • Deine erste Sicherheitsabfrage gehört in FormCloseQuery, in der der Parameter CanClose dann entsprechend gesetzt wird.



  • Ich denke, das Verhalten kommt daher, dass du im Falle von ID_YES noch ein Mal Close() aufrufst. In den Close Methode wird dann noch ein Mal der OnClose Event Handler aufgerufen und darin wieder die MessageBox angezeigt.
    Wenn du das im OnClose Handler lösen möchtest solltest du nicht Close aufrufen, sondern so

    void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
    {
       if(Application->MessageBox(L"Wirklich beenden ?",L"BEENDEN",MB_YESNO) != IDYES)
       {
          // wenn das Ergebnis NICHT Ja ist keine weiteren Aktionen ausführen
          Action = caNone;
       }
    }
    

    Wenn du´s richtig machen möchtest setz´ Burkhis Vorschlag um: Verschieb´ die Abfrage in den OnCloseQuery Handler und setz´ da ggf. den Referenzparameter CanClose auf false.



  • Super, danke euch.
    Hat geholfen.
    Was ich aber trotzdem nicht verstehe, warum das mit dem btnBeendenClick nicht richtig funktioniert.
    Bei vorherigen Programmen hat das geklappt.
    Da hatte ich es entweder so :

    void __fastcall TfrmMain::btnBeendenClick(TObject *Sender)
    {
    	if(Application->MessageBoxW(L"Wirklich beenden ?",L"BEENDEN",MB_YESNO) == IDYES){
    		frmMain->Close();
    	}
    }
    

    oder so :

    void __fastcall TfrmMain::btnBeendenClick(TObject *Sender)
    {
    	if(Application->MessageBoxW(L"Wirklich beenden ?",L"BEENDEN",MB_YESNO) == 6){
    		frmMain->Close();
    	}
    }
    

    Beides hat früher funktioniert.



  • Hast du denn in beiden Funktionen (FormClose und btnBeendenClick) die Abfrage drin?

    Dann ist ja klar, daß bei 'Beenden' zweimal die Abfrage kommt...

    Es reicht, nur in FormClose (bzw. wie schon geschrieben besser nur in FormCloseQuery) die Abfrage drin zu haben und bei 'Beenden' nur Close aufzurufen:

    void __fastcall TfrmMain::btnBeendenClick(TObject *Sender)
    {
    	Close(); // "frmMain->" ist unsinnig!
    }
    


  • Das zweimalige Aufpoppen der Meldungsbox kommt daher, dass du im OnClose Event Handler noch ein Mal Close() aufrufst. Wenn die Meldungsbox immer mit "Ja" schließt sähe der Callstack in etwa so aus:

    Close()
    => OnFormClose()
      => Close();
        => OnFormClose()
          => Close()
            OnFormClose()
    

    Das terminiert erst dann, wenn du die Meldungsbox mit "Nein" beendest. Und weil du in dem Fall die CloseAction nicht anfasst wird das Fenster endlich geschlossen.

    Das ist was ganz anderes, als wenn du aus einem anderen Handler Close() aufrufst. Im OnClose Aufruf hat der Referenzparameter CloseAction standardmäßig den Wert caFree, d.h. wenn du den nicht anfasst wird das Formular geschlossen. Wenn du aber im OnClose Handler wiederum Close() aufrufst landest du in einer Rekursion. Dein Code macht prinzipiell nichts anderes als das hier:

    void __fastcall TMyForm::OnFormClose( TObject* Sender, TCloseAction& Action )
    {
       if( MessageDlg(...) == ID_YES )
       {
          OnFormClose( Sender, Action ); // => Rekursion!
       }
    }


  • Verstehe ich.
    Jetzt ergibt das zwei mal aufploppen Sinn.

    Danke euch 🙂


Log in to reply