首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > 读写文档
【标  题】:读写文档
【关键字】:
【来  源】:http://blog.csdn.net/mqt_2003/archive/2006/11/24/1410686.aspx

读写文档

读写文档

作者:(ECNU)孟庆涛      Email:mqt-2003@163.com

 

1:通过菜单选择文档模板

void CMyApp::OnFileNewStudent()
{
    OpenNewDocument("Studnt");
}
void CMyApp::OnFileNewTeacher()
{
    OpenNewDocument("Teachr");
}

Then add the OpenNewDocument helper function as follows:

BOOL CMyApp::OpenNewDocument(const CString& strTarget)
{
    CString strDocName;
    CDocTemplate* pSelectedTemplate;
    POSITION pos = GetFirstDocTemplatePosition();
    while (pos != NULL) {
        pSelectedTemplate = (CDocTemplate*) GetNextDocTemplate(pos);
        ASSERT(pSelectedTemplate != NULL);
        ASSERT(pSelectedTemplate->IsKindOf(RUNTIME_CLASS(CDocTemplate)));
        pSelectedTemplate->GetDocString(strDocName,CDocTemplate::docName);
        if (strDocName == strTarget) { // from template's
                                       //  string resource
            pSelectedTemplate->OpenDocumentFile(NULL);
            return TRUE;
        }
    }
    return FALSE;
}

2:序列化

   在面向对象程序设计领域中,对象可以被持续,即当程序退出时他们可以被存盘,而当程序重启动时他们又可以被恢复。对象的这种存盘和恢复处理过程就称为“序列化”。
                                                                    

持续文档对象

Serialize

CArchive

CFile

    The CArchive object buffers data for the CFile object, and it maintains an internal flag that indicates whether the archive is storing (writing to disk) or loading (reading from disk). Only one active archive is associated with a file at any one time. The application framework takes care of constructing the CFile and CArchive objects, opening the disk file for the CFile object, and associating the archive object with the file. All you have to do (in your Serialize function) is load data from or store data in the archive object. The application framework calls the document’s Serialize function during the File Open and File Save processes

3:File/NewFile/Open

1CWinApp::OnFileNew

Creating an Empty Document: The CWinApp::OnFileNew Function

开始运行时,CWinApp::ProcessShellCommand会自动调用OnFileNew函数

       After your application class’s InitInstance function calls the AddDocTemplate member function, it calls OnFileNew (indirectly through CWinApp::ProcessShellCommand), another important CWinApp member function. OnFileNew sorts through the web of interconnected class names and does the following:

  1. Constructs the document object but does not attempt to read data from disk.
  2. Constructs the main frame object (of class CMainFrame); it also creates the main frame window but does not show it. The main frame window includes the IDR_MAINFRAME menu, the toolbar, and the status bar.
  3. Constructs the view object; it also creates the view window but doesn’t show it.
  4. Establishes connections among the document, main frame, and view objects. Do not confuse these object connections with the class connections established by the call to AddDocTemplate.
  5. Calls the virtual CDocument::OnNewDocument member function for the document object, which calls the virtual DeleteContents function.
  6. Calls the virtual CView::OnInitialUpdate member function for the view object.
  7. Calls the virtual CFrameWnd::ActivateFrame for the frame object to show the main frame window together with the menus, view window, and control bars.
2OnFileOpen

When the MFC Application Wizard generates an application, it maps the File Open menu command to the CWinApp::OnFileOpen member function. When called, this function invokes a sequence of functions to accomplish these steps:

1.     Prompts the user to select a file.

2.     Calls the virtual function CDocument::OnOpenDocument for the already existing document object. This function opens the file, calls CDocument::DeleteContents, and constructs a CArchive object set for loading. It then calls the document’s Serialize function, which loads data from the archive.

3.     Calls the view’s OnInitialUpdate function.

