Zugriff auf Dokumentklasse



  • 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 denn

    void 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);
    

  • Mod

    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 mit

    CError 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).


Anmelden zum Antworten