CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jan 2004
    Posts
    29

    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

  2. #2
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    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 ?

  3. #3
    Join Date
    Jan 2004
    Posts
    29
    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

  4. #4
    Join Date
    Feb 2002
    Posts
    4,640
    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

  5. #5
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354
    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 ?

  6. #6
    Join Date
    Jan 2004
    Posts
    29
    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

  7. #7
    Join Date
    Jan 2004
    Posts
    29
    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.

  8. #8
    Join Date
    Feb 2002
    Posts
    4,640
    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

  9. #9
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354
    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
  •  





Click Here to Expand Forum to Full Width

Featured