3MFC源代码分析:
注意:表格左边是新建文件过程,右边是打开文件过程,没分左右的则是二者的功用部分。下面都是MFC
后台代码,涉及到序列化问题等。总之,自己品味,其乐无穷。:)
 

NEW

Open

void CWinApp::OnFileNew()

{

         if (m_pDocManager != NULL)

                   m_pDocManager->OnFileNew();

}

void CWinApp::OnFileOpen()

{

         ASSERT(m_pDocManager != NULL);

         m_pDocManager->OnFileOpen();

}

void CDocManager::OnFileNew()

{

         if (m_templateList.IsEmpty())

         {

         TRACE(traceAppMsg, 0, "Error: no document templates registered with CWinApp.\n");      

      AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

                   return;

         }

         CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();

         if (m_templateList.GetCount() > 1)

         {

         // more than one document template to choose from

         // bring up dialog prompting user

                   CNewTypeDlg dlg(&m_templateList);

                   INT_PTR nID = dlg.DoModal();

                   if (nID == IDOK)

                            pTemplate = dlg.m_pSelectedTemplate;

                   else

                            return;     // none - cancel operation

         }

         ASSERT(pTemplate != NULL);

         ASSERT_KINDOF(CDocTemplate, pTemplate);

         pTemplate->OpenDocumentFile(NULL);

         // if returns NULL, the user has already been alerted

}

void CDocManager::OnFileOpen()

{

// prompt the user (with all document templates)

         CString newName;

         if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,

           OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))

                   return; // open cancelled

      AfxGetApp()->OpenDocumentFile(newName);

// if returns NULL, the user has already been alerted

}

 

 

CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)

{

         ASSERT(m_pDocManager != NULL);

         return   m_pDocManager->OpenDocumentFile(lpszFileName);

}

 

 

 

 

 

 

 

 

 

 

 

 

CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)

{

         // find the highest confidence

         POSITION pos = m_templateList.GetHeadPosition();

         CDocTemplate::Confidence bestMatch = CDocTemplate::noAttempt;

         CDocTemplate* pBestTemplate = NULL;

         CDocument* pOpenDocument = NULL;

         TCHAR szPath[_MAX_PATH];

         ASSERT(lstrlen(lpszFileName) < _countof(szPath));

         TCHAR szTemp[_MAX_PATH];

         if (lpszFileName[0] == '\"')

                   ++lpszFileName;

         lstrcpyn(szTemp, lpszFileName, _MAX_PATH);

         LPTSTR lpszLast = _tcsrchr(szTemp, '\"');

         if (lpszLast != NULL)

                   *lpszLast = 0;        

         if( AfxFullPath(szPath, szTemp) == FALSE )

         {

                   ASSERT(FALSE);

                   return NULL; // We won't open the file. MFC requires paths with

                                // length < _MAX_PATH

         }

         TCHAR szLinkName[_MAX_PATH];

         if (AfxResolveShortcut(AfxGetMainWnd(), szPath, szLinkName, _MAX_PATH))

                   lstrcpy(szPath, szLinkName);

         while (pos != NULL)

         {

               CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);

                   ASSERT_KINDOF(CDocTemplate, pTemplate);

                   CDocTemplate::Confidence match;

                   ASSERT(pOpenDocument == NULL);

                   match = pTemplate->MatchDocType(szPath, pOpenDocument);

                   if (match > bestMatch)

                   {

                            bestMatch = match;

                            pBestTemplate = pTemplate;

                   }

                   if (match == CDocTemplate::yesAlreadyOpen)

                            break;      // stop here

         }

         if (pOpenDocument != NULL)

         {

                   POSITION pos = pOpenDocument->GetFirstViewPosition();

                   if (pos != NULL)

                   {

         CView* pView = pOpenDocument->GetNextView(pos); // get first one

                            ASSERT_VALID(pView);

                            CFrameWnd* pFrame = pView->GetParentFrame()

                            if (pFrame == NULL)

                                     TRACE(traceAppMsg, 0, "Error: Can not find a frame for document to activate.\n");

                            else

                            {pFrame->ActivateFrame();

                                     if (pFrame->GetParent() != NULL)

                                     {

                                               CFrameWnd* pAppFrame;

                                               if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()->m_pMainWnd))

                                               {

                                                        ASSERT_KINDOF(CFrameWnd, pAppFrame);

                                                        pAppFrame->ActivateFrame();

                                               }

                                     }

                            }

                   }

                   else

                            TRACE(traceAppMsg, 0, "Error: Can not find a view for document to activate.\n");

                   return pOpenDocument;

         }

         if (pBestTemplate == NULL)

         {

                   AfxMessageBox(AFX_IDP_FAILED_TO_OPEN_DOC);

                   return NULL;

         }

         return pBestTemplate->OpenDocumentFile(szPath);

}

 

