Subdialogaufruf kackt ab, weiss net warum
-
Zeig mal genau die Zeile wo dein Programm eine exeption hat.
Wie kommst du dahin ? Debug !!!
-
vielleicht hilft dir das weiter:
[url]
http://www.devmentor.ch/teaching/additional/00I/Semester6/Abend8/TreeCtrl.pdf
[/url]
-
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