Programmende während ShowMessage()



  • Hallo!

    Ich habe ein minimales Test-Programm, das bei einem Buttonklick einen Thread erstellt und dieser Thread dann nur ShowMessage("Test") ausführt. Das erste Problem ist schon mal, dass die MessageBox nicht aufgeht.
    Schließe ich nun das Hauptfenster der Anwendung oder führe durch einen Button auf dem Hauptfenster Application->Terminate() aus, bekomme ich eine Zugriffsverletzung.

    Das ganze konnte ich mit dem BCB5 und 6 auf XP nachvollziehen. Auf W98 gab es keine Probleme: Die MessageBox ging auf und entsprechend gabs auch beim Programmende keine Fehlermeldung.

    Hier mal der Quellcode der Unit1 (Hauptfenster):

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        Application->Terminate();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        TTest *t = new TTest(false);
    }
    

    Und hier der Thread (TThread-Nachfahre):

    void __fastcall TTest::Execute()
    {
        ShowMessage("Test");
    }
    

    Benutze ich stattdessen

    MessageBox( Application->MainForm->Handle, "Test", "", MB_OK );
    

    sieht man die MessageBox und ich kann dann auch nicht das Hauptfenster schließen, da sie modal ist. Also muss es etwas damit zu tun haben, dass das ShowMessage-Fenster kein ParentWindow hat.

    Meine Frage nun:
    Wie schaffe ich es, die Anwendung zu beenden, wenn ein ShowMessage-Fenster eines anderen Threads, das nicht modal über dem Hauptfenster liegt, aktiv ist(egal ob sichtbar oder nicht) ?



  • hallo,

    immer wenn man auf elemente des vcl-hauptthreads zugreift, muß man dies in einer mehtode tun, die anschließend von synchronize aufgerufen wird, synchronize führt diesen quelltext dann im kontext des vcl-hauptthreads auf. messagebox ist im gegensatz zu showmessage eine api-routine, läuft also nicht im kontext des vcl-hauptthreads. in win98 hat es nur durch zufall geklappt, da nicht unbedingt etwas schieflaufen muß, die wahrscheinlichkeit aber gegeben ist...
    in quellcode ausgedrückt heisst dies folgendes:

    class TMyThread : public TThread
    {
    private:
    protected:
    	void __fastcall Execute();
    public:
    	void __fastcall GuiElements(void);
    	__fastcall TMyThread(bool CreateSuspended);
    };
    
    void __fastcall TMyThread::GuiElements(void)
    {
    	ShowMessage("ShowMessage aus dem Thread!");
    }
    
    void __fastcall TMyThread::Execute()
    {
    	Synchronize(GuiElements);
    
    }
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	Application->Terminate();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    	MyThread = new TMyThread(false);
    }
    


  • MessageBox(NULL, "Test", "", MB_OK );
    

    Damit ist die MessageBox nicht modal, die Anwendung kann somit jederzeit beendet werden.



  • Hey super!

    Vielen Dank!
    Ihr habt mir sehr geholfen.


Anmelden zum Antworten