CSplitterWnd bei einem Dialog basierten MFC Projekt ?!?



  • Guten Tag zusammen,

    ich arbeite seit einiger Zeit an einem Dialog basierten MFC Projekt und möchte nun ein Fenster erstellen das zur Konfiguration von Einstellungen dienen soll. Ich möchte das Fenster in 2 Spalten aufteilen und auf der linken Seite des Fensters möchte ich ein TreeCtrl plazieren und auf der rechten Seite den jeweiligen Dialog bzw View zu dem im Tree angewählten punkt.

    Ist das prinzipiell überhaupt möglich und wie mache ich das am einfachsten, bin was Visuall C++ angeht noch Anfänger.

    Vielen Dank schonmal!


  • Mod

    Stelle Deine Applikation auf SDI mit einem CFormView um, dann kannst Du auch Splitter verwenden.
    CSplitterWnd können nur ein einem CFrameWnd "vernünftig" leben.
    Anpassungen an CDialog sind nur unter extermen nachabeiten möglich.



  • Danke, aber wie mach ich das genau? Kann ich mein Projekt einfach umwandeln in SDI, geht das? Oder muss ich mein Projekt neu beginnen?


  • Mod

    Ich denke am einfachsten ist es ein neues SDI Projekt anzulegen mit einem CFormView.
    Dann einfach den bekannten Dialogcode entsprechend übernehmen.

    Du musst Dir nun nur etwas anderes mit OnOK und OnCancel einfallen lassen, denn die gibt es mit dieser Verwendung so nicht im SDI.



  • Vielen Dank, ich habe das Projekt jetzt als SDI neu angefangen und ich hatte zwar Anfangs paar kleine Probleme das fenster zu splitten und mit Views zu füllen, doch letztendlich hat's funktionier.
    Jetzt habe ich allerdings trotzdem wieder ein kleines Problem:

    Ich habe eine neue CFrameWnd Klasse erstellt und möchte ein FrameWnd aufpoppen lassen wenn man auf einen Menüpunkt klickt. Der Compiler meldet keinen Fehler, doch wenn ich dann auf den Menüpunkt klicke und create aufgerufen wird stürzt das Programm ab. Hier mal der code vom create aufruf:

    void CMainFrame::OnEditPreferences()
    {
    	PrefsDlg m_PrefsDlg;
    
    	RECT m_PrefsRct;
    
    	m_PrefsRct.left = 20;  
    	m_PrefsRct.top = 30;  
    	m_PrefsRct.right  = 180;  
    	m_PrefsRct.bottom = 230;
    
    	m_PrefsDlg.Create("Preferences", "Preferences", WS_BORDER | WS_POPUP, m_PrefsRct, this, NULL, 0, NULL);
    }
    

    Kann mir jemand sagen wo mein Fehler liegt?

    --------------------------------------------------

    UPDATE:

    Ich habe das erste "Preferences" mit NULL ersetzt, und danach m_PrefsDlg.ShowWindow(1) aufgerufen, jetzt gibt es kein Absturz mehr, allerdings ist das Fenster nur für einen Bruchteil einer Sekunde sichtbar und verschwindet dann wieder 😕


  • Mod

    Dein Objekt ist auf dem Stack angelegt! In dem Moment in dem die Funktion verlassen wird, geht das Objekt aus dem Scope und wird entsorgt. Der Destruktor zerstört das Fenster.
    Platziere das Objekt in das CMainFrame oder an anderer persistenter Stelle.

    Zudem: Ist das ein Dialog? Warum erzeugst Du das gute Stück nicht mit dem Template Namen.
    Und überhaupt. Sollte solch ein Dialog nicht Modal sein, also mit DoModal aufgerufen werden?



  • Ich weiß weder was ein Stack noch was ein Scope ist. Alles was ich machen will ist ein popup Fenster das in 2-3 teile gesplittet ist. Kann ich ein CFrameWnd überhaupt modal aufrufen und oder muss ich einen CDialog nehmen, ich bin doch noch Anfänger 🙄



  • frozen-one schrieb:

    Ich weiß weder was ein Stack noch was ein Scope ist.

    Dann zurück zu den Grundlagen:
    Alle Variablen, die du in deiner Funktion deklarierst, landen auf dem sog. Programmstack. Und der wird sauber wieder abgeräumt, wenn du die Funktion verlässt.
    ("Scope" bezeichnet den Gültigkeitsbereich einer Variablen - das kann eine Funktion oder auch nur der Anweisungsblock einer Schleife o.ä. sein. Wenn du diesen Bereich verlässt, wird für die Variable der Destruktor aufgerufen und sie verabschiedet sich)



  • Vielen Dank, jetzt isses mir in dem Fall auch klar wieso sich das fenster wieder schließt, aber wie mach ich jetzt am besten ein modales popup Fenster das gesplittet ist?


  • Mod

    So gar nicht... Schau Dir das Sample in den Technical Notes an.
    Du musst das Splitter window im SDI Main Frame erzeugen und jeweils dem Splitter Teilen mitteilen welche Fenster in Ihnen selbst wiederum angezeigt werden sollen.

    Wenn Du VS.NET 200x und höher hast, kannst Du Dir eine Applikation im Explorer Stil anlegen lassen. Da passiert genau das. Links im Splitter Fenster eine Baumansicht, rechts was immer du möchtest.



  • Ok, ich habe jetzt eine Membervariable in MainFrm.h angelget und erstelle ein Fenster mit folgendem Befehl in CMainFrame::OnCreate

    m_wndPrefs.Create(NULL, "Preferences", WS_OVERLAPPEDWINDOW, m_PrefsRct, this, NULL, 0, NULL);
    m_wndPrefs.ShowWindow(SW_SHOW);
    

    Bekomme auch mein FrameWnd mit SplitterWnd zu gesicht, doch sobald ich das Prefs Fenster schließe stürzt das Prog ab -> unhandled Exception.... und Visual Studio öffnet die Datei free.c 😞 🙄

    ---------------
    UPDATE:

    Dieses Problem habe ich behoben indem ich PrefsDlg* m_wndPrefs = new PrefsDlg; eingefügt habe, bevor ich create aufrufe. Jetzt stürzt das Prog zwar nicht mehr ab wenn ich das fenster schließe, jedoch kann ich das Fenster nur bei CMainFrame::OnCreate mit showWindow sichtbar machen, nicht jedoch wenn ich z.B. einen Menüpunkt anklicke, woran liegt das?


Anmelden zum Antworten