Subdialogaufruf kackt ab, weiss net warum



  • ok gut, ich sehs mir mal an, aber das mit der TreeControl haste ja vorher nicht geschrieben, daher konnte ich das nicht wissen ! 🤡



  • Ev. Solltest Du im Konstrutor Der B-Klasse das TreeControl "Createn".

    MSDN:

    CTreeCtrl::Create

    BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

    Return Value

    Nonzero if initialization was successful; otherwise 0.

    Parameters

    dwStyle

    Specifies the tree view control’s style. Apply any combination of tree view control styles to the control.

    rect

    Specifies the tree view control’s size and position. It can be either a CRect object or aRECT structure.

    pParentWnd

    Specifies the tree view control’s parent window, usually a CDialog. It must not be NULL.

    nID

    Specifies the tree view control’s ID.

    Remarks

    If you specify the tree control in a dialog box template, or if you are using CTreeView, your tree control is created automatically when the dialog box or view is created. If you want to create the tree control as a child window of some other window, use the Create member function. If you create the tree control using Create, you must pass it WS_VISIBLE, in addition to other tree view styles.

    You construct a CTreeCtrl in two steps. First call the constructor, then call Create, which creates the tree view control and attaches it to the CTreeCtrl object.

    The following styles can be applied to a tree view control:

    TVS_HASLINES The tree view control has lines linking child items to their corresponding parent items.

    TVS_LINESATROOT The tree view control has lines linking child items to the root of the hierarchy.

    TVS_HASBUTTONS The tree view control adds a button to the left of each parent item.

    TVS_EDITLABELS The tree view control allows the user to edit the labels of tree view items.

    TVS_SHOWSELALWAYS Causes a selected item to remain selected when the tree-view control loses focus.

    TVS_DISABLEDRAGDROP The tree-view control is prevented from sending TVN_BEGINDRAG notification messages.

    TVS_NOTOOLTIPS The tree view control uses no tooltips.

    TVS_SINGLEEXPAND When this style is enabled, changing the selection in the tree view will automatically cause the item being selected to expand and the item being unselected to collapse. If the mouse is used to single-click the selected item and that item is closed, it will be expanded. If the selected item is single-clicked when it is open, it will be collapsed.
    Example

    // Assuming your window has a CTreeCtrl member named m_TreeCtrl,
    // you can create the tree control window with a child ID of 0x1005
    // using a call like this:

    m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER
    | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES
    | TVS_DISABLEDRAGDROP,
    CRect(10, 10, 300, 100), this, 0x1005);

    // The control will have the appropiate window styles, and the tree
    // control styles specified are those most commonly used.

    CTreeCtrl Overview | Class Members | Hierarchy Chart

    See Also CTreeCtrl::CTreeCtrl,Tree View Control Window Styles in the Platform SDK

    --------------------------------------------------------------------------------
    Send feedback to MSDN.Look here for MSDN Online resources.



  • also den von benutzer "ü" geposteten tipp habe ich probiert (ueberprufung ob zeiger vielleicht null ist) --> er ist es nicht 😕

    noch eine kleine zusatzinfo:
    ich habe in der klasse A noch eine weitere member-variable die auch ein zeiger auf einen Dialog vom Typ C ist (also ein weiterer unterdialog). Das anzeigen dieses dialogs laeuft einwandfrei. nur klasse B macht schwierigkeiten.

    sone scheisse.



  • das mit dem createn des CTreeCtrl elements im Konstruktor der Klasse B habe ich probiert. Mal davon abgesehen das diese member m_Tree bei mir kein Zeiger ist, habe ich durch

    m_Tree.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER 
    		| TVS_HASBUTTONS | VS_LINESATROOT | TVS_HASLINES 
    		| TVS_DISABLEDRAGDROP, 
    		CRect(10, 10, 300, 100), this, IDC_WATREE);
    

    das CTreeCtrl element "created". Aber es funzt trotzdem nocht nicht !!!



  • ich habe die methode BOOL B::OnInitDialog() manuell in meinen Code so eingefuegt. Sie sieht so aus:

    BOOL CScopeSelectDlg::OnInitDialog(){
    
    	m_TreeImg.Create(IDB_BITMAP, 16, 2, RGB (255, 255, 255));
    	m_Tree.SetImageList(&m_TreeImg, TVSIL_NORMAL);
    
    	MessageBox("Oninitdialog","",MB_OK);
    
    	return CDialog::OnInitDialog();
    }
    

    Nur ich sehe die obige MessageBox garnicht. Wann wird eigentlich OnInitDialog()aufgerufen? VOR meinem Versuch von m_dlgB->DoModal() oder DANACH ?

    danke, grussle.



  • Zeig mal genau die Zeile wo dein Programm eine exeption hat.
    Wie kommst du dahin ? Debug !!!





  • also, soweit ich das jetzt analysiert habe, zerwurschtelt es ihn, weil er das m_Tree dort noch nicht intitialisiert hat.
    ich habe testweise die zeile mit Insert vor dem DoModal weggenommen und in die Klasse B OnInitDialog gepackt - funzt einwandfrei.
    Mal sehen...



  • geh den umgekehrten weg:
    gib nicht von A nach B, sondern hole mit B von A die Daten !

    probier mal folgendes:

    class A : public CDialog
    {
    public:
        CString strBla;
        void OnButton()
        {
            B dlg(this);
            dlg.DoModal();
        }
    }
    class B : public CDialog
    {
      private:
      A *a;
      public:
      B(A &a)
      {
        this->a=a;
      }
      BOOL OnInitDialog()
      {
            m_Tree->InsertItem(a->m_strBla,TVI_LAST);
            return TRUE;
      }
    }
    


  • Unix-Tom schrieb:

    Zeig mal genau die Zeile wo dein Programm eine exeption hat.
    Wie kommst du dahin ? Debug !!!

    also ich poste mal nochmal ein paar kleine code-schnippsel und sage dann an welcher stelle es abschmiert:

    void A::OnButton(){
    
    if(!m_pScopeSelectDlg) 
    	AfxMessageBox("Pointer ist NULL!!"); 
    else{ 
    	AfxMessageBox("Hurra");
    	if(m_pScopeSelectDlg->DoModal()==IDOK){
    	}	
    }
    }
    

    Ferner habe ich folgende zwei Methoden der Klasse B (Unterdialogsklasse) ueberschrieben:

    BOOL B::OnInitDialog(){
    
       CDialog::OnInitDialog();
    
       m_Tree.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER 
            | TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10,   300, 100), this, IDC_WATREE); 
    
       m_TreeImg.Create(IDB_BITMAP, 16, 2, RGB (255, 255, 255));
       m_Tree.SetImageList(&m_TreeImg, TVSIL_NORMAL);
    
       MessageBox("OnInit","",MB_OK);
    
       return TRUE;
    }
    
    int B::DoModal(){
       MessageBox("DoModal","",MB_OK);
       return CDialog::DoModal();
    }
    

    Es werden folgende MessageBoxen fuer obigen programm-ablauf gezeigt:

    "Hurra"
    "DoModal"

    Danach kackt es ab mit der Meldung:
    "Debug Assertion Failed" [irgendwo in wincore.cpp]
    Das heisst die MessageBox "OnInitDialog" wird NICHT angezeigt! 😕
    Verlege ich den Inhalt der Methode B::OnInitDialog() in den Konstruktor von B,
    schmiert das Programm gleich beim starten ab. 😞



  • Das Problem ist, dass

    mpDlgB->treeElement.InsertItem("Hallo", TVI_ROOT);
    

    VOR dem DoModal & OnInitDialog aufgerufen wird.
    Daher kommt die Assertation !
    Du kommst gar nicht mehr zu DoModal bzw. OnInitDialog !
    Richtigerweise solltest du das Frühestens im OnInitDialog füllen.

    Zuerst wird

    DoModal()
    

    aufgerufen, anschliessend

    OnInitDialog()
    
    BOOL B::OnInitDialog(){ 
    
       CDialog::OnInitDialog(); 
    
       m_Tree.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER 
            | TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10,   300, 100), this, IDC_WATREE); 
    
       m_TreeImg.Create(IDB_BITMAP, 16, 2, RGB (255, 255, 255)); 
       m_Tree.SetImageList(&m_TreeImg, TVSIL_NORMAL); 
    
       MessageBox("OnInit","",MB_OK); 
    
       m_Tree.InsertItem(((A*)GetParent())->GetTextString(),......);
    
       return TRUE; 
    } 
    
    int B::DoModal(){ 
       MessageBox("DoModal","",MB_OK); 
       return CDialog::DoModal(); 
    }
    
    [cpp]
    void OnButton(){ 
       B pDlg(this);
       if(pDlgB.DoModal()==IDOK){ 
          // hier irgendwas machen .. 
       } 
    }
    

    ich will nun keinen blödsinn schreiben, aber ich denke das es daran liegt, dass

    void B::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(B)
    	DDX_Control(pDX, IDC_IDC_WATREE, m_Tree);
    	//}}AFX_DATA_MAP
    }
    

    Erst vom OnInitDialog der BASISKLASSE aufgerufen wird !
    Daher kennt das Ding das Control nicht und macht einen auf Servus !



  • ü schrieb:

    geh den umgekehrten weg:
    gib nicht von A nach B, sondern hole mit B von A die Daten !

    ich glaube das entspricht nicht ganz dem, was ich so in manchem buch gesehen habe :). Da sind die Subdialoge als member des hauptdialogs zu sehen und nicht umgekehrt (ich vermute mal das ist geschmackssache !?).

    Darueber hinaus noch zu Ernsti:

    Ja das was du sagtest entspricht dem programm-verhalten. Nur mich wunderts warum B::OnInitDialog() bei mir ueberhaupt nicht aufgerufen wird!?

    Gibt es eigentlich fuer solch einen Fall, wie ich ihn hier habe keinen standard-loesungsweg !?!?!??
    Mein problem ist doch nur dass zunaechst das CTreeCtrl im subdialog mit daten gefuellt werden soll und danach vom hauptdialog aus angezeigt werden soll.

    das "createn" des CTreeCtrl geschieht bei mir in B::OnInitDialog() (siehe code oben). Der zeiger auf das B-Objekt wird in A::A() initialisiert (siehe auch oben). Warum funzt der scheiss also net 😞



  • OnInitDialog von B wird nicht mehr aufgerufen, weil es ihn bereits VOR dem DoModal weghängt.
    Bei von mir o.a. Lösung gibst du bei Erstellen von Dialog B einen Zeiger auf A mit. Dann hast du von B über GetParent() Zugriff auf A und kannst im OnInitDialog dein Control füllen und ANSCHLIESSEND anzeigen.



  • ich habe folgendes herausgefunden:
    ich habe den bereits geposteten code von BOOL B::OnInitDialog()
    wie folgt erweiter:

    BOOL CScopeSelectDlg::OnInitDialog(){
    
      CDialog::OnInitDialog();
    
      MessageBox("1","",MB_OK);
      m_Tree.Create(	WS_VISIBLE | WS_TABSTOP | 
    		WS_CHILD | WS_BORDER |
    		TVS_HASBUTTONS | TVS_HASLINES | 
    		TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), 
    		this, IDC_WATREE); 
    
      MessageBox("2","",MB_OK);
      m_TreeImg.Create(IDB_BITMAP, 16, 2, RGB (255, 255, 255));
    
      MessageBox("3","",MB_OK);
      m_Tree.SetImageList(&m_TreeImg, TVSIL_NORMAL);
    
      MessageBox("4","",MB_OK);
      return TRUE;
    }
    

    Ich weiss das sind nicht gerade die besten debug-vorgehen :)) aber eine weiter hilfreiche info waere vielleicht, dass ich nur die MessageBox "1" des obigen Aufrufs zu sehen bekomme. D.h. das mit dem m_Tree.Create(...) kackt ab.

    woran kann das liegen?

    grussle



  • Ist m_Tree vielleicht NULL ?

    Hast du das da:

    void B::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(B)
    	DDX_Control(pDX, IDC_IDC_WATREE, m_Tree);
    	//}}AFX_DATA_MAP
    }
    

    und ein Control auf deinem Dialog damit verbunden (mit Resourceneditor gemacht)

    dann kannst du dir das Create sparen



  • So, ich hab dir ein Beispiel gebastelt, was bei wunderbar funzt.

    //*******************************************************************
    // A Dialog Headerfile
    //*******************************************************************
    #ifndef _A_H_
    #define _A_H_
    
    //*******************************************************************
    
    //*******************************************************************
    
    class A : public CDialog
    {
    public:
    	A(CWnd* pParent = NULL);	
    	CString	m_strHomer;
    	CString	m_strMarge;
    	CString	m_strBart;
    	CString	m_strLisa;
    	CString	m_strMaggie;
    	enum { IDD = IDD_DLG_DIALOG };
    protected:
    	afx_msg void OnButton1();
    	DECLARE_MESSAGE_MAP()
    };
    
    //*******************************************************************
    
    #endif 
    
    //*******************************************************************
    //*******************************************************************
    //*******************************************************************
    
    //*******************************************************************
    // A Dialog cppfile
    //*******************************************************************
    #include "stdafx.h"
    #include "B.h"
    #include "A.h"
    
    //*******************************************************************
    // konstruktor
    //*******************************************************************
    A::A(CWnd* pParent) CDialog(A::IDD, pParent)
    {
    	m_strHomer ="Homer";
    	m_strMarge ="Marge";
    	m_strBart  ="Bart";
    	m_strLisa  ="Lisa";
    	m_strMaggie="Maggie";
    }
    
    //*******************************************************************
    // messagemap
    //*******************************************************************
    BEGIN_MESSAGE_MAP(A, CDialog)
    	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
    END_MESSAGE_MAP()
    
    //*******************************************************************
    // button gedrückt
    //*******************************************************************
    void A::OnButton1() 
    {
    	B dlg;
    	dlg.DoModal();	
    }
    
    //*******************************************************************
    //*******************************************************************
    //*******************************************************************
    
    //*******************************************************************
    // B Dialog Header file
    //*******************************************************************
    #ifndef _B_H_
    #define _B_H_
    
    //*******************************************************************
    
    //*******************************************************************
    
    class B : public CDialog
    {
    public:
    	CTreeCtrl m_Tree; 
    	B(CWnd* pParent = NULL);
    	enum { IDD = IDD_DIALOG1 };
    protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    
    	afx_msg void OnButton1();
    	virtual BOOL OnInitDialog();
    };
    
    //*******************************************************************
    
    #endif 
    
    //*******************************************************************
    //*******************************************************************
    //*******************************************************************
    
    //*******************************************************************
    // B - Dialog cpp file
    //*******************************************************************
    #include "stdafx.h"
    #include "A.h"
    #include "B.h"
    
    //*******************************************************************
    // konstruktor
    //*******************************************************************
    B::B(CWnd* pParent) : CDialog(B::IDD, pParent)
    {
    }
    
    //*******************************************************************
    // ddx
    //*******************************************************************
    void B::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_TREE1, m_Tree);
    }
    
    //*******************************************************************
    // initialisiert den dialog
    //*******************************************************************
    BOOL B::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
    
    	m_Tree.InsertItem(((A*)GetParent())->m_strHomer, NULL,TVI_LAST);
    	m_Tree.InsertItem(((A*)GetParent())->m_strMarge, NULL,TVI_LAST);
    	m_Tree.InsertItem(((A*)GetParent())->m_strBart,  NULL,TVI_LAST);
    	m_Tree.InsertItem(((A*)GetParent())->m_strLisa,  NULL,TVI_LAST);
    	m_Tree.InsertItem(((A*)GetParent())->m_strMaggie,NULL,TVI_LAST);
    
    	return TRUE;  
    }
    
    //*******************************************************************
    //*******************************************************************
    //*******************************************************************
    


  • vielen vieleeen dank :))

    ich habe wie von euch vorgeschlagen das fuellen des CTreeCtrl Elements in die OnInitDialog von Klasse B verschoben. Das Create kann ich mir in der Tat sparen, da ich das Tree-Element mit Ressourcen-Editor erstellt hatte (Warum ein zweites Create dann gleich abkackt ist mir nicht ganz geheuer).

    Nun funzt alles wunderbar.

    Ich danke allen vielmals 😃

    grussle


Anmelden zum Antworten