zoukankan      html  css  js  c++  java
  • 深入浅MFC

    视图类CView

      在MFC"文档/视图"架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口。在"文档/视图"架构中,文档负责管理和维护数据;而视图类则负责如下工作:

      (1) 从文档类中将文档中的数据取出后显示给用户;

      (2) 接受用户对文档中数据的编辑和修改;

      (3) 将修改的结果反馈给文档类,由文档类将修改后的内容保存到磁盘文件中。

      文档负责了数据真正在永久介质中的存储和读取工作,视图呈现只是将文档中的数据以某种形式向用户呈现,因此一个文档可对应多个视图。

      下面我们来看看CView类的声明:

    class CView : public CWnd
    {
     DECLARE_DYNAMIC(CView) 
     // Constructors
    protected:
     CView();

     // Attributes
    public:
     CDocument* GetDocument() const;

     // Operations
    public:
     // for standard printing setup (override OnPreparePrinting)
     BOOL DoPreparePrinting(CPrintInfo* pInfo);

     // Overridables
    public:
     virtual BOOL IsSelected(const CObject* pDocItem) const; // support for OLE

     // OLE scrolling support (used for drag/drop as well)
     virtual BOOL OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll = TRUE);
     virtual BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll = TRUE);

     // OLE drag/drop support
     virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject,DWORD dwKeyState, CPoint point);
     virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject,DWORD dwKeyState, CPoint point);
     virtual void OnDragLeave();
     virtual BOOL OnDrop(COleDataObject* pDataObject,DROPEFFECT dropEffect, CPoint point);
     virtual DROPEFFECT OnDropEx(COleDataObject* pDataObject,
     DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
     virtual DROPEFFECT OnDragScroll(DWORD dwKeyState, CPoint point);

     virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

     virtual void OnInitialUpdate(); // called first time after construct

    protected:
     // Activation
     virtual void OnActivateView(BOOL bActivate, CView* pActivateView,CView* pDeactiveView);
     virtual void OnActivateFrame(UINT nState, CFrameWnd* pFrameWnd);

     // General drawing/updating
     virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
     virtual void OnDraw(CDC* pDC) = 0;

     // Printing support
     virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
     // must override to enable printing and print preview

     virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
     virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
     virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

     // Advanced: end print preview mode, move to point
     virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point,CPreviewView* pView);

     // Implementation
    public:
     virtual ~CView();
     #ifdef _DEBUG
      virtual void Dump(CDumpContext&) const;
      virtual void AssertValid() const;
     #endif //_DEBUG

     // Advanced: for implementing custom print preview
     BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView,CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);

     virtual void CalcWindowRect(LPRECT lpClientRect,UINT nAdjustType = adjustBorder);
     virtual CScrollBar* GetScrollBarCtrl(int nBar) const;
     static CSplitterWnd* PASCAL GetParentSplitter(const CWnd* pWnd, BOOL bAnyState);

    protected:
     CDocument* m_pDocument;

    public:
     virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo);
    protected:
     virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
     virtual void PostNcDestroy();

     // friend classes that call protected CView overridables
     friend class CDocument;
     friend class CDocTemplate;
     friend class CPreviewView;
     friend class CFrameWnd;
     friend class CMDIFrameWnd;
     friend class CMDIChildWnd;
     friend class CSplitterWnd;
     friend class COleServerDoc;
     friend class CDocObjectServer;

     //{{AFX_MSG(CView)
      afx_msg int OnCreate(LPCREATESTRUCT lpcs);
      afx_msg void OnDestroy();
      afx_msg void OnPaint();
      afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
      // commands
      afx_msg void OnUpdateSplitCmd(CCmdUI* pCmdUI);
      afx_msg BOOL OnSplitCmd(UINT nID);
      afx_msg void OnUpdateNextPaneMenu(CCmdUI* pCmdUI);
      afx_msg BOOL OnNextPaneCmd(UINT nID);

      // not mapped commands - must be mapped in derived class
      afx_msg void OnFilePrint();
      afx_msg void OnFilePrintPreview();
     //}}AFX_MSG
     DECLARE_MESSAGE_MAP()
    };


      CView类首先要维护文档与视图之间的关联,它通过CDocument* m_pDocument保护性成员变量记录关联文档的指针,并提供CView::GetDocument接口函数以使得应用程序可得到与视图关联的文档。而在CView类的析构函数中,需将对应文档类视图列表中的本视图删除:

    CView::~CView()
    {
     if (m_pDocument != NULL)
      m_pDocument->RemoveView(this);
    }


      CView中地位最重要的函数是virtual void OnDraw(CDC* pDC) = 0;从这个函数的声明可以看出,CView是一个纯虚基类。这个函数必须被重载,它通常执行如下步骤:

      (1) 以GetDocument()函数获得视图对应文档的指针;

      (2) 读取对应文档中的数据;

      (3) 显示这些数据。

      以MFC向导建立的一个初始"文档/视图"架构工程将这样重载OnDraw()函数,注意注释中的"add draw code for native data here(添加活动数据的绘制代码)":

    /////////////////////////////////////////////////////////////////////////////
    // CExampleView drawing
    void CExampleView::OnDraw(CDC* pDC)
    {
     CExampleDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
     // TODO: add draw code for native data here
    }
    CView::PreCreateWindow负责View的初始化:
    /////////////////////////////////////////////////////////////////////////////
    // CView second phase construction - bind to document
    BOOL CView::PreCreateWindow(CREATESTRUCT & cs)
    {
     ASSERT(cs.style & WS_CHILD);

     if (cs.lpszClass == NULL)
     {
      VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
      cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
     }

     if (afxData.bWin4 && (cs.style & WS_BORDER))
     {
      cs.dwExStyle |= WS_EX_CLIENTEDGE;
      cs.style &= ~WS_BORDER;
     }

     return TRUE;
    }


      CView::OnUpdate函数在文档的数据被改变的时候被调用(即它被用来通知一个视图的关联文档的内容已经被修改),它预示着我们需要重新绘制视图以显示变化后的数据。其中的Invalidate(TRUE)将整个窗口设置为需要重绘的无效区域,它会产生WM_PAINT消息,这样OnDraw将被调用:

    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);
    }


      假如文档中的数据发生了变化,必须通知所有链接到该文档的视图,这时候文档类的UpdateAllViews函数需要被调用。

      此外,CView类包含一系列函数用于进行文档的打印及打印预览工作:

      (1)CView::OnBeginPrinting在打印工作开始时被调用,用来分配GDI资源;

      (2)CView::OnPreparePrinting函数在文档打印或者打印预览前被调用,可用来初始化打印对话框;

      (3)CView::OnPrint用来打印或打印预览文档;

      (4)CView::OnEndPrinting函数在打印工作结束时被调用,用以释放GDI资源;

      (5)CView::OnEndPrintPreview在退出打印预览模式时被调用。

      CView派生类

      MFC提供了丰富的CView派生类,各种不同的派生类实现了对不同种类控件的支持,以为用户提供多元化的显示界面。这些CView派生类包括:

      (1)CScrollView:提供滚动支持;

      (2)CCtrlView:支持tree、 list和rich edit控件;

      (3)CDaoRecordView:在dialog-box控件中显示数据库记录;

      (4)CEditView:提供了一个简单的多行文本编辑器;

      (5)CFormView:包含dialog-box控件,可滚动,基于对话框模板资源; 

      (6)CListView:支持list控件;

      (7)CRecordView:在dialog-box控件中显示数据库记录;

      (8)CRichEditView:支持rich edit控件;

      (9)CTreeView:支持tree控件。

      其中,CRichEditView、CTreeView及CListView均继承自CCtrlView类;CFormView继承自CScrollView类;CRecordView、CDaoRecordView则进一步继承自CFormView类。

      下图描述了CView类体系的继承关系:

  • 相关阅读:
    Selenium(Python)等待元素出现
    java文件的I/O
    Map的四种遍历方式
    模板类实现链表
    字符串相关库函数使用
    动态规划之背包问题
    最长递增子序列
    深度优先搜索(DFS),逃离迷宫
    素数环问题(递归回溯)
    枚举(百鸡问题)
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/5085380.html
Copyright © 2011-2022 走看看