Recordview Problem



  • Du hast die Funktion aus der FAQ genommen und die Variablennamen geändert und es geht nicht mehr? 😕

    Oder hast du doch mehr geändert? Zeig doch mal. 🙂

    Ich habe an der Stelle optimistischerweise keine NULL-Zeiger-Prüfung 🙄 , vielleicht solltest du das nachholen. 🙂



  • void CMainFrame::SwitchToView(unsigned int f_nId)
    {
    
        // Ist es nicht der aktuelle View? 
        if (f_nId != m_nCurID) 
        { 
            // aktuellen view holen 
            CView* pActiveView = GetActiveView(); 
            ASSERT(pActiveView); 
    
            // den nächsten view holen 
            CView* pNextView; 
            switch (f_nId) 
            { 
            case IDD_MY11_FORM: 
                pNextView = create_view<CMy11View, CMy11Doc>(this); 
                break; 
            case IDD_BOUNDARY: 
                pNextView = create_view<CBoundaryView, CBoundaryDoc>(this); 
                break; 
            default: 
                ASSERT(0); 
                return; 
                break; 
            } 
    
            // die interne id austauschen 
            UINT nTemp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID); 
            ::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNextView->m_hWnd, GWL_ID)); 
            ::SetWindowLong(pNextView->m_hWnd, GWL_ID, nTemp); 
            pActiveView->ShowWindow(SW_HIDE); 
            pNextView->ShowWindow(SW_SHOW); 
            // neuen View setzen 
            SetActiveView(pNextView); 
            // layout updaten 
            RecalcLayout(); 
            // View neuzeichnen 
            pNextView->Invalidate(); 
    
            // altes document löschen     
            CDocument* pOldDoc = pActiveView->GetDocument(); 
            delete pOldDoc; 
            // alten view löschen 
            pActiveView->DestroyWindow(); 
            m_nCurID = f_nId; 
        } 
    
    }
    

    Das ist die paar wenigen Änderungen belaufen sich wirklich nur auf Variablennamen-Änderungen oder habe ich etwas unbewußt verändert (durch aufschlagendem Kopf auf der Tastatur 😃 )
    Wo ist da bitte ne NULL-Pointer Abfrage? weiß nicht wo! 🕶 *blindenbrille*



  • Ich sach doch:

    Ich habe an der Stelle optimistischerweise keine NULL-Zeiger-Prüfung 🙄 , vielleicht solltest du das nachholen. 🙂

    Ich baus mal ein, formatieren musst du:

    void CMainFrame::SwitchToView(unsigned int f_nId)
    {
        // Ist es nicht der aktuelle View?
        if (f_nId != m_nCurID)
        {
            // aktuellen view holen
            CView* pActiveView = GetActiveView();
            ASSERT(pActiveView);
    if(!pActiveView)
    {
    return;
    }
    
            // den nächsten view holen
            CView* pNextView;
            switch (f_nId)
            {
            case IDD_MY11_FORM:
                pNextView = create_view<CMy11View, CMy11Doc>(this);
                break;
            case IDD_BOUNDARY:
                pNextView = create_view<CBoundaryView, CBoundaryDoc>(this);
                break;
            default:
                ASSERT(0);
                return;
                break;
            }
    ASSERT(pNextView);
    if(!pNextView)
    {
    return;
    }
    
            // die interne id austauschen
            UINT nTemp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
            ::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNextView->m_hWnd, GWL_ID));
            ::SetWindowLong(pNextView->m_hWnd, GWL_ID, nTemp);
            pActiveView->ShowWindow(SW_HIDE);
            pNextView->ShowWindow(SW_SHOW);
            // neuen View setzen
            SetActiveView(pNextView);
            // layout updaten
            RecalcLayout();
            // View neuzeichnen
            pNextView->Invalidate();
    
            // altes document löschen    
            CDocument* pOldDoc = pActiveView->GetDocument();
            delete pOldDoc;
            // alten view löschen
            pActiveView->DestroyWindow();
            m_nCurID = f_nId;
        }
    }
    

    Und IDD_MY11_FORM oder IDD_BOUNDARY hat tatsächlich den Wert 2? 😕
    Schreib lieber IDD_MY11_FORM oder IDD_BOUNDARY hin, das ist später leichter nachzuvollziehen und auch zu pflegen. 🙂

    Du hast auch keinen ASSERT bekommen und einfach ignoriert? 🙄



  • OK das mit der NULL-POinter hab ich wohl vorhin gepennt, ich bekomm jetzt auch einen anderen Fehler, allerdings immernoch "unknown sofware exception" (künftig U S E) ich hab auch die IDD anstelle der 2 eingetrage, weiß nicht warum ich das so hatte. Ich bekomm den Fehler U S E jetzt in der Zeile:

    ASSERT(pActiveView);
    

    in der SwitchToView Methode 😕 😕 😕 komm da irgendwie auf keinen grünen Zweig



  • Hab grad im Debug festgestell dass die current ID nie die ID von meinen IDD hat ewige Zahl 343578936 oder so und die ID sind eigentlich 101(IDD_MY11_FORM) und 130(IDD_BOUNDARY)
    liegt es daran? 😕



  • Ooookay, ganz langsam:
    1. Das ist ein ASSERT. Erklärungen findest du im Forum und der MSDN.
    Fakt ist, dass du keinen aktiven View hast ODER keiner gefunden werden konnte. Kann das sein?
    2. Drück mal "Alles neu erstellen", das hilft bei komischen Fehlern.
    3. Hast du VC6? Hast du den Service Pack 6 installiert? Sollte man nachholen, hilft auch bei unverständlichen Fehlern.

    So, dass war jetzt der große Rundumschlag 😉 jetzt kommst du. 🙂



  • Das ist ein Indiz für meinen Verdacht, dass du keinen aktuellen view hast. Kann das sein?



  • Das habe ich auch gerade eben festgestellt aber ich weiß nicht wieso! Wie sag ich denn überhaupt dass ein View aktiv ist und wo? Das mit dem ASSERT hab ich grad mal nachgelesen, und ich verwende VC++ 6 SPs hab ich keine zusätzlichen installiert werde ich aber gleich mal nacholen.



  • Das machst du mit SetActiveView (ist ja auch in der Funktion).

    Aber für den Startview habe ich das gelassen, was der Assistent erstellt hat - aber mdifiziert, weil ich da mal rumprobiert hatte.
    Musst mal gucken, ob du es wiedererkennst:
    Im InitInstance

    // Die Doc-View-Kombination anmelden
    	if (!RegisterDocView (RUNTIME_CLASS(CKundenDoc), RUNTIME_CLASS(CKundenView)))
    	{
    		return FALSE;
    	}
    
    // ------------------------------------------------------------------------------------------------
    // 
    // Diese Funktion führt alle notwendigen Schritte aus, um die Doc-View-Kombination anzumelden
    // 
    // ------------------------------------------------------------------------------------------------
    bool CMyApp::RegisterDocView(
    						 CRuntimeClass* f_pDocClass, 
    						 CRuntimeClass* f_pViewClass)
    {
    	// Neues Template erstellen
    	CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate(
    		// Welches Menü (immer das normale)
    		IDR_MAINFRAME,
    		// Welche Dokumentenklasse
    		f_pDocClass,
    		// Welches Rahmenfenster (immer das normale)
    		RUNTIME_CLASS(CMainFrame),
    		// Welche Viewklasse
    		f_pViewClass);
    
    	// Hats geklappt?
    	if (!pDocTemplate)
    	{
    		return false;
    	}
    
    	// Hinzufügen
    	AddDocTemplate(pDocTemplate);
    	return true;
    }
    


  • Also ich hab das mal versucht mit dem wo du da geschrieben hast, er fragt mich jetzt am anfang ob ich My11 oder My11 öffnen will aber sonst ändert sich nicht wirklich viel ich flieg wieder beim Assert auf die Schnauze, vermutlich immernoch weil ich kein aktiven View hab. Aber dafür hab ich jetzt
    SP6 😉 👍
    Ich muss doch einfach im Startview (bei mir CMy11View) sagen,

    SetActiveView(this);
    

    muss da noch irgendwas davor oder danach?
    Ich verzweifel so langsam! 😞



  • Okay, dann nimm die Zeilen wieder raus, wenn der dich fragt, dann hast du AddDocTemplate zweimal aufgerufen.

    Sag mal, bekommst du denn einen View angezeigt? Also, tritt der Fehler gleich beim Starten auf oder erst beim Umschalten? 😕

    PS: Das SetActiveView macht das Framework automatisch.



  • ICh kann die Anwendung starten und ich hab ja auf nen Buton diese Funktion SwitchView, und sobald ich auf diesen Button clicke steigt er aus. Was kann ich da jetzt tun?
    Geht das vielleicht gar nicht so mit Recordviews? Geht das nur mit Formviews oder mit allen?? Eigentlich dohc mit allen Views, oder?



  • Eigentlich sollte das mit allen Views gehen. 😕

    Ich mache das mit Formviews.

    Wenn du gar keine Idee mehr hast gibt es zwei Möglichkeiten.
    1. Du machst ein leeres Projekt, wo du das nochmal versuchst. Manchmal baut man Fehler ein, die man später nicht mehr findet.
    2. Du bereinigst das Projekt, packst es als zip (!!!) und schickst es an estartu_de@yahoo.com. Ich gucke drauf, wenn ich Zeit habe und finde vielleicht den Fehler. 🙂



  • Wow zwei Möglichkeiten sind immer gut, ich hab die erste Möglichkeit gemacht und wie ich feststellen musste ist das immernoch genau das gleiche Problem, ich hab wirklich nur noch die View-Geschichte drin sonst nichts. Jetzt werde ich zur zweiten übergehen.



  • Ich habe den Fehler! 🙂

    void CMy11View::OnBtnView2() 
    {
    	CMainFrame switchto; 
    	switchto.SwitchView(IDD_BOUNDARY);	
    }
    

    Denk bitte mal über diese Zeilen nach, vielleicht kommst du drauf - sonst muss ich mich mal als Erklärbär üben. 😉



  • Nanu? Was ist los? 😕
    Keine Idee?



  • Sorry bei uns war das I-Net gestern mittag tot. Ich hab mir die Zeilen angeschaut und bin bis jetzt noch nicht auf die Lösung des Problems gekommen,ich rufe die Funktion OnBTNView2 auf. Und in der Funktion rufe ich dann doch meine Funktion SwitchView auf. Da bin ich mir eigentlich recht sicher. Jetzt kann der Fehler eigentlich nur noch in der Zeile

    CMainframe switchto;
    

    liegen, in der ich eine Instanz vom Mainframe anlege. 🙄 glaube ich. Aber von was muss ich denn vor dem aufruf dann eine Instanz anlegen? ( Muss ich doch oder?) Weil ich kann ja die FKT nicht einfach mit

    CMainframe::SwitchView(IDD_BOUNDARY);
    

    aufrufen. Aber ich hab da noch was vielleicht sein könnte und zwar übergebe ich doch eigentlihc ein unsigned int muss ich dann erst noch meine IDD an eine int Variable übergeben? Ich dachte da stünde schon ein int drin.
    So das war mein Gedankengang im kurzen zusammengefasst, aber die Lösung habe ich immer noch nicht.
    Please tell me.



  • Ah, dann ist ja gut, ich dachte schon, ich habe dich verärgert.

    Ich hab neulich mal Zeiger anhand von Autos erklärt. ( http://www.c-plusplus.net/forum/viewtopic-var-t-is-103523.html )
    In dem Stil mach ich jetzt einfach weiter, okay? 🙂

    Du hast ein Auto, das steht zu Hause in der Garage. (Das ist der MainFrame, den das Framework für dich anlegt.)
    Bei dem Auto hast du deine Lieblingscd im Radio. (Die CD macht mal den Platzhalter für alle Membervariablen, die initialisiert wurden. Der aktuelle View gehört auch dazu.)
    **
    So, jetzt bist du aber auf Arbeit und willst deine Lieblingscd hören.** Dazu brauchst du ja ein Auto mit Radio.

    Du gehst also zum nächsten Autohaus und kaufst dir ein Auto.

    CMainframe switchto;
    

    Dann machst du das Radio an und wunderst dich, dass da gar nicht deine CD drin ist. 😃

    Dämmert es? 🙂
    Der MainFrame, den du da anlegst hat NICHTS mit dem zu tun, dem der aktuelle View bekannt ist. 🤡

    Nur mit der Lösung des Problems wirds etwas schwieriger. Vom View aus kommt man irgendwie nicht so einfach an den MainFrame. 😞
    Möglichkeit 1: Du machst das nicht per Knopf, sondern per Menübefehl (der im Frame behandelt wird), so war es ja auch in der FAQ, Reste davon hab ich noch in deinem Quelltext gefunden.
    Möglichkeit 2: Du holst dir in der OnBtnView2 einen Zeiger auf das Hauptfenster (AfxGetMainWnd) und schickst dem eine Nachricht.
    Im MainFrame muss dann ein MessageHandler sein, der dann den Viewtausch macht.
    Möglichkeit 3: Du kombinierst beides.

    So, du bist. 🙂



  • OK hört sich doch schon mal gut an ich hatte in der Zeit in der zwischen unseren Posts probiert im MainFrame eine Membervariable anzulegen, aber bin damit auch nicht weiter gekommen. Das mit den Überresten stimmt. Das habe ich gestern so aus meiner Verzweiflung raus noch unten aus der FAQ kopiert und einfach mal rein geschmissen, in der Hoffnung dass sich der Fehler an ner ganz anderen Stelle von selbst löst. 🙄 Naja jetzt hab ich es übers Menü versucht ich hab einen Menüeintrag gemacht der Switch heißt und dann

    void CMainFrame::OnSwitch(UINT f_nID) 
    {
    	SwitchView(IDD_BOUNDARY);	
    }
    

    So ich bin danach aber immnoch gleich weit wie bisher. Der steigt mit dem gleichen Fehler an der gleichen Stelle aus.
    Soviel zu Möglichkeit 1. Zu 2 😕 😕 😕 versteh ich net, daraus folgt dass aus drei bei mir nichts werden kann.
    Kannst du mir das mal Sourcen??



  • Kannst du mir die aktuelle Version mal schicken?
    Dann weiß ich, wodrauf ich aufbauen kann. 🙂

    Dann sehen wir weiter. Fertig einbauen werde ich es dir jedenfalls nicht, dann lernst du ja nix.
    Ich schubs dich weiter in die richtige Richtung, das wird schon noch. 😉


Anmelden zum Antworten