• MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同


    MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同

    若文档内容有修改,则前者会询问用户,是否保存修改;后者不保存修改直接关闭。
    原因在于,从菜单关闭时,调用OnClose,一定会调用SaveModified(),其源码如下

    /
    // Standard file menu commands
    
    void CDocument::OnFileClose()
    {
    	if (!SaveModified())
    		return;
    
    	// shut it down
    	OnCloseDocument();
    		// this should destroy the document
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    而点击x关闭时,CanCloseFrame()函数会判断是否保存文档,其源码如下:

    BOOL CDocument::CanCloseFrame(CFrameWnd* pFrameArg)
    	// permission to close all views using this frame
    	//  (at least one of our views must be in this frame)
    {
    	ASSERT_VALID(pFrameArg);
    	UNUSED(pFrameArg);   // unused in release builds
    
    	POSITION pos = GetFirstViewPosition();
    	while (pos != NULL)
    	{
    		CView* pView = GetNextView(pos);
    		ASSERT_VALID(pView);
    		CFrameWnd* pFrame = pView->GetParentFrame();
    		// assume frameless views are ok to close
    		if (pFrame != NULL)
    		{
    			// assumes 1 document per frame
    			ASSERT_VALID(pFrame);
    			if (pFrame->m_nWindow > 0)
    				return TRUE;        // more than one frame refering to us
    		}
    	}
    
    	// otherwise only one frame that we know about
    	return SaveModified();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    可见,仅当父框架的窗口为0时才会执行SaveModified()语句,其余情况都只会返回TRUE。在使用多文档编程时,要注意为了文档的安全,在自己重载的CanCloseFrame()中加上SaveModified()语句。

    如何默默保存,不询问用户?

    CDocument::SaveModified()的实现如下:

    BOOL CDocument::SaveModified()
    {
    	if (!IsModified())
    		return TRUE;        // ok to continue
    
    	// get name/title of document
    	CString name;
    	if (m_strPathName.IsEmpty())
    	{
    		// get name based on caption
    		name = m_strTitle;
    		if (name.IsEmpty())
    			VERIFY(name.LoadString(AFX_IDS_UNTITLED));
    	}
    	else
    	{
    		// get name based on file title of path name
    		name = m_strPathName;
    		if (afxData.bMarked4)
    		{
    			AfxGetFileTitle(m_strPathName, name.GetBuffer(_MAX_PATH), _MAX_PATH);
    			name.ReleaseBuffer();
    		}
    	}
    
    	CString prompt;
    	AfxFormatString1(prompt, AFX_IDP_ASK_TO_SAVE, name);
    	switch (AfxMessageBox(prompt, MB_YESNOCANCEL, AFX_IDP_ASK_TO_SAVE))
    	{
    	case IDCANCEL:
    		return FALSE;       // don't continue
    
    	case IDYES:
    		// If so, either Save or Update, as appropriate
    		if (!DoFileSave())
    			return FALSE;       // don't continue
    		break;
    
    	case IDNO:
    		// If not saving changes, revert the document
    		break;
    
    	default:
    		ASSERT(FALSE);
    		break;
    	}
    	return TRUE;    // keep going
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    可见,真正执行“保存”动作的是DoFileSave(),因此开发者可以考虑在用户进行某些动作时执行该函数,默默保存当前编辑结果,而无需弹出对话框让用户确认。

  • 相关阅读:
    Java:强引用、软引用、弱引用与虚引用
    蓝桥杯官网练习题(幸运数字)
    Web自动化Selenium-常见控件操作
    【DAY04 软考中级备考笔记】数据结构基本结构和算法
    10年软件测试工程师经验,很茫然....
    Manopt使用
    C#餐饮收银系统
    UML,集合框架
    SpringMVC【超详情!!!】
    stm32 笔记 UART读取及HAL库应用
  • 原文地址:https://blog.csdn.net/qq_42679415/article/details/132835453