|
-
April 29th, 2004, 11:00 AM
#1
Multiple new files on same DocTemplate
I am writing some modelling software. A variety of models/simulations can be run which are chosen from sub menu items in File>New. A simulation may not work, in which case a new document will not be opened.
Currently I have several CMultiDOcTemplates and corresponding CDocument classes derived from a 'standard' CBaseDoc base class, one for each simulation type. The derived classes override OnNewDocument. ie:
CBaseDoc : public CDocument // the one provided by app wizard
{...
BOOL OnFileOpen()...
BOOL OnSaveAs(pathname)...
};
CSimulation1Doc : public CBaseDoc
{
BOOL OnFileNew() {
// code for this simulation. If it fails return FALSE, else returnTRUE
}
};
CSimulation2Doc : public CBaseDoc
{
BOOL OnFileNew() {
// code for this simulation. If it fails return FALSE, else returnTRUE
}
};
All the document fuctionality is in CBaseDoc, except for OnNewDocument, which is in the derived classes.
In the WinApp derived class, the different templates are setup to use the different documents, but with the same CView and IDR_resource, which includes the string resource.
The File>New part of this works well. However, since there are several document templates, opening a file shows the same filter extension several times (as you would expect).
I don't really like the above solution because there should only really one document type.
I would be very grateful if someone could suggest a 'neat' solution to providing different data in new documents, depending on the type of simulation chosen, using just ONE document and ONE document template.
There must not be a situation where a blank document is created (eg if the simulation fails and fails to fill the arrays in the document)
Thanks
Jon
-
April 29th, 2004, 03:47 PM
#2
Re: Multiple new files on same DocTemplate
Originally posted by JonnoA
I would be very grateful if someone could suggest a 'neat' solution to providing different data in new documents, depending on the type of simulation chosen, using just ONE document and ONE document template.
1. How would you specify the simulation type ( I assume that the simulation type is what decides which CBaseDoc derivative to use , right ? )
2. When you mean just ONE document, do you mean one document object or document class ?
I mean it is not clear. You say you have different documents, but is it that you want to get rid of those and have just one ?
-
April 29th, 2004, 04:16 PM
#3
Reply to your questions:
1- Each File>New menu subitem is handled by a function in the CWinApp derived class which asks the chosen simulation template to create a new document. eg
void CSpectrumApp::OnFileNewSimulationA()
{
m_pSimulationATemplate->OpenDocumentFile(NULL);
}
void CSpectrumApp::OnFileNewSimulationB()
{
m_pSimulationBTemplate->OpenDocumentFile(NULL);
}
etc.
2- For all the simulations, the data and all other functionality (except for OnFileNew) is stored in the CBaseDoc base class. I am only using different document classes and document templates classes to put the code which runs the simulation on File>New...
Instead I would like just ONE DOCUMENT CLASS. I would choose File>New>SimulationA, for example, it would run the simulation and if successful it would put the results in a new document.
It works in the usual multi-doc way, ie there can be multiple document objects in the app, holding the results from different simulations.
I'm sure there must be a better, simpler way to do this.
Thanks
-
April 29th, 2004, 04:20 PM
#4
Are you handling "File->New"? If I remember correctly, if you do not handle OnFileNew in your app class, the framework will pop up it's own file new dialog; asking the user which document to create.
Of course, the alternative is to remove "File"->"New" from your toolbar and menu!
Viggy
-
April 29th, 2004, 04:27 PM
#5
Originally posted by JonnoA
2- For all the simulations, the data and all other functionality (except for OnFileNew) is stored in the CBaseDoc base class. I am only using different document classes and document templates classes to put the code which runs the simulation on File>New...
Instead I would like just ONE DOCUMENT CLASS. I would choose File>New>SimulationA, for example, it would run the simulation and if successful it would put the results in a new document.
So, you mean, that CBaseDoc has all data, but the CSimulationDocA, CSimulationDocB classes have the simulation logic ?
-
April 29th, 2004, 04:31 PM
#6
MrViggy:
Yes I am handling File->New>sub menu items, but just as an alternative to the dlg box which MFC pops up (which is NEVER seen in commercial apps). This part works fine. In fact the only problem this introduced (other than increased complexity and more classes) is in File>Open/save as dialog boxes: because each doc template uses the same string resource, I get numerous file extension filters all the same.
Cheers
Jon
-
April 29th, 2004, 04:45 PM
#7
Kirants:
YES, but the simulations are only called from CSimulationADoc, CSimulationBDoc etc
As an example(simplified):
BOOL CSimulationADoc::OnNewDocument()
{
SimulationA simulation; // create a simulation
if (simulation.run()) { // run the simulation and if successful...
m_Data = simulation.Data; //copy the data into m_Data, held in CBaseDoc
return TRUE;
}
return FALSE;
}
So it all works neatly at the moment - if the simulation fails, FALSE is returned and no document is created. If the simulation works, the data is copied into a member variable in my document base class.
-
April 29th, 2004, 04:57 PM
#8
Originally posted by JonnoA
MrViggy:
Yes I am handling File->New>sub menu items, but just as an alternative to the dlg box which MFC pops up (which is NEVER seen in commercial apps). This part works fine. In fact the only problem this introduced (other than increased complexity and more classes) is in File>Open/save as dialog boxes: because each doc template uses the same string resource, I get numerous file extension filters all the same.
Cheers
Jon
You should provide your own overrides for them, too. Otherwise, you get the default (which is what you're seeing).
You can easily override File->Open and File->SaveAs; and then pop up the common "File Open(SaveAs)" dialog, with whatever extension(s) you want...
Viggy
-
April 29th, 2004, 04:57 PM
#9
you could do this:
1. Just have one template -> say MyDocTemplate
2. Just use one document class -> say CBaseDoc
3. Use a simulation class for each simulation derived from CBaseSimulation. In CBaseSimulation implement have a virtual method Run() which does nothing. Override these in SimulationA, SimulationB etc to do specific things.
4. Override, CreateNewDocument in MyDocTemplate class
5. In the override, do this
Code:
CDocument* MyDocTemplate::CreateNewDocument()
{
// default implementation constructs one from CRuntimeClass
if (m_pDocClass == NULL)
{
TRACE0("Error: you must override CDocTemplate::CreateNewDocument.\n");
ASSERT(FALSE);
return NULL;
}
CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
if (pDocument == NULL)
{
TRACE1("Warning: Dynamic create of document type %hs failed.\n",
m_pDocClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CDocument, pDocument);
//now depending on the simulation you want, set the simulation accordingly
( (CBaseDoc*)pDocument)->SetSimulation(blah blah);
AddDocument(pDocument);
return pDocument;
}
CBaseDoc::SetSimulation(blah blah)
{
if(blah blah == A)
m_pSimulation = new CSimulationA;
else...
}
CBaseDoc::OnNewDocument()
{
m_pSimulation->Run();
....
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|