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++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

java中ssh2执行多条命令的四种方法

《java中ssh2执行多条命令的四种方法》本文主要介绍了java中ssh2执行多条命令的四种方法,包括分号分隔、管道分隔、EOF块、脚本调用,可确保环境配置生效,提升操作效率,具有一定的参考价值,感... 目录1 使用分号隔开2 使用管道符号隔开3 使用写EOF的方式4 使用脚本的方式大家平时有没有遇到自

Spring Boot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)

《SpringBoot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)》本文将以一个实际案例(用户管理系统)为例,详细解析SpringBoot中Co... 目录引言:为什么学习Spring Boot分层架构?第一部分:Spring Boot的整体架构1.1

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Linux命令rm如何删除名字以“-”开头的文件

《Linux命令rm如何删除名字以“-”开头的文件》Linux中,命令的解析机制非常灵活,它会根据命令的开头字符来判断是否需要执行命令选项,对于文件操作命令(如rm、ls等),系统默认会将命令开头的某... 目录先搞懂:为啥“-”开头的文件删不掉?两种超简单的删除方法(小白也能学会)方法1:用“--”分隔命

5 种使用Python自动化处理PDF的实用方法介绍

《5种使用Python自动化处理PDF的实用方法介绍》自动化处理PDF文件已成为减少重复工作、提升工作效率的重要手段,本文将介绍五种实用方法,从内置工具到专业库,帮助你在Python中实现PDF任务... 目录使用内置库(os、subprocess)调用外部工具使用 PyPDF2 进行基本 PDF 操作使用