Datei öffnen bei Programmstart/Kommandozeile (Anwendungsassistent)
-
Ich möchte dass - sofern eine Datei mit dem Programm verküpft wurde/öffnen mit... verwendet wurde - die Datei natürlich geöffnet wird
Die Dokument-Klasse enthält ja dann den Dateinamen.
Dazu versuchte ich folgendes:BOOL CEMFBetrachter_MFCDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; HENHMETAFILE H; H=GetEnhMetaFile(CDocument::GetPathName()); (((CMainFrame *)AfxGetMainWnd())->hMFile)=H; ENHMETAHEADER Metaheader; GetEnhMetaFileHeader(H, sizeof(ENHMETAHEADER), &Metaheader); (((CMainFrame *)AfxGetMainWnd())->MFileHeader)=Metaheader; (((CMainFrame *)AfxGetMainWnd())->viertelgr)=true; (((CMainFrame *)AfxGetMainWnd())->Originalgr)=false; (((CMainFrame *)AfxGetMainWnd())->Fenstergr)=false;
Der Handle H ist eine globale Variable in der MainFrame-Klasse. Doch der Code verursacht eine Zugriffsverletzung.
Ein anderer Versuch ging über pDoc->GetDocument() in der View-Klasse, doch dort fand ich keine Methode welche beim Programmstart ausgeführt wird (es ist ein CView ohne Spezialisierung, daher auch kein automatisches Öffnen durch die Doc-Klasse). Drucken funktioniert lustigerweise automatisch (es handelt sich um Bilder).
Gibt es einen anderen Weg?
-
Ich verstehe nicht, was Dein Code soll. Die MFCffnet doch automatisch die entsprechende Datei und ruft die entsprechenden On... Funktionen in Deinem Document auf!
-
Ja klar; aber da ich kein spezialisiertes Ansichtsfenster habe funktioniert das automatische Öffnen nicht. Muss ich eine On-Funktion in der Dokument-Klasse manuell überschreiben?
-
Was bedeutet es, wenn Du schreibst, dass Du kein spezialisiertes Anwednungsfenster hast?
Wie öffnest Du denn das Dokument?
Der normale Mechanismus. ist es das CDocument zu erzeugen und OnOpenDocument oder OnNewDocument aufzurufen, wenn Du nicht direkt alles aus dem Framework benutzt.
-
Ach so, OnOpenDocument ist wahrscheinlich das von mir gesuchte! Es ist ein normales CView und ich zeichne mit PlayEnhMetaFile rein.
Vielen Dank
-
Ich verstehe immer noch nicht was Du suchst?
Die Default Implementierung öffnet die Datei und assoziert ein CArchive mit dieser Datei. Dann wird Serialize aufgerufen.
Wenn Du also auf die geöffnete Datei zugreifen möchtest, wäre Serialize der richtige Punkt.
-
Vielen Dank, ich habe den Code nun beim Laden eingefügt. Allerdings kommt es wieder zu dieser Zugriffsverletzung durch die Zeile
(((CMainFrame *)AfxGetMainWnd())->hMFile)=H;
Wahrscheinlich weil das Hauptfenster zu diesem Zeitpunkt noch nicht existiert?
Der Handle zum Metafile habe ich im MainFrm als Variable deklariert, um sie von überall im Programm nutzen zu können. Vieleicht ein eigenartiger Weg, in C# instanziere ich einfach eine selbstdefinierte Klasse oder einfach globale Variable dafür aber mit MFC und dem Doc/View ist mir nichts anderes eingefallen um von überall her auf diesen Handle zugreifen zu können.void CEMFBetrachter_MFCDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: Hier Code zum Speichern einfügen } else { HENHMETAFILE H; H=GetEnhMetaFile(CDocument::GetPathName()); (((CMainFrame *)AfxGetMainWnd())->hMFile)=H; ENHMETAHEADER Metaheader; GetEnhMetaFileHeader(H, sizeof(ENHMETAHEADER), &Metaheader); (((CMainFrame *)AfxGetMainWnd())->MFileHeader)=Metaheader; (((CMainFrame *)AfxGetMainWnd())->viertelgr)=true; (((CMainFrame *)AfxGetMainWnd())->Originalgr)=false; (((CMainFrame *)AfxGetMainWnd())->Fenstergr)=false; } }
-
Gibt es für das CView nicht etwas wie das Form_Load bei .NET bzw. die WM_Create-Nachricht überschrieben?
-
Ich verstehe in keiner Form was Du willst.
- Ein CView ist von einem CDocument unabhängig. Punkt.
- Die Daten liegen im Document und werden vom CView dargestellt.
- Ein CView existiert immer erst nachdem ein CDocument angelegt wurde.
- Ein CDocument kann auch ohne CView leben.
- Ob Ein View existiert oder zerstört wurde erfährst Du über OnChangedViewListDein Problemist einfach, dass Du hier alle Objekte wild durcheinander würfelst und auf die entsprechende Datentrennung nicht achtest.
Für was hast Du Daten bitte im CMainFrame?
-
Das ist mir alles klar. Stimmt, die Document-Klasse habe ich ziemlich aussen vor gelassen; da PlayEnhMetaFile das Öffnen halt selbständig übernimmt. Und diese Funktionen habe ich im View geschrieben wo die Daten angezeigt werden.
Da ich es nicht schaffte Variablen für die Handles etc. global zu deklarieren schaute ich in einem Forum, wo ich diese Idee fand diese in MainFrm anzulegen; dort ist nun das Handle und die Auswahl der Anzeigegrösse. Wäre ja wunderbar, so sind sie von der Document-Klasse zugänglich um den Handle beim ÓnNewDocument anzulegen dass er beim Paint-Event des Views verfügbar ist wenn eine Datei über die Kommandozeile geöffnet wird. Nun gibt es aber genau da eine Zugriffsverletzung...
Von anderen Programmiersprachen und Frameworks (Assembler/win32 bis C#/VB) bin ich mir gewohnt diese DInge im WM_Create oder Form_Load zu erledigen was aber anscheinend in diesem Sinn mit MFC nicht geht.
-
Anzeigegrößen Auswahl? Gehört in den View?
Es gibt alle diese Events CMainFrame/CView::OnCreate, CView::OnInitialUpdate.
Die Frage ist nur was paltziert man wohin und das ist die Crux bei Dir....
-
So wie ich gelesen habe gehört alles was mit einer alternativen Ansicht des selben Dokuments zu Tun hat ins View?
Ich versuchte eben die OnCreate-Methode hinzuzufügen auf WM_Create. Nun meldet mir Visual Studio "Hinzufügen/entfernen nicht möglich da das Codeelement.... schreibgeschützt ist"
-
Keine Ahnung. Setzt Du Source COntrol ein?
Im CView ist OnInitialUpdate der richtige Ansatz. OnCreate wäre wirklich nur für Basis-Dinge wichtig.
-
Vielen Dank; ja in der InitialUpdate hatte ich den Code schonmal und das gab auch eine Zugriffsverletzung; aber wahrscheinlich habe ich da einen Fehler drin. Die Dokumentklasse sollte ja von dort aus zugänglich sein und das Paint-Ereignis wird nacher ausgelöst.
-
Source Control kenne ich gar nicht, nein; ist das ein Dokumentations/Überprüfungswerkzeug?
-
Dann zeig mal Code.
Source Control Systeme verwalten den Sourcecode und bieten Versionierung und Historien an. Erlauben meistens auch ein Arbeiten im Team am Code.
-
Der Code welcher ausgeführt werden sollte wäre dieser:
CEMFBetrachter_MFCDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; HENHMETAFILE H; H=GetEnhMetaFile(pDoc->GetPathName()); (((CMainFrame *)AfxGetMainWnd())->hMFile)=H; ENHMETAHEADER Metaheader; GetEnhMetaFileHeader(H, sizeof(ENHMETAHEADER), &Metaheader); (((CMainFrame *)AfxGetMainWnd())->MFileHeader)=Metaheader; (((CMainFrame *)AfxGetMainWnd())->viertelgr)=true; (((CMainFrame *)AfxGetMainWnd())->Originalgr)=false; (((CMainFrame *)AfxGetMainWnd())->Fenstergr)=false;
Irgendwie kann ich keine Funktionen hinzufügen und OnInitialUpdate ist nicht vorhanden.
Ach so, danke. Nein so etwas verwende ich nicht
-
Jetzt hat's geklappt! Heute ging die Überschreibung von OnInitialUpdate und darin habe ich den Code jetzt und läuft. Jetzt lässt sich das Programm sinnvoll verwenden.
Danke !
-
C. M. Obrecht schrieb:
CEMFBetrachter_MFCDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; HENHMETAFILE H; H=GetEnhMetaFile(pDoc->GetPathName()); (((CMainFrame *)AfxGetMainWnd())->hMFile)=H; ENHMETAHEADER Metaheader; GetEnhMetaFileHeader(H, sizeof(ENHMETAHEADER), &Metaheader); (((CMainFrame *)AfxGetMainWnd())->MFileHeader)=Metaheader; (((CMainFrame *)AfxGetMainWnd())->viertelgr)=true; (((CMainFrame *)AfxGetMainWnd())->Originalgr)=false; (((CMainFrame *)AfxGetMainWnd())->Fenstergr)=false;
Merke: Wenn Du soviele Cast zum Zugriff auf andere Objekte benötigst ist etwas grundsätzlich falsch!
Warum stehen diese Daten/Objekte nicht im View!
-
Ja das ist mir klar. Ich hatte bloss Mühe mit dem globalen Deklarieren und bin dann im Internet darauf gestossen es so zu tun... Wie könnte ich so eine Variable normal im View deklarieren? In C# wäre mir klar wie, aber die Doc/View-Architektur wollte es nicht so wie ich...
Das Programm habe ich in Assembler zuerst geschrieben und dort ist es fast so gross wie die Casts alleine
Allerdings kann diese Version nicht zu BMP konvertieren.