分享

CView类的使用

 pphsy 2017-12-14

首先我们来写一个例子:

1.建一个win32简单应用程序,不要认为这样就不能写出MFC程序,因为是不是MFC程序取决于调没调MFC函数。

2. 删除入口函数,只留下#include "stdafx.h"

3.将stdafx.h中的头文件 <windows.h> 更改为 <afxwin.h>。

4.Project-->Settings菜单项中设置使用MFC库

5.编写代码

  1. #include "stdafx.h"  
  2. #include "resource.h"  
  3. //视图类(创建方式与工具栏与工具栏步骤相似)  
  4. class CMyView:public CView  
  5. {  
  6. public:  
  7.     virtual void OnDraw( CDC* pDC );  
  8.     DECLARE_MESSAGE_MAP ()  
  9. protected:  
  10.     afx_msg void OnTest();  
  11.   
  12. };  
  13. BEGIN_MESSAGE_MAP(CMyView,CView)  
  14. ON_COMMAND(ID_TEST,OnTest)  
  15. END_MESSAGE_MAP()  
  16.   
  17. void CMyView::OnTest()  
  18. {  
  19.     MessageBox("CMView::OnTest");  
  20. }  
  21. void CMyView::OnDraw( CDC* pDC )  
  22. {  
  23.     pDC->TextOut(100,100,"Hello World!");  
  24. }  
  25. //框架窗口类  
  26. class CMainFrame :public CFrameWnd  
  27. {  
  28. public:  
  29. //  CMyView m_wndView;//视图类对象  
  30.     CMyView*m_pWndView;//视图类的指针  
  31.     DECLARE_MESSAGE_MAP()  
  32. protected:  
  33.     afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );  
  34.       
  35. };  
  36. BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)  
  37. ON_WM_CREATE()  
  38. END_MESSAGE_MAP()  
  39.   
  40. int CMainFrame::OnCreate( LPCREATESTRUCT lpCreateStruct )   
  41. {  
  42.     if(-1==CFrameWnd::OnCreate(lpCreateStruct))//父类的  
  43.     {  
  44.         return -1;  
  45.     }  
  46.     //创建视图窗口  
  47.     m_pWndView = new CMyView;//在堆中创建对象  
  48.     m_pWndView->Create(NULL,"MyView",WS_VISIBLE|WS_CHILD|WS_BORDER,CRect(0,0,100,100),  
  49.         this,AFX_IDW_PANE_FIRST);//AFX_IDW_PANE_FIRST可使边框和客户区重叠  
  50.     //将视图设置为活动视图  
  51.     //方式1:调用函数    
  52.     //  SetActiveView(m_pWndView);  
  53.     //方式2:指针赋值  
  54.     m_pViewActive = m_pWndView;  
  55.   
  56.     return 0;  
  57. }  
  58. //应用程序类  
  59. class CViewApp :public CWinApp  
  60. {  
  61. public:  
  62.     virtual BOOL InitInstance();  
  63.   
  64.   
  65. };  
  66. CViewApp theApp;//唯一的应用程序对象  
  67. BOOL CViewApp::InitInstance()  
  68. {  
  69.     //创建基本的主框架窗口  
  70.     CMainFrame *pFrame = new CMainFrame;  
  71.     //创建窗口,内部调用Create函数  
  72.     pFrame->LoadFrame(IDR_MENU1);//比Create函数用起来简单  
  73.     //将窗口设置为应用程序主窗口  
  74.     m_pMainWnd = pFrame;  
  75.     //显示和更新  
  76.     pFrame->ShowWindow(SW_SHOW);  
  77.     pFrame->UpdateData();  
  78.   
  79.     return TRUE;  
  80. }  
注意:

实例化CMyView对象前必须重写OnDraw()函数,因为OnDraw()是纯虚函数
        视图窗口的创建是在CMainFrame的 OnCreate()函数中调Create函数

思考&提升:

1. 为什么非要使用视图类的指针来?

 由于在CView::PostNcDestroy()函数中,调用了delete this;  所以,视图对象的创建放到堆中,即new 对象,

2. 创建视图时,怎样视图铺满框架窗口的客户区?

创建时视图的ID填AFX_IDW_PANE_FIRST

3.  为什么要将视图对象设置为框架窗口的活动视图?

因为 处理菜单等命令消息的先后顺序: 活动视图->框架窗口->应用程序。我们将对此进行验证:在消息提示框那行加断点,调试运行,我们通过调用堆栈得到下图调用信息



菜单消息都属于命令消息,所以我们找CFrameWnd 的 OnCmdMsg,双击进入CFrameWnd::OnCmdMsg()中得到

  1. BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,  
  2.     AFX_CMDHANDLERINFO* pHandlerInfo)  
  3. {  
  4.     CPushRoutingFrame push(this);  
  5.   
  6.     // pump through current view FIRST  
  7.     CView* pView = GetActiveView();  
  8.     if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))  
  9.         return TRUE;  
  10.   
  11.     // then pump through frame  
  12.     if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))  
  13.         return TRUE;  
  14.   
  15.     // last but not least, pump through app  
  16.     CWinApp* pApp = AfxGetApp();  
  17.     if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))  
  18.         return TRUE;  
  19.   
  20.     return FALSE;  
  21. }  

可以看出:处理菜单等命令消息的先后顺序: 活动视图->框架窗口->应用程序


4.OnPaintOnDraw之间的关系?

OnPaint调的是OnDraw。因为OnDraw函数比OnPaint更简单,不用添加消息映射所以视图的信息显示,直接在OnDraw函数中。



5.为什么不用框架窗口的客户区显示数据,而非要用视图窗口显示?

框架窗口:就好像个容器,负责装各种各样的子窗口
视图窗口:是一种子窗口,父类是框架窗口,负责显示数据。这样做是因为当应用程序比较复杂时,我们希望一个类去做一件事


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多