Zugriff auf Dokumentklasse
-
Wenn ein Fehler aufgetreten ist öffnet sich ein Dialogfeld(nur in Debug mode) und gibt die Variable nActualRuntimeFunction aus.
nActualRuntimeFunction wird in jeder Funktion mit einem anderen Wert initialisiert, daher weiß ich welche Funktion einen Fehler auslöst.
Ich habe jetzt das dynamic_cast<> durch einen einfachen C cast ersezt und so funktioniert es glaub ich auch.Ich muss allerdings einen nicht-modalen Dialog erstellen. Da ja sonst die Variable im Textfeld nicht ausgegeben wird.
Und da hab ich schon das nächste Problem:
Ich kriege beim Kompilieren die Fehlermeldung CError typ neudefinitionvoid CError::OnBnClickedBtnCancel() { OnCancel(); } void CError::InitialDialog(void) { UpdateData (FALSE); } CError* CError::Instance(CWnd* pParentWnd) { BOOL bWOldState=FALSE; CError* pWDlg = new CError; if (pParentWnd==NULL) pWDlg->m_pParentWnd = AfxGetApp()->m_pMainWnd; // can be NULL! else pWDlg->m_pParentWnd = pParentWnd; if (!pWDlg->Create(IDD_ERRORDLG, pWDlg->m_pParentWnd)) { DeleteObject( pWDlg); pWDlg=NULL; return NULL; } if (pWDlg->m_pParentWnd != NULL) bWOldState = pWDlg->GetParentWnd()->EnableWindow(FALSE); // under window = incative pWDlg->EnableWindow (TRUE); if (bWOldState) pWDlg->m_bOldEnableState=FALSE; else pWDlg->m_bOldEnableState=TRUE; pWDlg->ShowWindow(SW_SHOW); return pWDlg; } void CError::Done(void) { if (::IsWindow(GetSafeHwnd())) { if (m_pParentWnd!=NULL) m_pParentWnd->EnableWindow(m_bOldEnableState); if (::IsWindow(GetSafeHwnd())) DestroyWindow(); } } void CError::OnCancel(void) { notifyCancel(); } void CError::PostNcDestroy(void) { delete this; } void CError::OnCancelMode() { CDialog::OnCancelMode(); } void CError::SetActualRuntimeFunction(Uint16_t nActualRuntimeFunction) { m_nActualRuntimeFunction = nActualRuntimeFunction; } Uint16_t CError::GetActualRuntimeFunction(void) { return m_nActualRuntimeFunction; } void CError::RuntimeError(void) { CError* pError; MSG Msg; /*creates the non-modal dialog*/ pError=CError::Instance(NULL); pError->InitialDialog(); pError->UpdateData(FALSE); while(::PeekMessage(&Msg, NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); break; } } pError->UpdateData(FALSE); CSipromTDoc* pDoc = (CSipromTDoc*)(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument()); m_ActualRuntimeFunction.SetWindowText(pDoc->CastInt2String(m_nActualRuntimeFunction)); } BEGIN_MESSAGE_MAP(CError, CDialog) ON_BN_CLICKED(IDC_BTN_CANCEL, OnBnClickedBtnCancel) END_MESSAGE_MAP()Was könnte denn daran falsch sein?
-
maRKus23 schrieb:
Ich muss allerdings einen nicht-modalen Dialog erstellen. Da ja sonst die Variable im Textfeld nicht ausgegeben wird.
Nein, mußt du nicht - du mußt nur die Kennziffer übergeben, bevor du DoModal() aufrufst.
Und da hab ich schon das nächste Problem:
Ich kriege beim Kompilieren die Fehlermeldung CError typ neudefinitionWenn du jetzt noch dazusagst, WO die Meldung kommt, könnte ich dazu auch einige Ratschläge loswerden

-
Hab den Fehler gefunden. war mal wieder ein fehler bei den includes.
-
Ich kann nun den nicht-modalen dialog erstellen und zerstören, wenn ich aber eine Textausgabe mache, stürzt mein Programm ab und ich bekomme ein ASSERT.
void CError::RuntimeError(void) { BOOL bCancel=FALSE; CError* pError; MSG Msg; /*creates the non-modal dialog*/ pError=CError::Instance(&bCancel, AfxGetMainWnd()); pError->InitialDialog(); pError->ShowWindow(false); pError->UpdateData(FALSE); while(bCancel == FALSE) { while(::PeekMessage(&Msg, NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); break; } } CSipromTDoc* pDoc = (CSipromTDoc*)(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument()); m_ActualRuntimeFunction.SetWindowText(pDoc->CastInt2String(m_nActualRuntimeFunction)); pError->ShowWindow(true); pError->UpdateData(FALSE); } pError->Done(); }Weiß jemand wo der Fehler liegt?
-
Zeig doch mal den Code, der diese Methode aufruft. Der Ansatz sieht in meinen Augen zumindest fragwürdig aus - normalerweise erzeugt das Hauptprogramm das Dialogobjekt, übergibt (optional) einige Werte und ruft dann selber DoModal() auf. Und der Dialog stellt sich selber dar (da ist es nicht nötig, noch einen Bruder zu Hilfe zu holen ;)).
-
Zum testen hab ich den aufruf der Funktion in der Initialisierung der View.
void CSipromTView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); CError MyError; MyError.RuntimeError(); }IMHO sollte das nicht der Grund für den Fehler sein.
-
Der Grund für den Fehler dürfte irgendwo in deinem abenteuerlichen Klassenkonzept liegen. Soweit ich das überblicke, dient die Klasse CError nur dazu, den Benutzer über einen Fehler zu informieren - also sollte sie das auch machen. Dazu braucht sie aber kein zweites CError-Objekt, dem sie die Arbeit übergeben soll.
-
Welches zweite Error-Objekt meinst du denn? MyError?
MyError muss ich doch erstellen um die Funktion MyError.RuntimeError(); aufzurufen.Den Dialog könnte ich auch aus der Applikation erstellen, aber was ändert das?
-
maRKus23 schrieb:
Welches zweite Error-Objekt meinst du denn? MyError?
MyError muss ich doch erstellen um die Funktion MyError.RuntimeError(); aufzurufen.MyError ist nicht das Problem. Aber warum holst du dir in RuntimeError noch ein weiteres Objekt (pError)?
-
Habe es zuerst mit this versucht, dann krieg ich aber in der Programmzeile
pError=CError::Instance(&bCancel, AfxGetMainWnd());die Fehlermeldung Operand= benötigt L-Wert
-
Wozu brauchst du diese Zeile denn überhaupt? Du hast doch bereits ein Dlg-Objekt (MyError aus Sicht des Views alias *this aus Sicht deiner Methode) - und genau dieses sollte den Fehler auch weitermelden:
void CError::RuntimeError() { ...//initialisiere Membervariablen DoModal(); }
-
Das hab ich jetzt nicht so richtig kapiert.
was macht dennvoid CError::RuntimeError() { ...//initialisiere Membervariablen DoModal(); }Ich weiß nicht wie du einen nicht-modalen Dialog erstellst, ich mache es immer auf diese Art. Deine Methode kenn ich nicht.
-
Wozu brauchst du überhaupt einen Nicht-modalen Dialog? In den meisten Anwendungsfällen reicht ein modaler Dialog völlig aus.
-
Der Dialog soll sich öffnen und den Wert der Variablen ausgeben.
Wie kann ich das denn mit modalen dialog machen?void CError::RuntimeError(void) { this->DoModal(); m_editFeld.SetWindowText(m_nActualRuntimeFunction); }Würde das funktionieren wenn der Wert der Variable in CError abgelegt ist?
-
Die Dialog-Elemente (inklusive der Titelleiste) kannst du nur solange ansprechen, wie der Dialog tatsächlich existiert. Das heißt, du müsstest die Daten in einer "normalen" (je nach Typ int, double, CString o.ä.) Membervariablen zwischenlagern und in der (afair) OnInitialUpdate()-Methode dein SetWindowText aufrufen.
(btw, von wo aus wird eigentlich m_nActualRuntimeFunction befüllt?)
-
m_nActualRuntimeFunction wird in der Funktion gefüllt die den Fehler verursacht.
CError MyError; MyError.SetActualRuntimeFunction(xxxx);
-
maRKus23 schrieb:
Ich kann nun den nicht-modalen dialog erstellen und zerstören, wenn ich aber eine Textausgabe mache, stürzt mein Programm ab und ich bekomme ein ASSERT.
void CError::RuntimeError(void) { BOOL bCancel=FALSE; CError* pError; MSG Msg; /*creates the non-modal dialog*/ pError=CError::Instance(&bCancel, AfxGetMainWnd()); pError->InitialDialog(); pError->ShowWindow(false); pError->UpdateData(FALSE); while(bCancel == FALSE) { while(::PeekMessage(&Msg, NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); break; } } CSipromTDoc* pDoc = (CSipromTDoc*)(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument()); m_ActualRuntimeFunction.SetWindowText(pDoc->CastInt2String(m_nActualRuntimeFunction)); pError->ShowWindow(true); pError->UpdateData(FALSE); } pError->Done(); }Weiß jemand wo der Fehler liegt?
1. Warum verwendest Du nicht DoModal, wenn Du schon eine eigene Nachrichtenschleife implementierst?
2. Du solltest den Dokument-Zeiger den Du erhälst auf NULL testen und durch DYNAMIC_DOWNCAST umwandeln.
-
maRKus23 schrieb:
m_nActualRuntimeFunction wird in der Funktion gefüllt die den Fehler verursacht.
CError MyError; MyError.SetActualRuntimeFunction(xxxx);Du machst es dir nur unnötig kompliziert
Und außerdem besteht (vermutlich) kein direkter Kontakt zwischen diesem MyError und dem, dessen RuntimeError()-Methode du später aufrufen willst.
-
Wie würdest du es denn machen?
Ich muss doch auf eine Methode zugreifen die in einer anderen Klasse implementiert ist.
Das geht doch mitCError MyError; MyError.SetActualRuntimeFunction(xxxx);oder nicht?
-
Ja, technisch geht es so. Allerdings überleben die Member eines Objekts nicht, wenn es zerstört wird. D.h. wenn du woanders einen CError anlegst, weiß der überhaupt nichts von diesem Aufruf.
Ich würde gleich dort, wo der Fehler aufgetreten ist, die entsprechende Meldung anzeigen lassen (und im Bestfall die beiden Methoden SetActualRuntimeFunction() und RuntimeError() zu einer verschmelzen).