8.2. Documents

Microsoft Visual C++/Microsoft Foundation Classes


8.2. Documents

8.2.1. Do I have to use the Document/View architecture?

MFC does not force you to use document/views. Check out hello, mdi, and helloapp samples, they don't use it at all. Most MFC features can be used in non-document/view applications. You do lose features like print preview and of many OLE features when you don't go document/view.

[email protected] 6/7/95

8.2.2. How do I get the current Document?

See section 8.1.5. for the details.

8.2.3. When are documents destroyed?

In SDI applications, the document is deleted when the application exits. In MDI applications, the document is deleted when the last view on the document is closed. To help keep your document SDI/MDI compatible, you should delete the document's data in the virtual DeleteContents() function, not in the destructor.

Richard Hazenberg, [email protected], programmer.misc, 6/24/95

8.2.4. How do I create multiple documents?

To add support for additional document types, you can create and register additional CMultiDocTemplate objects with your CWinApp derived object. This technique is illustrated in the MULTDOCS sample application. The general steps needed to add an additional document type to an MFC application are listed below:

  1. Use AppWizard to create a new document class and a new view class.
  2. Use the Resource Editor to add a new resource string to support the new document class. For more information on the format of the document template string resource, see the topic How to Interpret a Document Template String.
  3. Use the Resource Editor to add an additional icon and menu resource to the application. Note, the ID for each of these resources needs to be the same ID as the resource ID used for the document template string created in step 2. This ID is used by the CMultiDocTemplate class to identify the resources associated with the additional document type.
  4. In the applications InitInstance() function, create another CMultiDocTemplate object and register it with the CWinApp::AddDocTemplate() function. For example:

CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate( IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CView2)); AddDocTemplate(pDocTemplate2);

  1. And finally, add the custom serialization and painting code to your new document and view classes.

MS FAQ, 6/25/95

8.2.5. How do I get a list of open documents?

The code below demonstrates how to retrieve a list of pointers to all CDocuments that were created using a CDocTemplate object.

In the code below, CMyApp is derived from CWinApp. The variable m_templateList is a CPtrList object that is a member of CWinApp, and it contains a list of pointers to all of the document templates (CDocTemplates). The CDocTemplate functions GetFirstDocPosition() and GetNextDoc() are used to iterate through the list of documents for each document template.

void CMyApp::GetDocumentList(CObList * pDocList)
{
    ASSERT(pDocList->IsEmpty());
    POSITION pos = m_templateList.GetHeadPosition();
    while (pos)
    {
        CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
        POSITION pos2 = pTemplate->GetFirstDocPosition();
        while (pos2)
        {
            CDocument* pDocument;
            if ((pDocument=pTemplate->GetNextDoc(pos2)) != NULL)
                pDocList->AddHead(pDocument);
        }
    }
}

There are two public member functions of the CDocTemplate class that are not documented in the reference manual or the online help. However, these are public member functions defined in the CDocTemplate class and provide simple functionality for traversing the list of open documents. These functions operate as follows:
Function: virtual POSITION GetFirstDocPosition() const;
Remarks: Call this function to get the position of the first document in the list of open documents associated with the template.
Return Value: A POSITION value that can be used for iteration with the GetNextDoc member function.
 
Function: virtual CDocument* GetNextDoc(POSITION& rPosition) const;
rPosition: A reference to a POSITION value returned by a previous call to the GetNextDoc or GetFirstDocPosition member function. This value must not be NULL.
Remarks: Call this function to iterate through all of the document template's open documents. The function returns the document identified by rPosition and then sets rPosition to the POSITION value of the next document in the list. If the retrieved document is the last in the list, then rPosition is set to NULL.
Return Value: A pointer to the view identified by rPosition.

MS FAQ, 6/25/95

NOTE: This is only valid for MFC 3.2 and lower, MFC 4.0 version follows->

void CMyApp::DoSomethingToAllDocs()
{
    CObList pDocList;
    POSITION pos = GetFirstDocTemplatePosition();
    while(pos)
    {
        CDocTemplate* pTemplate = GetNextDocTemplate(pos);
        POSITION pos2 = pTemplate->GetFirstDocPosition();
        while(pos2)
        {
            CDocument* pDocument;
            if(pDocument = pTemplate->GetNextDoc(pos2))
            pDocList.AddHead(pDocument);
        }
    }
    if(!pDocList.IsEmpty())
    {
        pos = pDocList.GetHeadPosition();
        while(pos)
        {
            // Call some CDocument function for each document
            ( (CDocument*)pDocList.GetNext(pos) )->UpdateAllViews(NULL);
        }
    }
}

[email protected], email, 9/22/95

8.2.6. How do I keep my application from creating a new document at startup?

Add this call:

cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing

just before the call to ProcessShellCommand in the app's InitInstance.

[email protected], email, 1/6/96