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

2024-03-22 23:58

本文主要是介绍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。 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1765131


这篇关于C++--MFC的SDI程序的用户命令的处理顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836514

相关文章

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表