MFC的SDI程序的用户命令的处理顺序

C++--MFC的SDI程序的用户命令的处理顺序

 

1.用户命令处理顺序图

2. 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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值