Funktion aus anderem Dialog rufen



  • Zu meinem Problem:

    Ich habe zwei Dialoge in meiner Anwendung und möchte
    aus dem Hauptdialog den anderen aufrufen.

    Aus diesem zweiten Dialog soll nun eine Funktion des Hauptdialog
    ausgeführt werden. Und ich weiss einfach nicht wie man das machen
    kann.

    Habe ich überhaupt diese Möglichkeit?


  • Administrator

    Du übergibst dem zweiten Dialog einen Zeiger auf deinen ersten Dialog. Über den Zeiger kannst dann die Funktion aufrufen? Ist doch ganz einfach ^^

    Grüssli



  • Habe das mal probiert und es geht auch schon.
    Aber sobald er die Funktion aufruft beendet sich mein Programm.
    Die Funktion selbst wird nie ausgeführt. Alle nötigen Include
    sind gesetzt.

    CenumwinDlg *penumwin; 
     penumwin->screenshot();
    


  • Hallo,

    Du musst dem Zeiger noch die Adresse des Hauptdialoges zuweisen...

    Also so in etwa...

    CenumwinDlg *penumwin = &DeinHauptDialog;
    penumwin->screenshot();

    Ohne diese Zuweisung zeigt der Zeiger ins Nirvana. Deshalb schmiert
    dein Programm auch beim Funktionsaufruf ab.


  • Administrator

    Lotti schrieb:

    Habe das mal probiert und es geht auch schon.
    Aber sobald er die Funktion aufruft beendet sich mein Programm.
    Die Funktion selbst wird nie ausgeführt. Alle nötigen Include
    sind gesetzt.

    CenumwinDlg *penumwin; 
     penumwin->screenshot();
    

    Ganz ehrlich eine Frage. Ist es nicht ultra logisch, dass sowas nicht funktionieren kann? Woher soll dein Programm wissen auf welches CenumwinDlg Objekt der Zeiger zeigt? Ein Zeiger ist die Speicheradresse eines Objekts. Wenn sowas noch nicht weisst, dann würde ich vorschlagen, dass du noch ein paar Tutorials durcharbeitest.

    Grüssli



  • Dravere schrieb:

    Lotti schrieb:

    Habe das mal probiert und es geht auch schon.
    Aber sobald er die Funktion aufruft beendet sich mein Programm.
    Die Funktion selbst wird nie ausgeführt. Alle nötigen Include
    sind gesetzt.

    CenumwinDlg *penumwin; 
     penumwin->screenshot();
    

    Ganz ehrlich eine Frage. Ist es nicht ultra logisch, dass sowas nicht funktionieren kann? Woher soll dein Programm wissen auf welches CenumwinDlg Objekt der Zeiger zeigt? Ein Zeiger ist die Speicheradresse eines Objekts. Wenn sowas noch nicht weisst, dann würde ich vorschlagen, dass du noch ein paar Tutorials durcharbeitest.

    Grüssli

    Wenn ich mir deinen ersten Post hier im Forum ansehe stelle ich auch nur
    fest, dass mit dir auch kein Meister vom Himmel gefallen ist....

    Wir fangen eben alle mal klein an. Immer daran denken 💡


  • Administrator

    @Semiprofi ... Das ist mir auch klar. Ich würde auch selber von mir sagen, dass ich bei weitem noch kein Profi bin. Ich würde mich selber sogar immer noch in den Bereich fortgeschrittener Neuling einsortieren 😉
    Und ja ich habe auch mal angefangen, aber das ist doch sowas von logisch. Ein Zeiger ist die Adresse auf den Speicher und man muss dem Zeiger sagen auf welchen Speicher er zeigen soll. Das wäre ja meiner Mutter klar, dass man den zuerst initialisieren muss oder die Adresse zuweisen muss, bevor man ihn benutzen kann.

    Mir geht es auch nicht darum jemanden schlecht zu reden. Es fällt mir einfach nur immer wieder auf, dass verdammt viele Hilfesuchende keinen einzigen Gedanken mitdenken. Die meisten machen sogar einfach nur Copy&Paste. Dann schreibt man:

    CBeispielDlg* pBeispielDlg = &DeinBeispielDlg;
    pBeispielDlg->DeineFunktion();
    

    Und die kopieren das 1 zu 1 rüber und meckern dann drüber, dass es nicht funktioniere. Indem Fall war es jetzt nicht so, aber es ist doch sowas von LOGISCH, dass man dem Zeiger sagen muss, wohin er zeigen soll. Man müsste halt nur mal selber mitdenken, aber das scheint völlig zu viel verlangt zu sein. Ich frage mich da aber wieso? Ich dachte die Leute wollen proggen lernen und beim lernen sollte man doch wirklich etwas mitdenken oder nicht?

    Ok ist jetzt das falsche Forum. Und ich konnte es jetzt einmal nicht mehr zurückhalten. Tut mir leid, dass es dein Thread war Lotti.

    //////////////////////////////////////////////////
    // DeinHautDialog -> cpp Datei
    
    #include "DeinZweiterDialog.h"
    
    // ...
    
    void CDeinHauptDialog::IrgendEineFunktion()
    {
        CDeinZweiterDialog dlg;
        dlg.SetMainDlgPointer(this);
        dlg.DoModal();
    }
    
    // ...
    
    //////////////////////////////////////////////////
    // DeinZweiterDialog -> h Datei
    
    class CDeinHauptDialog;
    
    // ...
    
    class CDeinZweiterDialog : public CDialog
    {
        // ...
    private:
        CDeinHauptDialog* m_pMainDlg;
    
        // ...
    public:
        void SetMainDlgPointer(CDeinHauptDialog* pPointer) { m_pMainDlg = pPointer; };
        // ...
    }
    
    //////////////////////////////////////////////////
    // DeinZweiterDialog -> cpp Datei
    
    #include "DeinHauptDialog.h"
    
    // ...
    
    CDeinZweiterDialog::CDeinZweiterDialog(CWnd* pParent /*=NULL*/)
        : CDialog(CDeinZweiterDialog::IDD, pParent)
        , m_pMainDlg(NULL)
    {
    }
    
    // ...
    
    void CDeinZweiterDialog::IrgendEineFunktionVomZweitenDialog()
    {
        if(pMainDlg != NULL)
        { m_pMainDlg->ScreenshotOderWasAuchImmer(); }
    }
    
    // ...
    

    Bevor du DoModal aufrufst, übergibst du über eine Funktion den Zeiger auf deinen Hauptdialog. this ist immer der Zeiger auf das Objekt, in welchem this steht.
    Beim initialisieren im Konstruktor setzt du m_pMainDlg auf NULL. So kannst du mit der if Anweisung überprüfen, ob ein Zeiger gesetzt wurde oder nicht. So wird verhindert, dass der Zeiger nicht ins nichts hinein zeigt.

    Das "class CDeinHauptDialog;" ist eine Vordefinition. Man kann damit Zeiger definieren ohne die Klasse in der .h Datei zu includieren. In der .cpp muss dann aber alles includiert sein.

    Das ist auch noch eine Lösung:

    //////////////////////////////////////////////////
    // DeinHautDialog -> cpp Datei
    
    #include "DeinZweiterDialog.h"
    
    // ...
    
    void CDeinHauptDialog::IrgendEineFunktion()
    {
        CDeinZweiterDialog dlg(this);
        dlg.DoModal();
    }
    
    // ...
    
    //////////////////////////////////////////////////
    // DeinZweiterDialog -> cpp Datei
    
    #include "DeinHauptDialog.h"
    
    // ...
    
    void CDeinZweiterDialog::IrgendEineFunktionVomZweitenDialog()
    {
        CDeinHauptDialog* pDlg = reinterpret_cast<CDeinHauptDialog*>(GetParent());
        if(pDlg != NULL)
        { pDlg->ScreenshotOderWasAuchImmer(); }
    }
    
    // ...
    

    Wenn du deinen zweiten Dialog konstruierst, dann kannst du ihm ein Parent Window angeben. Also ein Fenster zu welchem dein zweiter Dialog quasi gehört. So muss man keine eigene Variable erstellen, sondern kann die von CWnd gleich benutzen. CDialog ist ja auch von CWnd abgeleitet. Das reinterpret_cast<> ist ein C++ Casting. Gibt davon verschiedene, kannst mal in der MSDN nachschauen.

    (CDeinHauptDialog*)GetParent();
    

    Ist ein C Casting und ein wenig unsicherer, zwar vielleicht nicht unbedingt in dem Fall, aber es lohnt sich, das ganze anzugewöhnen.

    Noch fragen?

    Grüssli


Anmelden zum Antworten