tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
7
ZUGRIFFE
2565
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    JoachimJogi JoachimJogi ist offline Mitglied
    Registriert seit
    Feb 2007
    Beiträge
    22
    Hi,

    ich kann mir nicht vorstellen, dass mein Problem ein "spezielles" ist, eher ein ganz alltägliches und ich suche nur in die falsche Richtung. Daher wäre ich dankbar, wenn mir jm. auf die Sprünge helfen könnte und sagen wie die "richtige" Lösungsvariante ist.

    Das Testprogramm soll so aussehen
    http://jogipalace.jo.funpic.de/mfc/demo.jpg

    Zur besseren CodeÜbersichtlichkeit, ist der "dünne Rahmen" ein eigener Dialog. Das muss ich so machen, weil hier später ein CTabCtrl hinkommt, indem auch jedes Tab ein eigener Dialog ist.
    Ich möchte durch das Betätigen des Button1 einen Text in der Editbox ausgeben. Das Problem ist, dass die Editbox von einem anderen Dialog stammt.

    Wie mache ich das?

    =======================

    Meine bisherige Lösungsvariante ist:

    CMyTestDlg* p; // Das hier ist der "innere" Dialog
    p = (CMyTestDlg*) AfxGetApp()->m_pMainWnd;
    p->testMethode(); // Diese Methode des "äußeren Dialoges" schreibt einen Text

    Diese Methode ist sehr unschön, da dieser 3Zeiler in jeder Funktion, in der ich etwas ausführen will reingeschrieben werden muss.

    Ich vermute stark,d ass an meinem Gesamtkonzept etwas nicht stimmt. Daher die allgemeine Frage: Wie realisiert man einen Dialog auf dem zb ein CTabCtrl und andere Elemente zu sehen sind? Irgendwie müssen die Tab Seiten auch Zugriff auf den Rest haben

    VIELEN DANK!
     

  2. #2
    JoachimJogi JoachimJogi ist offline Mitglied
    Registriert seit
    Feb 2007
    Beiträge
    22
    Ich kann meine Frage auch umformulieren:

    Nehmen wir, ich habe einen (Haupt)Dialog mit einem TabCTrl. Hierbei kann man zwischen verschiedenen Tabs, also zwischen verschiedenen Dialogen umschalten. (TabDlg1,TabDlg2, ...)

    auf TabDlg5 möchte ich ein Log integrieren. Wenn man zb auf TabDlg1 einen Button drückt, soll im Editfeld auf TabDlg5 ein Eintrag erscheinen.

    Wie mache ich das? Ich hab inzwischen eine ganze Reihe an Foren (auch englische) durchgearbeitet und stoße immer wieder auf den umgekehrten Fall (Wie spreche ich eine EditBox in einem TabDialog aus dem Hauptdialog an). In meinem FAll möchte ich aber aus einem Tab Dialog einen anderen Tab Dialog ansprechen (bzw ähnlicher Fall: aus einem Tab Dialog den Hauptdialog).


    P.S.: Bitte jetzt nicht den Hinweis, dass Logging in Dateien gehört. Hierbei handelt es sich um ein konstruirtes Beispiel.

    Vielen Dank!!
     

  3. #3
    Avatar von Endurion
    Endurion Endurion ist offline Mitglied Diamant
    Registriert seit
    Apr 2004
    Beiträge
    2.151
    Ich weiss nicht, warum so viele Leute ein Problem mit sowas haben, nur weil es nicht in ein OOP-Design-Pattern passt.

    Du brauchst einen Pointer auf den anderen CDialog. Irgendwo erstellst du den ja. Jetzt pappst du den Pointer irgendwo hin, wo du vom anderen CDialog aus Zugriff drauf hast.

    Das kann jetzt global rumliegen (nicht so schön) oder in die CWinApp als Member aufgenommen werden.

    Du kannst auch den Constructor von dem einen CDialog um einen Parameter erweitern, der einen Pointer auf den anderen CDialog übernimmt. Da musst du dann nur bei der Erstellreihenfolge aufpassen.

    Auf kurz: Du brauchst etwas, dann pack es irgendwo hin, wo du drauf zugreifen kannst.
     

  4. #4
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Im Spezialfall TabCtrl kannst du dir den Pointer zum Dialog über die Methode "GetItem()" von CTabCtrl holen:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    // Im Click-Eventhandler von TabDlg1 ausführen
     
    TCITEM item;
    item.mask = TCIF_PARAM;
    ((CTabCtrl *)GetParent())->GetItem(4 /*die 5. Tabkarte*/, &item);
        
    CTabDlg5 *pDlg = (CBTabDlg5 *)item.lParam;
        
    if( pDlg && ::IsWindow(pDlg->GetSafeHwnd()) )
    {
        // irgendwas tun
    }
    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  5. #5
    JoachimJogi JoachimJogi ist offline Mitglied
    Registriert seit
    Feb 2007
    Beiträge
    22
    @Endurion: Leider kommt es mir überhaupt nicht so vor, als ob dieses Problem viele Leute haben. Ich habe wircklich schon viele Tutorials und Foren gelesen, stoße aber nicht auf dieses Themengebiet.

    Dein Satz "Auf kurz: Du brauchst etwas, dann pack es irgendwo hin, wo du drauf zugreifen kannst." trifft es genau richtig! Danke! (Manchmal braucht man einfach eine Bestätigung, dass es ganz einfach ist)


    @MCoder: Dir natürlich auch vielen Dank für den "Tipp" mit GetItem.

    Es klappt noch nicht ganz mit dem bekannt machen, wahrscheinlich include fehler, aber das probier ich erstmal selber.


    Danke!
    Geändert von JoachimJogi (19.02.07 um 20:38 Uhr)
     

  6. #6
    JoachimJogi JoachimJogi ist offline Mitglied
    Registriert seit
    Feb 2007
    Beiträge
    22
    Es klappt leider immer noch nicht wie ich will ;(

    Wieder ein konstruiertes Beispiel, diesmal mit
    CTryApp, CTryDlg und InnerDlg.
    Ich möchte von InnerDlg Zugriff auf CTryDlg bekommen.

    1) InnerDlg anzeigen, indem Membervariable InnerDlg in CTryDlg initialisiert und angezeigt wird (keine Probleme)

    2) Member Variable vom Typ CDialog* in InnerDlg erzeugen. Name: m_super;

    3) Dem Konstruktor von InnerDialog gebe ich einen this Zeiger mit (aufgerufen vom CTryDlg::OnInitDialog() )

    4) Im Konstruktor speichere ich die übergebene Adresse.

    In der InnerDlg.cpp ist die TryDlg.h includiert. Wenn ich jetzt mit
    ((CTryDlg*)m_super)->MessageBox("hallo","",0); einen Test mache, funktioniert es.
    Aber bei
    ((CTryDlg*)m_super)->setLog("hallo welt"); kommt ein Speicherfehler.

    Meine setLog Methode ist richtig.
    Code :
    1
    2
    3
    4
    5
    
    void CTRYDlg::setLog(CString c)
    {
       m_strEdit.Format("ASdf");
       UpdateData(false);
    }
    , da sie lokal aufgerufen funktioniert.


    Ist es überhaupt richtig, dass ich eine Membervariable vom Typ CDialg* anlege? Wenn ich nämlich direkt versuche CTryDlg* anzulegen, meckert er, dass er den Bezeichner nicht kennt. Nach dem includieren von TryDlg.h in der InnerDlg.h geht dann nix mehr, da er keine der beiden Dateien compiliert. (Beides mal "; erwartet", also wie bei unbekannten Datentypen.

    Ich könnt mri auch nicht vorstellen, wie der Compiler dass dann auflösen soll, denn um TryDlg.h zu kompilieren benötigt er die InnerDlg.h und anders herum ebenso.

    Lege ich die Membervariablen falsch an?
     

  7. #7
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Zitat Zitat von JoachimJogi Beitrag anzeigen
    Aber bei
    ((CTryDlg*)m_super)->setLog("hallo welt"); kommt ein Speicherfehler.
    Vom Prinzip ist eigentlich alles richtig. Kannst du mal die genaue Fehlermeldung zeigen? Hast du "setLog" auch als "public" deklariert?
    Zitat Zitat von JoachimJogi Beitrag anzeigen
    Ist es überhaupt richtig, dass ich eine Membervariable vom Typ CDialg* anlege? Wenn ich nämlich direkt versuche CTryDlg* anzulegen, meckert er, dass er den Bezeichner nicht kennt.
    Kann man schon so machen, aber gleich den Typ "CTryDlg*" anzulegen ist natürlich günstiger, weil du dir später das Type-Casting ersparst. Das Problem mit dem unbekannten Speichertyp kannst du lösen, indem du in "InnerDlg.h" vor der Klassendeklaration eine sogenannte Vorwärtsdeklaration einfügst:
    Code cpp:
    1
    2
    3
    4
    5
    6
    
    class CTryDlg;    // Vorwärtsdeklaration
     
    class CInnerDlg : public CDialog
    {
        // ...
    };
    TryDlg.h kannst du dann in der .cpp belassen. Vorwärtsdeklarationen funktionieren nur bei Zeigern.

    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  8. #8
    JoachimJogi JoachimJogi ist offline Mitglied
    Registriert seit
    Feb 2007
    Beiträge
    22
    Hallo McCoder.

    vielen Dank für deine Antwort!

    Es funktioniert alles, wie ich es will. Durch die Vorwärtsdeklaration kann ich alles so formulieren, wie es mir logisch erscheint. Der Speicherfehler ist weg. Ich hatte es public. Den Fehler möchte ich aber auch gar nicht reproduzieren, wahrscheinlich eine Kleinigkeit.

    Somit wäre dieses Topic erledigt!

    Grüße an alle Forumuser!
     

Ähnliche Themen

  1. Strings von Dialog A nach Dialog B übertragen
    Von king_of_drums im Forum C/C++
    Antworten: 13
    Letzter Beitrag: 30.08.06, 13:45
  2. Strings von Dialog A nach Dialog B übertragen
    Von king_of_drums im Forum Visual Basic 6.0
    Antworten: 3
    Letzter Beitrag: 15.08.06, 13:47
  3. Dialog aus anderem Projekt verwenden/importieren
    Von Boneman im Forum VisualStudio & MFC
    Antworten: 1
    Letzter Beitrag: 06.04.06, 08:44
  4. Antworten: 5
    Letzter Beitrag: 24.05.05, 12:49
  5. Zugriff auf Dialog ?
    Von can im Forum VisualStudio & MFC
    Antworten: 5
    Letzter Beitrag: 10.07.04, 10:58