Neues Fenster in MDI

HolgerX

Mitglied
Hallo,
ich komme eigentlich von der Java-Programmierung, muss jetzt aber mit Visual Studio meine Diplomarbeit in C++ schreiben. :(

Mir wurde vorgegeben mit einer MDI zu arbeiten, statt einfacherheitshalber mit einer SDI.

Jetzt habe ich folgendes Problem:
Meine Anwendung soll nur mit leerem CMainFrame starten (d.h. ohne CChildFrame). Erst nach Öffnen einer Datei soll ebendiese in einem (neuen) CChildFrame angezeigt werden.
Wie kann ich nun dieses CChildFrame erzeugen?


Ein anderes Problem habe ich in folgendem Bereich:
Da ich die Dokument-Ansicht-Architektur erhalten soll, würde ich gerne wissen, wie man aus der Dokument-Klasse heraus eine Art Trigger also Auslöser implementiert, um der Ansicht-Klasse zu sagen, dass sich etwas geändert hat?

Über Vorschläge oder Quelltext würde ich mich freuen. :)

HOLGER
 
Um die erste Farge zu beantworten, muss ich erstmal in meinen Sourcen stöbern. Vielleicht schaffe ich es nachher noch.

Was deine zweite Frage betrifft: Die Klasse CView (von der dein View zwangsläufig abgeleitet ist) hat die virtuelle Methode CView::OnUpdate(). Die solltest du in deiner View-Klasse überschreiben. Sie wird aufgerufen, wenn du für dein Document CDocument::UpdateAllViews() aufrufst.

---

Zur ersten Frage: Eigentlich sorgt das MFC-Framework dafür, dass für ein neues Doc auch ein neuer View (mit Frame) geöffnet wird.
 
Zuletzt bearbeitet:
Original geschrieben von Kachelator
Was deine zweite Frage betrifft: Die Klasse CView (von der dein View zwangsläufig abgeleitet ist) hat die virtuelle Methode CView::OnUpdate(). Die solltest du in deiner View-Klasse überschreiben. Sie wird aufgerufen, wenn du für dein Document CDocument::UpdateAllViews() aufrufst.

Die Funktion CDocument::UpdateAllViews() hat leider noch ein paar Parameter:
void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

Wie kann ich auf pSender zugreifen?
Was zum Teufel ist ein LPARAM? - Ist das ein Template, das alle möglichen Datentypen zulässt? - Was bedeutet 0L ?
Ist pHint mein aktives Dokument CDocument?

Meine Frage (Problem) ist:
Wo wird die Instanz meiner Ansicht erzeugt?
Gibt es da nicht irgendwo eine Instanz, oder einen Zeiger, auf den ich zugreifen kann, und dass ich darauf direkt eine Methode der CView-Klasse ansprechen kann?


Original geschrieben von Kachelator
Zur ersten Frage: Eigentlich sorgt das MFC-Framework dafür, dass für ein neues Doc auch ein neuer View (mit Frame) geöffnet wird.
Ich will ja gerade, dass meine MDI ohne CChildFrame startet, bzw. ohne CChildView.
Meine Frage ist: Was muss ich in CMainFrame::OnOpenDokument() schreiben, damit mein olles Programm ein neues CChildFrame (mit CChildView) erzeugt?
Den Menüpunkt Datei - Neu gibt es in meiner Anwendung nämlich nicht, da keine neuen Dokumente erzeugt, sondern lediglich bestehende analysiert werden sollen.
 
Die Funktion CDocument::UpdateAllViews() hat leider noch ein paar Parameter:
Wieso "leider"?
void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );
Die Hints ("Hinweise") kannst du selbst verwalten oder auch nicht. Das Framework gibt sie einfach an CView::OnUpdate() weiter. Schon mal da die Parameter angeschaut?

Wie kann ich auf pSender zugreifen?
pSender wird gebraucht, damit bei einem Update festgestellt werden kann, von welchem View eine Änderung ausging - wenn überhaupt.

Was zum Teufel ist ein LPARAM? - Ist das ein Template, das alle möglichen Datentypen zulässt? - Was bedeutet 0L ?
Ist pHint mein aktives Dokument CDocument?
Fragen, Fragen! ;)
Warum fluchen? Mit LPARAM hast du im Prinzip recht - da kann man alles reinpacken, was maximal 32 Bit gross ist, man muss es nur richtig casten.
0L bedeutet einfach nur 0 als LONG.

Ist pHint mein aktives Dokument CDocument?
pHint ist nichts, wenn du es nicht benutzt. Es ist dafür da, dass du bei einem Update zusätzliche Informationen übergeben kannst.

Um zu verhindern, dass bei Start der Anwendung direkt ein leeres Dokument erzeugt wird, kommentiert folgende Zeilen in der CHolgerSeineApp::InitInstance() aus:
Code:
	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

Meine Frage ist: Was muss ich in CMainFrame::OnOpenDokument() schreiben, damit mein olles Programm ein neues CChildFrame (mit CChildView) erzeugt?
Nix. Das erledigt das Framework für dich.
 
Jetzt nochmal zu der Frage: Wie kann ich ein neues Fenster im MDI öffnen?

Nach dem Start der Anwendung erledigt das Framework das ja für mich.
Aber ich will mittels individuell gestaltetem CFileDialog die Datei öffnen.

Den CFileDialog habe ich auch schon wunderbar implementiert.
Er wird aufgerufen, wenn ich im Menü "Datei - Öffnen" wähle. Ich bekomme damit auch den Namen der zu öffnenden Datei. Ich kann dann mittels CFile Objekt auch die Datei auslesen, aber:

Wie kann ich das Programm dazu bringen ein neues Fenster aufzumachen, wo ich den Inhalt der Datei dann anzeigen kann?
Ich versuche das mittels CMDIChildWnd::Create(...) zu realisieren.
Ist das der richtige Versuch ?
 
Um ein neues Dokument aufzumachen (samt View und allem) sollte es reichen, einfach von der entsprechenden Doc-Template pDocTemplate->OpenDocumentFile( szFile ); aufzurufen. Über interne Umwege wird dann ein Dokument vom passenden Typ erzeugt, versucht zu laden, und wenn das klappt, wird auch ein zugehöriger View angelegt.

Den Doc-Template-Zeiger müsstest du ja vom AddDocTemplate haben oder dir dort merken.
 
Ich bekomme dann immer folgende Fehlermeldung:

Der linke Teil von '->OpenDocumentFile' muss auf Klasse/Struktur/Union zeigen
 
Dann ist an der Stelle pDocTemplate nicht definiert. Steht da vorher nicht sowas wie
Code:
CMultiDocTemplate* pDocTemplate = ...
?

An die DocTemplates deiner Winapp kommst du mit CWinApp::GetFirstDocTemplatePosition() und CWinApp::GetNextDocTemplate .
 
Zuletzt bearbeitet:
Doch, pDocTemplate ist dort definiert.

Ich schreibe meine Methode nämlich gerade in die CxyzApp Klasse.
Ich habe die pDocTemplate sogar global und public gemacht. :(
 
Dann musst du da irgendwas falsch gemacht haben.
Es gibt aber auch noch diese Möglichkeit, eine Datei zu öffnen:
virtual CDocument* OpenDocumentFile( LPCTSTR lpszFileName );
Mach mal:
Code:
AfxGetApp()->OpenDocumentFile( "meinedatei.xyz" );
Oder so ähnlich.
 
Zurück