打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
文档视图框架总结--My Blog Homepage

一、UpdateAllViews

如果文档的数据改变了,所有的视图都要通知到,所以一般在派生类的文档类调用UpdateAllViews函数,

注意:

(1)UpdateAllViews(this)表示不在通知当前的视图,当然这里已经假定当前视图(GetActiveView)已经更新

(2)UpdateAllViews(NULL)通知所有的视图

 

void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)

       // walk through all views

{

       ASSERT(pSender == NULL || !m_viewList.IsEmpty());

              // must have views if sent by one of them

 

       POSITION pos = GetFirstViewPosition();

       while (pos != NULL)

       {

              CView* pView = GetNextView(pos);

              ASSERT_VALID(pView);

              if (pView != pSender)

                     pView->OnUpdate(pSender, lHint, pHint);

       }

}

CDocument::UpdateAllViews调用了pView->OnUpdate(pSender, lHint, pHint);

 

CView::OnUpdate

void CView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/)

{

       ASSERT(pSender != this);

       UNUSED(pSender);     // unused in release builds

 

       // invalidate the entire pane, erase background too

       Invalidate(TRUE); //使整个视图无效,发出WM_PAINT消息

}

 

促使OnPaint()被调用

void CView::OnPaint()

{

       // standard paint routine

       CPaintDC dc(this);  //在构造函数中,BeginPaint函数被调用,联想WIN32 API中响应WM_PAINT消息的做法

       OnPrepareDC(&dc); //如果不是打印工作,什么都不做

       OnDraw(&dc);

    //dc(堆栈变量,要自动释放)的析构函数中,调用了EndPaint函数

}

 

然后调用OnDraw(&dc)虚函数,这里就是通常我们在C**View中看到的C**View::OnDraw(CDC* pDC)。在这里面做一些显示工作。

 

二、OnInitialUpdate

到用户选择了FILE 中的NEW,则会引起CView::OnInitialUpdate的调用

void CView::OnInitialUpdate()

{

       OnUpdate(NULL, 0, NULL);        // initial update

}

 

默认的CView::OnInitialUpdate除了调用OnUpdate什么都不做,可以重写这个虚函数,对视图对象进行初始化,OnInitialUpdate可以被调用多次。

 

三、OnNewDocument

调用时机:

(1)、在文档对象被构造之后(应用程序第一次启动时,实质是执行了一个file/new 命令,只是没有构造)

(2)、选择了file/new 命令

BOOL CDocument::OnNewDocument()

{

       if (IsModified())

              TRACE0("Warning: OnNewDocument replaces an unsaved document.\n");

 

       DeleteContents();

       m_strPathName.Empty();      // no path name yet

       SetModifiedFlag(FALSE);     // make clean

 

       return TRUE;

}

设置是文档数据成员初始值的好地方,OnNewDocument要调用虚函数DeleteContents()。在CDocument

void CDocument::DeleteContents()

{

}

该函数什么都不做,需要派生文档类去重写它,

特别提醒:

1、因为SDI中,只有在关闭应用程序的时候,文档对象才会调用析构函数,所以在析构函数中完成所有文档共有的成员变量的删除工作,而在DeleteContents函数中完成与某个特定文档相关的数据的删除工作。

2、在MDI中,则没有必要注意这点,因为文档对象可以被多次创建

 

 

四、简单的SDI程序启动时候的流程如下:

 

1CHelloApp::CHelloApp() 全局变量的构造函数

 

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)函数中

{

        ...............

        ...............

       if (!pThread->InitInstance()) //一般在应用程序派生类重写InitInstance虚函数

       {

              if (pThread->m_pMainWnd != NULL)

              {

                     TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");

                     pThread->m_pMainWnd->DestroyWindow();

              }

              nReturnCode = pThread->ExitInstance();

              goto InitFailure;

       }

       nReturnCode = pThread->Run(); //进入消息循环

       ................

}

 

2

CHelloApp::InitInstance()虚函数中

{

创建了文档模版,并加入文档模版链

 

before call ProcessShellCommand

 

   CHelloDoc::CHelloDoc()

   CMainFrame::CMainFrame()

   BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

   int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

 

   BOOL CHelloView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect,                            CWnd* pParentWnd, UINT nID, CCreateContext* pContext)

   BOOL CHelloView::PreCreateWindow(CREATESTRUCT& cs)

   int CHelloView::OnCreate(LPCREATESTRUCT lpCreateStruct)

 

   BOOL CHelloDoc::OnNewDocument()

   void CHelloDoc::DeleteContents()

 

   void CHelloView::OnInitialUpdate()

 

after call ProcessShellCommand

}

 

注意:

(1)SDI程序启动时,默认的ShellCommand是:file/new, 启动的时候只是构造空的文档对象

(2)、在SDI中,文档、主框架、视图对象都只被创建一次,所以再次使用file/new的时候,只完成

   BOOL CHelloDoc::OnNewDocument()

   void CHelloDoc::DeleteContents()

   void CHelloView::OnInitialUpdate(),这3个步骤

 

 

 

五、打开文件(file/open)

1、选择文件

2、调用CDocument::OnOpenDocument函数(其中:删除文档的内容,并进行了序列化)

BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)

{

       if (IsModified())

              TRACE0("Warning: OnOpenDocument replaces an unsaved document.\n");

 

       CFileException fe;

       CFile* pFile = GetFile(lpszPathName,

              CFile::modeRead|CFile::shareDenyWrite, &fe);  //打开文件

       

 

       DeleteContents();  //删除文档的内容

       SetModifiedFlag();  // dirty during de-serialize //表明改变了文档内容

 

       CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);

       loadArchive.m_pDocument = this;

       loadArchive.m_bForceFlat = FALSE;  //CArchive对象与文件关联起来,用于序列化

 

       TRY

       {

              CWaitCursor wait;

              if (pFile->GetLength() != 0)

                     Serialize(loadArchive);     // load me  //序列化

              loadArchive.Close();

              ReleaseFile(pFile, FALSE);

       }

        .......

        ........

 

       SetModifiedFlag(FALSE);     // start off with unmodified  //设置文档没有被改变

 

       return TRUE;

}

3、调用void CHelloView::OnInitialUpdate() 函数

 

 

六、保存文件(file/save file/save as)

void CDocument::OnFileSave()

{

       DoFileSave(); //DoFileSave()调用了DoSave()

}

 

void CDocument::OnFileSaveAs()

{

       if (!DoSave(NULL))

              TRACE0("Warning: File save-as failed.\n");

}

 

DoSave()调用了OnSaveDocument()函数,在OnSaveDocument()函数中进行了序列化操作

 

 

 

七、特别注意:

file/new file/open 被映射到了应用程序类

file/save fi

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
·教程:轻松玩转MFC文档视图架构编程
文档与视图的相互作用
如何联系CMainFrame和CView各自的成员变量? VC/MFC / 界面
理解MFC文档/视图框架
MFC 中获得各个类的指针/句柄 ID的总结(转)
MFC多文档和单文档视结构
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服