zoukankan      html  css  js  c++  java
  • CView类的使用

    首先我们来写一个样例:

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

    2. 删除入口函数。仅仅留下#include "stdafx.h"

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

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

    5.编写代码

    #include "stdafx.h"
    #include "resource.h"
    //视图类(创建方式与工具栏与工具栏步骤类似)
    class CMyView:public CView
    {
    public:
    	virtual void OnDraw( CDC* pDC );
    	DECLARE_MESSAGE_MAP	()
    protected:
    	afx_msg void OnTest();
    
    };
    BEGIN_MESSAGE_MAP(CMyView,CView)
    ON_COMMAND(ID_TEST,OnTest)
    END_MESSAGE_MAP()
    
    void CMyView::OnTest()
    {
    	MessageBox("CMView::OnTest");
    }
    void CMyView::OnDraw( CDC* pDC )
    {
    	pDC->TextOut(100,100,"Hello World!");
    }
    //框架窗体类
    class CMainFrame :public CFrameWnd
    {
    public:
    //	CMyView m_wndView;//视图类对象
    	CMyView*m_pWndView;//视图类的指针
    	DECLARE_MESSAGE_MAP()
    protected:
    	afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
    	
    };
    BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
    ON_WM_CREATE()
    END_MESSAGE_MAP()
    
    int CMainFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
    {
    	if(-1==CFrameWnd::OnCreate(lpCreateStruct))//父类的
    	{
    		return -1;
    	}
    	//创建视图窗体
    	m_pWndView = new CMyView;//在堆中创建对象
    	m_pWndView->Create(NULL,"MyView",WS_VISIBLE|WS_CHILD|WS_BORDER,CRect(0,0,100,100),
    		this,AFX_IDW_PANE_FIRST);//AFX_IDW_PANE_FIRST可使边框和客户区重叠
    	//将视图设置为活动视图
    	//方式1:调用函数  
    	//	SetActiveView(m_pWndView);
    	//方式2:指针赋值
    	m_pViewActive = m_pWndView;
    
    	return 0;
    }
    //应用程序类
    class CViewApp :public CWinApp
    {
    public:
    	virtual BOOL InitInstance();
    
    
    };
    CViewApp theApp;//唯一的应用程序对象
    BOOL CViewApp::InitInstance()
    {
    	//创建主要的主框架窗体
    	CMainFrame *pFrame = new CMainFrame;
    	//创建窗体,内部调用Create函数
    	pFrame->LoadFrame(IDR_MENU1);//比Create函数用起来简单
    	//将窗体设置为应用程序主窗体
    	m_pMainWnd = pFrame;
    	//显示和更新
    	pFrame->ShowWindow(SW_SHOW);
    	pFrame->UpdateData();
    
    	return TRUE;
    }
    注意:

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

    思考&提升:

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

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

    2. 创建视图时,如何视图铺满框架窗体的客户区?

    创建时视图的ID填AFX_IDW_PANE_FIRST

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

    由于 处理菜单等命令消息的先后顺序: 活动视图->框架窗体->应用程序。

    我们将对此进行验证:在消息提示框那行加断点,调试执行,我们通过调用堆栈得到下图调用信息



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

    BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    	AFX_CMDHANDLERINFO* pHandlerInfo)
    {
    	CPushRoutingFrame push(this);
    
    	// pump through current view FIRST
    	CView* pView = GetActiveView();
    	if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    		return TRUE;
    
    	// then pump through frame
    	if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    		return TRUE;
    
    	// last but not least, pump through app
    	CWinApp* pApp = AfxGetApp();
    	if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    		return TRUE;
    
    	return FALSE;
    }

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


    4.OnPaintOnDraw之间的关系?

    OnPaint调的是OnDraw。

    由于OnDraw函数比OnPaint更简单。不用加入消息映射所以视图的信息显示,直接在OnDraw函数中。



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

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


  • 相关阅读:
    Mysql 中的MVCC原理,undo日志的依赖
    Innodb 实现高并发、redo/undo MVCC原理
    Django restful 规范
    TCP 原理
    HTTPS建立连接的过程
    HTTP协议,Http 常用状态码
    SQL注入
    Mysql 索引问题集锦
    Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
    归并排序Python 实现
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6737572.html
Copyright © 2011-2022 走看看