: 单文档模板

CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)

// if lpszPathName == NULL => create new file of this type

{

CDocument* pDocument = NULL;

CFrameWnd* pFrame = NULL;

BOOL bCreated = FALSE;      // => doc and frame created

BOOL bWasModified = FALSE;

 

if (m_pOnlyDoc != NULL)

{

// already have a document - reinit it

pDocument = m_pOnlyDoc;

if (!pDocument->SaveModified())

return NULL;        // leave the original one

 

pFrame = (CFrameWnd*)AfxGetMainWnd();

ASSERT(pFrame != NULL);

ASSERT_KINDOF(CFrameWnd, pFrame);

ASSERT_VALID(pFrame);

}

else

{

// create a new document

pDocument = CreateNewDocument();    //建立一个新的文档对象

ASSERT(pFrame == NULL);     // will be created below

bCreated = TRUE;

}

if (pDocument == NULL)

{

AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

return NULL;

}

ASSERT(pDocument == m_pOnlyDoc);

 

if (pFrame == NULL)

{

ASSERT(bCreated);

 

// create frame - set as main document frame

BOOL bAutoDelete = pDocument->m_bAutoDelete;

pDocument->m_bAutoDelete = FALSE;

// don't destroy if something goes wrong

pFrame = CreateNewFrame(pDocument, NULL);     //在这里建立框架和视图,实现三位一体

pDocument->m_bAutoDelete = bAutoDelete;

if (pFrame == NULL)

{

AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

delete pDocument;       // explicit delete on error

return NULL;

}

}

if (lpszPathName == NULL)       //  File/NEW而言

{

// create a new document

SetDefaultTitle(pDocument);

 

// avoid creating temporary compound file when starting up invisible

if (!bMakeVisible)

pDocument->m_bEmbedded = TRUE;

 

if (!pDocument->OnNewDocument())//调用前面建立的文档对象的函数,建立新文档

{

// user has been alerted to what failed in OnNewDocument

TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE.\n");

if (bCreated)

pFrame->DestroyWindow();    // will destroy document

return NULL;

}

}

else                    //File/Open而言

{

CWaitCursor wait;

// open an existing document

bWasModified = pDocument->IsModified();

pDocument->SetModifiedFlag(FALSE);  // not dirty for open

if (!pDocument->OnOpenDocument(lpszPathName))

{

// user has been alerted to what failed in OnOpenDocument

TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE.\n");

if (bCreated)

{

pFrame->DestroyWindow();    // will destroy document

}

else if (!pDocument->IsModified())

{

// original document is untouched

   pDocument->SetModifiedFlag(bWasModified);

}

else

{

// we corrupted the original document

SetDefaultTitle(pDocument);

if (!pDocument->OnNewDocument())

{

TRACE(traceAppMsg, 0, "Error: OnNewDocument failed after trying "

"to open a document - trying to continue.\n");

// assume we can continue

}

}

return NULL;        // open failed

}

 pDocument->SetPathName(lpszPathName);

}

 

CWinThread* pThread = AfxGetThread();

ASSERT(pThread);