单文档程序的用户命令的处理顺序

    技术2022-05-19  25

    1.OnCmdMsg的代码 BOOL CFrameWnd::OnCmdMsg(...) {        CView* pView = GetActiveView();        if(pView != NULL && pView->OnCmdMsg(...))               return TRUE;        if (CWnd::OnCmdMsg(...))               return TRUE;        CWinApp* pApp = AfxGetApp();        if(pApp != NULL && pApp->OnCmdMsg(...))               return TRUE;        return FALSE; // call ::DefWindowProc } 2.用户命令默认处理的对象: Application: File-New File-Open File-Exit Document: File-Save File-Save As CFrameWnd tool bars status resize 注意:只有用户命令消息和UI更新消息才回被按上面的顺序处理。键盘输入和鼠标输入直接被活动窗口处理(视图或者框架窗口)。文档对象和程序对象不会接受处理任何非命令消息。  1.ID_FILE_NEW   入口:ON_COMMAND(ID_FILE_NEW,CWinApp::OnFileNew) CWinApp::OnFileNew调用CDocManager::OnFileNew. CDocManager::OnFileNew判断文档模板是否多于一个,是则显示文档类型对话框(AFX_IDD_NEWTYPEDLG) ,让用户选择要创建的文档类型。然后调用CDocTemplate::OpenDocumentFile(NULL). CDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMake_Visible=TRUE)对于SDI和MDI的处理不一样。     对于SDI, (1),若已有文档打开,对其重新初始化,调用CDocument::SaveModified()保存当前文档;若没   有文档存在,则调用CreateNewDocument()创建文档对象,再调用CreateNewFrame(pDoucment,NULL)创建   文档的框架窗口。 (2),若lpszPathName为NULL,则调用CDocument::OnNewDocument()处理新文档,用   pDocument->SetPathName(lpszPathName)设置文档的路径。 (3),判断当前线程主框架窗口是否存在,不存   在则将1中创建的新框架作为主框架。 (4),调用InitialUpdateFrame显示框架窗口。     对于MDI,与SDI基本相同,但是没有第3步。   CDocument::OnNewDocument()首先调用DeleteContents()删除原文档内容,使用m_strPathName.Empty()   清除当前文档路径,SetModifiedFlag(FALSE)。   --------------------------------------------------------------------   摘抄关于ID_FILE_NEW的处理代码 CWinApp::OnFileNew()   {       CDocManager::OnFileNew()       {           if(没有文档模板)               return;           if(有多个文档模板)           {               弹出对话框让用户选择;               取得模板指针;           }           CMultiDocTemplate::OpenDocumentFile()           {               new一个文档;               创建子框架;               构建frame,doc,view之间的关系;               CDocument::OnNewDocument()               {                   DeleteContents();               }               InitialUpdateFrame();               return pDoc;           }       }   }    2.ID_FILE_OPEN   入口:ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen) CWinApp::OnFileOpen调用CDocManager::OnFileOpen。   CDocManager::OnFileOpen首先显示文件打开对话框(AFX_IDS_OPENFILE),然后调用CWinApp::OpenDocumentFile(FileName)。   CWinApp::OpenDocumentFile(FileName)调用CDocManager::OpenDocumentFile。   CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)遍历文档模板,对每个模板用MatchDocType(szPath,pOpenDocument)匹配文档类型。匹配时主要根据文件扩展名判断。若文件已经在某个文档中打开,则激活文档的第一个视图,否则用匹配的文档模板pBestTemplate->OpenDocumentFile(szPath)。   CDocTemplate::OpenDocumentFile调用CDocument::OnOpenDocument打开文件。   CDocument::OnOpenDocument打开文件,用DeleteContents删除现有文档内容,创建文件对应的CArchive对象loadArchive,Serialize(loadArchive)读文件内容,SetModifiedFlage(FALSE)。   MDI: New Frame, New View?   SDI: Update View?   摘抄关于MDI的ID_FILE_OPEN   CWinApp::OnFileOpen()   {       CDocManager::OnFileOpen()       {           CDocManager::DoPromptFileName()           {               CFileDialog::DoModal();           }           CWinApp::OpenDocumentFile()           {               ...选择文档模板;               ...调整视图和框架;               CDocTemplate::OpenDocumentFile();               {                   判断有无现存文档,是否需要保存                   新建框架                   判断文件是否存在,调用CMyDoc::OnOpenDocunment/OnNewDocument               }           }       }   }     摘抄关于SDI的ID_FILE_OPEN代码 CWinApp::OnFileOpen()   {       CDocManager::OnFileOpen()       {           CDocManager::DoPromptFileName()           {               CFileDialog::DoModal();           }           CWinApp::OpenDocumentFile()           {               ...选择文档模板;               ...调整视图和框架;               CDocTemplate::OpenDocumentFile();               {                   判断有无现存文档,是否需要保存                   新建框架                   判断文件是否存在                   CMyDoc::OnOpenDocunment()                   {                       打开文件;                       DeleteContents();                       建立CArchive;                       Serialize;                       关闭CArchive;                   }               }           }       }   }  

    3.ID_FILE_SAVE   入口:ON_COMMAND(ID_FILE_SAVE,CDocument::OnFileSave) CDocument::OnFileSave调用CDocument::DoFileSave()。   CDocument::OnFileSave判断文件是否只读,是则DoSave(NULL),否则DoSave(m_strPathName)。   CDocument::DoSave(LPCTSTR lpszPathName,BOOL bReplace=TRUE)的流程为:   1,判断lpszPathName不空则跳第二步,为空则获取文档的路径名,加上扩展符。bReplace为TRUE则显示保存文件对话框(AFX_IDS_SAVEFILE),否则显示拷贝保存对话框(AFX_IDS+SAVEFILECOPY)。   2,调用CDocument::OnSaveDocument保存文档。   3,若bReplace==TRUE则SetPathName(newName)覆盖当前路径名。   CDocument::OnSaveDocument打开文件,创建CArchive对象saveArchive,Serialize(saveArchive)读写文件,SetModifiedFlag(FALSE)。   摘抄关于ID_FILE_SAVE的代码 CDocument::OnFileSave()   {       DoFileSave(NULL)       {           CFileDialog::DoModal();           OnSaveDocument()           {               CArchive;               Serialize;           }       }   }

    4.ID_FILE_SAVEAS   入口:ON_COMMAND(ID_FILE_SAVEAS,CDocument::OnFileSaveAs) CDocument::OnFileSave调用DoSave(NULL)。     5.ID_FILE_CLOSE   入口:ON_COMMAND(ID_FILE_SAVEAS,CDocument::OnFileClose) CDocument::OnFileClose调用SaveModified()保存文件,再用OnCloseDocument处理文档关闭。   CDocument::SaveModified()用IsModified()判断是否修改,是则显示文件保存对话框(AFX_IDP_ASK_TO_SAVE),若用户选择“是”,则调用DoFileSave()保存文件。   CDocument::OnCloseDocument()首先销毁文档框架,再用DeleteContents()删除文档内容,若m_bAutoDelete则delete this。 


    最新回复(0)