Splitter & GetDocument



  • hallo,

    folgende Situation:
    in einer SDI-Anwendung möchte ich einen zweiten Fenster öffnen wenn der Benutzer eine bestimmte Aktion durchführt.
    dieses zweiten Fenster habe ich mit einen eingenen Splitter geteilt in zwei Zeilen.
    jeden Teil habe ich einen View zugeordnet.

    Problem:
    wie greife ich in meinem View (zweite teil des zweiten fenster) auf das Dokument von meiner SDI-Anwendung.

    int CGueltigkeitsBestaetigungView2 :: OnCreate ( LPCREATESTRUCT lpCreateStruct )
    {
       ASSERT_VALID ( this );
    
       if ( CFormView :: OnCreate ( lpCreateStruct ) == -1 )
       {
          return -1;
       }
    
       //--  Hole nach dem Erzeugen des Views den nun gueltigen Document Zeiger
       m_pDoc = GetDocument ( );
    
       ASSERT_VALID ( m_pDoc );
    
       return 0;
    }
    
    #ifdef _DEBUG
    CMainDoc* CGueltigkeitsBestaetigungView2::GetDocument()  // non-debug version is inline
    {
       //ASSERT( m_pDocument->IsKindOf( RUNTIME_CLASS( CMainDoc ) ) );
       ASSERT ( strcmp ( m_pDocument->GetRuntimeClass ( )->m_lpszClassName, "CMainDoc" ) == 0 );
       return ( CMainDoc* ) m_pDocument;
    }
    #endif //_DEBUG
    
    void CGueltigkeitsBestaetigungView2 :: SetDocument ( CMainDoc *pDoc )
    {
       m_pDoc = pDoc;
    
       ASSERT_VALID ( m_pDoc );
    }
    

    ich habe mit GetDocument ausprobiert einen zeiger auf das dokument zu holen
    aber m_pDocument ist null


  • Mod

    Erzeuge den View mit dem entsprechenden Create Context, dann wird der View automatisch diesem Dokument zugeordnet.

    Fülle die CCreateContext Struktur entsprechend aus und erzeuge den View damit. Schau Dir mal das ganze im MFC Quellcode an.



  • danke Martin für deine Antwort.

    ich habe die Funktion jetzt so umgeschrieben.

    int CGueltigkeitsBestaetigungView2 :: OnCreate ( LPCREATESTRUCT lpCreateStruct )
    {
       ASSERT_VALID ( this );
    
       if ( CFormView :: OnCreate ( lpCreateStruct ) == -1 )
       {
          return -1;
       }
    
       CRuntimeClass *runtimeClass = NULL;
       runtimeClass = RUNTIME_CLASS( CGueltigkeitsBestaetigungView2 );
    
       CCreateContext context;
       context.m_pNewViewClass   = runtimeClass;
       m_pDoc = dynamic_cast<CMainDoc*>(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument()); 
       //context.m_pCurrentDoc     = GetDocument();
       context.m_pCurrentDoc     = m_pDoc;
    
       context.m_pNewDocTemplate = context.m_pCurrentDoc->GetDocTemplate();
       context.m_pCurrentFrame   = (CFrameWnd*) AfxGetMainWnd();
       context.m_pLastView       = NULL;
    
       //--  Hole nach dem Erzeugen des Views den nun gueltigen Document Zeiger
       //m_pDoc = GetDocument ( );
    
       ASSERT_VALID ( m_pDoc );
    
       return 0;
    }
    
    /*#ifdef _DEBUG
    CMainDoc* CGueltigkeitsBestaetigungView2::GetDocument()  // non-debug version is inline
    {
       //ASSERT( m_pDocument->IsKindOf( RUNTIME_CLASS( CMainDoc ) ) );
       ASSERT ( strcmp ( m_pDocument->GetRuntimeClass ( )->m_lpszClassName, "CMainDoc" ) == 0 );
       return ( CMainDoc* ) m_pDocument;
    }
    #endif //_DEBUG*/
    

    .

    aber GetDocument liefert immer null. ich habe die abgeleitete variante und die basis-variante ausprobiert aber beide liefern null.
    zeiger auf das dokument habe ich jetzt mit

    m_pDoc = dynamic_cast<CMainDoc*>(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument());
    

    geholt


  • Mod

    Falscher Ansatz. OnCreate benutzt diesen CCreateContext!

    Du sollst diesen CCreateContext ausfüllen bevor Du den View erzeugst.

    Wie erzeugst Du den View? Zeige den Code davon!



  • BOOL CGueltigkeitsBestaetigungFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
    {
       CRect cr; 
       GetClientRect( &cr);
    
       //teilen des Hauptfensters in 2 Zeilen
       if ( !m_mainSplitter.CreateStatic( this, 2, 1 ) ) 
       { 
          AfxMessageBox( _T("Error setting up splitter frames?"), 
             MB_OK);
          return FALSE; 
       }
    
       if ( !m_mainSplitter.CreateView( 0, 0, 
          RUNTIME_CLASS(CGueltigkeitsBestaetigungView1), 
          CSize(cr.Width(), 50), pContext ) ) 
       { 
          AfxMessageBox( _T("Error setting up splitter frames!"), MB_OK);
          return FALSE; 
       }
       if ( !m_mainSplitter.CreateView( 1, 0, 
          RUNTIME_CLASS(CGueltigkeitsBestaetigungView2), 
          CSize(cr.Width(),cr.Height()-50), pContext ) ) 
       { 
          AfxMessageBox( _T("Error setting up splitter frames!"), MB_OK);
          return FALSE; 
       }
    
       // Lock a Bar
    
       m_bInitSplitter = true;
       return TRUE;
    }
    

  • Mod

    Ist hier der pContext mit dem richtigen CDocument ausgefüllt?
    Denn dieses Dokument wird verwendet um im View m_pDocument zu setzten. Und diese Daten werden verwendet um den View auch dem Dokument zuzuweisen.



  • nein pContext ist mit dem richtigen CDocument in dieser Stelle noch nicht ausgefüllt.
    ich habe die Aufrufe in Debuger verfolgt. so ist die Reihenfolge:

    zuerst wird ein objekt von der zu teilende Fensterklasse erzeugt

    // Gültigkeitsbestätigung
       CGueltigkeitsBestaetigungFrame* pFrm = NULL;
       pFrm = new CGueltigkeitsBestaetigungFrame(m_pDoc);
       if ( pFrm  )
       {
          CFrameWnd *pFrame = (CFrameWnd *)AfxGetApp()->m_pMainWnd;
          CRect rect ( 0, 0, 750, 400 );
    [b]      pFrm->Create( pFrame);[/b]   }
    

    selbst implementierte Funktion create

    BOOL CGueltigkeitsBestaetigungFrame::Create( CWnd *pParent)
    {
       .......
       // hier wird das Fenster erzeugt
       BOOL ret = [b]CFrameWnd :: Create [/b]( NULL,
          csFehlerausgabeTitel,
          WS_OVERLAPPEDWINDOW | WS_POPUP,
          rect,
          pParent ); 
    ......
    }
    

    der Befehl CFrameWnd :: Create ruft OnCreate MFC-methode

    int CGueltigkeitsBestaetigungFrame :: OnCreate
    (
     LPCREATESTRUCT lpCreateStruct
     )
    {
       [b]// hier kann der lpCreateStruct ausfühllen werden oder ?[/b]
       if ( [b]CFrameWnd :: OnCreate ( lpCreateStruct )[/b] == -1 )
       {
          return -1;
       }
    
          return 0;
    }
    

    der Befehl CFrameWnd :: OnCreate ( lpCreateStruct) ruft wiederum
    die MFC-Methode

    BOOL CGueltigkeitsBestaetigungFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
    {
    //hier werden die Views erzeugt
    }
    

  • Mod

    Du musst bei CFrameWnd::Create den CCreateContext mit übergeben!

    Denn alle weiteren Fenster (Views) werden in diesem Conext angelegt!


Anmelden zum Antworten