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
-
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 mitm_pDoc = dynamic_cast<CMainDoc*>(((CMainFrame*)AfxGetMainWnd())->GetActiveDocument());geholt
-
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; }
-
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-MethodeBOOL CGueltigkeitsBestaetigungFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { //hier werden die Views erzeugt }
-
Du musst bei CFrameWnd::Create den CCreateContext mit übergeben!
Denn alle weiteren Fenster (Views) werden in diesem Conext angelegt!