zoukankan      html  css  js  c++  java
  • 单文档、多文档浅析 [一]

    废话不多说,直切主题。(以下的示例说明均以MDI作为叙述)

    整个程序就相当于一个 文档模板[CSingleDocTemplate/CMultiDocTemplate]列表,单文档就是只有一个模板,多文档就是有多个模板。

    一个模板就包括:菜单[Menu]、文档[Doc]、框架[Frame]、视图[View]

    注意,他们是一个整体。

    看一下代码:

    CMultiDocTemplate* pDocTemplate;
    pDocTemplate = new CMultiDocTemplate(
        IDR_MDI_TETYPE, // 菜单资源ID
        RUNTIME_CLASS(CMDI_testDoc),
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame
        RUNTIME_CLASS(CMDI_testView));
    AddDocTemplate(pDocTemplate); // 放到模板列表中

    当使用VC自动生成的代码时,编译运行,使用菜单“开始”->“新建”,会从模板列表中选择一个模板进行创建一个“整体”,最初的话,会自动生成一个新的窗口,因为最初只有一个文档模板(“整体”),所以,它自动就生成了一个。注意菜单ID,它是子框架的菜单,它与ChildFrame绑定在一起了。我们可以通过关闭所有的View窗口,就可以观察到菜单改变了,MainFrame主框架和ChildFrame在默认的情况下,它们的菜单是不同的。

    请做试验:添加一个菜单,响应该菜单函数,代码就是创建一个新的模板,并加入到列表:

    CMultiDocTemplate* pDocTemplate;
    pDocTemplate = new CMultiDocTemplate(
        IDR_MDI_TETYPE,
        RUNTIME_CLASS(CMDI_testDoc),
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame
        RUNTIME_CLASS(CMDI_testView));
    AddDocTemplate(pDocTemplate);

    再通过“开始”->“新建”,这个时候,你会不会发现,这个时候,就会有两个模板供你选择了,因为你已经又创建了一个模板。如下图:

     

    说完了他们一个整体性,接下来,我们就来说说一个整体中,各个部件的关系。

    1)框架 (Frame)是视图和文档的载体,视图是一个窗口,文档则不是窗口,视图是要显示在框架中的。我们看一下窗口父子关系:

    从上面这两幅图对比,可以看出,视图“sfdjk”的父窗口是“MDIClient”即是类CChildFrame[它从CMDIClientWnd派生出来]的对象。

    2)视图是显示文档数据的窗口。这里可以看出,文档负责管理数据,视图负责将文档中的数据显示出来。我们可以看下视图OnDraw的代码:

    void CMDI_testView::OnDraw(CDC* pDC)
    {
        CMDI_testDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        // TODO: add draw code for native data here
    }

    通过GetDocument就获取了文档的指针,然后就能去文档中取数据,并在OnDraw中显示出来。我们要知道的是,视图View是有一个文档Document的指针的,这便是对应关系了。[文档并不需要一个视图指针,因为数据便是数据,它不需要去关心谁去显示它,但是事实上,它保存有与它关联的视图指针]

    很多时候,我们一个文档可以会包含有多份不同类别的数据,而又想用不同的窗口显示不同类别的数据,这个时候,可以创建多个视图,一个文档是可以包含多个视图的。然后在程序中处理好视图的切换即可。我们创建一个新的视图时,如何与文档关联起来呢?见代码[主框架中,而非子框架中]:

    // 文档和视图关联
    
    CDocument* m_pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument(); // 这里为什么要获取活动的文档呢?
    // 因为主框架有可能含有多个模板,就有可能有多个文档[因为一个模板有一个文档就足够了,多出的文档有可能是其它模板的]
    // 所以要获取活动的文档 CCreateContext context; context.m_pCurrentDoc
    = m_pDoc; // 创建视图 UINT nIDFORANOTHERVIEW = AFX_IDW_PANE_FIRST + 1; CRect rect; m_pAnotherView->Create(
      NULL,
      NULL,
      WS_CHILD,
      rect,
      ((CFrameWnd*)m_pMainWnd)->GetActiveFrame (),
      nIDFORANOTHERVIEW,
      &context);

    通过 CCreateCContext对象进行关联。注意:因为框架是视图和文档的载体,所以框架有必要提供接口:获取活动文档、获取活动视图 [这里要注意,文档和视图虽然是对应关系,或者说有一定的包含关系,但它们并不能互相管理对方,它们只能由框架(Frame)进行统一管理]。

    视图既然是显示在框架上的,那二者又如何关联起来呢?见代码:

    CChildFrame * pFrm = new CChildFrame();// 框架可以是你新建或者定制的框架类
    
    CCreateContext context;
    context.m_pNewViewClass = RUNTIME_CLASS(CDemoView);// 视图可以是你想显示的视图
    // context.m_pCurrentDoc = m_pDoc;// m_pDoc 就是你要关联到的文档对象
    // 也可以进行文档的关联
    
    pFrm->LoadFrame(IDR_TEST2TYPE,WS_CHILD|WS_OVERLAPPEDWINDOW, this, &context);// 菜单资源你可以修改
    
    pFrm->ShowWindow(SW_SHOW);// 显示窗口
    
    pFrm->InitialUpdateFrame(NULL,true);// 调用视图的 OnInitialUpdate ()和框架的 ActiveFrame (),你可以在这里设置窗口的标题 

     最后来说一下他们之间的关系。

    Frame框架可以:

    1)获取活动的Frame框架[如果没有子框架,就返回它自己]

    2)获取活动的文档

    2)获取/设置活动的视图

    Document文档可以:

    1)获取Frame框架

    2)增加/删除视图

    3)更新视图

    4)设备所有从该文档生成的Frame框架的标题

    View视图可以:[就它最可怜]

    1)获取它所关心的文档

     参考资料:http://blog.163.com/hzxjtx@126/blog/static/356533742009121105752954/

  • 相关阅读:
    js 和 jquery 动态创建元素
    京东火车票正式上线:开卖火车票!
    网易旗下新域名泰坦尼克曝光:要出航海题材新作
    Facebook CEO扎克伯格造访日本,获首相会见
    struts2教程系列
    hadoop方面的资料
    FlexViewer入门资料
    深入浅出Flex Viewer系列
    flex css
    【Flex4中的皮肤使用组件数据】系列
  • 原文地址:https://www.cnblogs.com/lin1270/p/2917440.html
Copyright © 2011-2022 走看看