一、视图窗口
提供一个用于显示数据的窗口
1、视图窗口相关类
CView及其子类,父类为CWnd类,封装了关于视图窗口的各种操作,以及和文档类的数据交互
2、视图窗口的使用
(1)定义了一个自己的视图类(CMyView),派生自CView,并重写父类成员纯虚函数void OnDraw(CDC* pDC),可以用于绘图
(2)其余框架类和应用类程序代码不变
(3)处理框架的WM_CREATE消息时,定义CMyView类对象,并调用Create函数创建视图窗口,视图窗口的ID为 AFX_IDW_PANE_FIRST
3、创建项目(MFCView)
(1)创建项目
(2)编写程序
- #include
- #include "resource.h"
-
- class CMyView:public CView
- {
- DECLARE_MESSAGE_MAP()
- public:
- virtual void OnDraw(CDC* pDC);
- afx_msg void OnPaint();
- afx_msg void OnNew();
- };
- BEGIN_MESSAGE_MAP(CMyView, CView)
- //ON_WM_PAINT()
- ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
-
- //父类处理绘图消息时会调用OnDraw,当本类由绘图消息处理,则OnDraw不会被调用
- void CMyView::OnDraw(CDC* pDC)
- {
- pDC->TextOut(100, 100, "CMyView::OnDraw");
- }
- void CMyView::OnPaint()
- {
- PAINTSTRUCT ps = {0};
- HDC hdc = ::BeginPaint(m_hWnd, &ps);
- ::TextOutA(hdc, 200, 200, "CMyView::OnPaint", strlen("CMyView::OnPaint"));
- ::EndPaint(m_hWnd, &ps);
- }
- void CMyView::OnNew()
- {
- AfxMessageBox("视图类处理了OnNew消息");
- }
-
- class CMyFrameWnd:public CFrameWnd
- {
- DECLARE_MESSAGE_MAP()
- public:
- afx_msg void OnPaint();
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- afx_msg void OnNew();
- };
- BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
- ON_WM_CREATE()
- ON_WM_PAINT()
- ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
-
- int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
- {
- CMyView* pView = new CMyView;
- pView->Create(NULL, "MFCView", WS_CHILD|WS_VISIBLE|WS_BORDER, CRect(0, 0, 200, 200),
- this, AFX_IDW_PANE_FIRST); //AFX_IDW_PANE_FIRST 生成的视图窗口会平铺在框架窗口
- m_pViewActive = pView; //将窗口赋值给活动窗口
- return CFrameWnd::OnCreate(pcs);
- }
-
- void CMyFrameWnd::OnPaint()
- {
- PAINTSTRUCT ps = {0};
- HDC hdc = ::BeginPaint(m_hWnd, &ps);
- ::TextOutA(hdc, 100, 100, "框架窗口客户区", strlen("框架窗口客户区"));
- ::EndPaint(m_hWnd, &ps);
- }
- void CMyFrameWnd::OnNew()
- {
- AfxMessageBox("框架类处理了OnNew消息");
- }
-
-
- class CMyWinApp:public CWinApp
- {
- DECLARE_MESSAGE_MAP()
- public:
- virtual BOOL InitInstance();
- afx_msg void OnNew();
- };
- BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
- ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
- void CMyWinApp::OnNew()
- {
- AfxMessageBox("框架类处理了OnNew消息");
- }
-
- BOOL CMyWinApp::InitInstance()
- {
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- pFrame->Create(NULL, "MFCView", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault,NULL,
- (char*)IDR_MENU1);
- m_pMainWnd = pFrame;
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
-
- CMyWinApp theApp;
(3)命令消息处理顺序
视图类 -》 框架类 -》 应用程序类
(4)对象关系图
- theApp
- theApp->m_pMainWnd = pFrame
- pFrame->m_pViewActive = pView
-
二、文档类
相关类 CDocument,提供了用于管理数据的类,封装了关于数据的管理(数据提取,数据转换,数据存储等),并和视图类进行数据交互。
1、创建项目
(1)创建项目(MFCDoc)
(2)编写程序
- #include
- #include
- #include "resource.h"
-
- class CMyDoc:public CDocument
- {
-
- };
-
- class CMyView:public CView
- {
- DECLARE_DYNCREATE(CMyView)
- DECLARE_MESSAGE_MAP()
- public:
- virtual void OnDraw(CDC* cDC);
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- };
- IMPLEMENT_DYNCREATE(CMyView, CView)
- BEGIN_MESSAGE_MAP(CMyView, CView)
- ON_WM_CREATE()
- END_MESSAGE_MAP()
-
- void CMyView::OnDraw(CDC* cDC)
- {
- cDC->TextOut(100, 100, "视图窗口");
- }
- int CMyView::OnCreate(LPCREATESTRUCT pcs)
- {
- return CView::OnCreate(pcs);
- }
-
- class CMyFrameWnd:public CFrameWnd
- {
- DECLARE_MESSAGE_MAP()
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- afx_msg void OnPaint();
- };
- BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
- ON_WM_CREATE()
- ON_WM_PAINT()
- END_MESSAGE_MAP()
- int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
- {
- return CFrameWnd::OnCreate(pcs);
- }
- void CMyFrameWnd::OnPaint()
- {
- PAINTSTRUCT ps = {0};
- HDC hdc = ::BeginPaint(m_hWnd, &ps);
- ::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
- ::EndPaint(m_hWnd, &ps);
- }
-
- class CMyWinApp:public CWinApp
- {
- public:
- virtual BOOL InitInstance();
- };
- BOOL CMyWinApp::InitInstance()
- {
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- CCreateContext cct;
- CMyDoc* pDoc = new CMyDoc;
- cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
- cct.m_pCurrentDoc = pDoc;
- pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
- m_pMainWnd = pFrame;
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
- CMyWinApp theApp;
(3)创建过程
利用框架类对象地址(pFrame)调用LoadFrame函数,创建框架窗口
在处理框架窗口的WM_CREATE消息时,(父类CFrameWnd)动态创建视图类对象,并创建视图窗口
在处理视图窗口的WM_CREATE消息时,(父类CView)将文档类和视图类对象见理关系
2、创建流程
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- CMyDoc* pDoc = new CMyDoc;
-
- CCreateContext cct;
- cct.m_pCurrentDoc = pDoc;//文档类对象地址
- cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);//&CMyView::classCMyView
-
- pFrame->LoadFrame(... &cct)//函数内部this为pFrame
- {
- Create(...,&cct)//函数内部this为pFrame
- {
- CreateEx(...&cct)//函数内部this为pFrame
- {
- CREATESTRUCT cs;
- ....
- cs.lpCreateParams = &cct;
- ::CreateWindowEx(...,&cct);//创建主框架窗口
- }
- }
- }
- //处理框架窗口的WM_CREATE消息
- CFrameWnd::OnCreate( pcs )//函数内部this为pFrame,参数可以获取::CreateWindowEx的12个参数
- {
- CCreateContext* pContext = (CCreateContext*)pcs->lpCreateParams;//获取&cct
- OnCreateHelper(pcs, pContext)//函数内部this为pFrame,pContext===&cct
- {
- OnCreateClient(pcs, pContext)//函数内部this为pFrame,pContext===&cct
- {
- CreateView(pContext..)//函数内部this为pFrame,pContext===&cct
- {
- CWnd* pView = pContext->m_pNewViewClass->CreateObject();
- //动态创建视图类对象,并返回对象地址
- pView->Create(..,pContext)//函数内部this为pView,pContext===&cct
- {
- CreateEx(..,pContext)//函数内部this为pView,pContext===&cct
- {
- CREATESTRUCT cs;
- ....
- cs.lpCreateParams = pContext;//pContext===&cct
- ::CreateWindowEx(...,pContext);//创建视图窗口
- }
- }
- }
- }
- }
- }
-
- //处理视图窗口的WM_CREATE消息
- CView::OnCreate( pcs )//函数内部this为pView,参数可以获取::CreateWindowEx函数的12个参数
- {
- CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;//获取&cct
- pContext->m_pCurrentDoc->AddView(pView)//函数内部this为pDoc,参数为视图类对象地址
- {
- m_viewList.AddTail(pView);//文档类对象用一个链表成员变量,保存视图类对象地址
- pView->m_pDocument = this;//视图类对象用一个普通成员变量,保存文档类对象地址
- }
- }
3、对象关系
(1)文档类对象用一个链表成员变量,保存视图类对象地址
(2)视图类对象用一个普通成员变量,保存文档类对象地址
一个文档类对象可以对应多个视图类对象(视图窗口)
一个视图类对象(视图窗口)只能对应一个文档类对象
4、视图切分
(1)相关类
CSplitterWnd 不规则框架窗口类,分装了关于不规则框架窗口的操作
(2)窗口切分的使用
重写CFrameWnd类的成员虚函数OnCreateClient
在虚函数中调用CSplitterWnd::CreateStatic创建不规则框架窗口
在虚函数中调用CSplitterWnd::CreateView创建视图窗口
(3)编写程序
- #include
- #include
- #include "resource.h"
-
- class CMyDoc:public CDocument
- {
-
- };
-
- class CMyView:public CView
- {
- DECLARE_DYNCREATE(CMyView)
- DECLARE_MESSAGE_MAP()
- public:
- virtual void OnDraw(CDC* cDC);
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- };
- IMPLEMENT_DYNCREATE(CMyView, CView)
- BEGIN_MESSAGE_MAP(CMyView, CView)
- ON_WM_CREATE()
- END_MESSAGE_MAP()
-
- void CMyView::OnDraw(CDC* cDC)
- {
- cDC->TextOut(100, 100, "视图窗口");
- }
- int CMyView::OnCreate(LPCREATESTRUCT pcs)
- {
- return CView::OnCreate(pcs);
- }
-
- class CMyFrameWnd:public CFrameWnd
- {
- DECLARE_MESSAGE_MAP()
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- afx_msg void OnPaint();
- virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
- private:
- CSplitterWnd m_split; //不规则框架窗口
- };
- BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
- ON_WM_CREATE()
- ON_WM_PAINT()
- END_MESSAGE_MAP()
- int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
- {
- return CFrameWnd::OnCreate(pcs);
- }
- void CMyFrameWnd::OnPaint()
- {
- PAINTSTRUCT ps = {0};
- HDC hdc = ::BeginPaint(m_hWnd, &ps);
- ::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
- ::EndPaint(m_hWnd, &ps);
- }
- BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
- {
- //创建两个视图窗口
- m_split.CreateStatic(this, 1, 2);
- m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
- m_split.CreateView(0, 1, pContext->m_pNewViewClass, CSize(100, 100), pContext);
- m_pViewActive = (CView*)m_split.GetPane(0,0); //设置活动窗口
- return TRUE;
- }
- class CMyWinApp:public CWinApp
- {
- public:
- virtual BOOL InitInstance();
- };
- BOOL CMyWinApp::InitInstance()
- {
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- CCreateContext cct;
- CMyDoc* pDoc = new CMyDoc;
- cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
- cct.m_pCurrentDoc = pDoc;
- pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
- m_pMainWnd = pFrame;
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
- CMyWinApp theApp;
三、命令消息(WM_COMMAND)处理顺序
对象关系图
1、编写程序
- #include
- #include
- #include "resource.h"
-
- class CMyDoc:public CDocument
- {
- DECLARE_MESSAGE_MAP()
- public:
- afx_msg void OnNew();
- };
- BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
- //ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
-
- void CMyDoc::OnNew()
- {
- AfxMessageBox("CMyDoc::OnNew");
- }
-
- class CMyView:public CView
- {
- DECLARE_DYNCREATE(CMyView)
- DECLARE_MESSAGE_MAP()
- public:
- virtual void OnDraw(CDC* cDC);
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- afx_msg void OnNew();
- };
- IMPLEMENT_DYNCREATE(CMyView, CView)
- BEGIN_MESSAGE_MAP(CMyView, CView)
- ON_WM_CREATE()
- //ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
-
- void CMyView::OnDraw(CDC* cDC)
- {
- cDC->TextOut(100, 100, "视图窗口");
- }
- int CMyView::OnCreate(LPCREATESTRUCT pcs)
- {
- return CView::OnCreate(pcs);
- }
- void CMyView::OnNew()
- {
- AfxMessageBox("CMyView::OnNew");
- }
-
- class CMyFrameWnd:public CFrameWnd
- {
- DECLARE_MESSAGE_MAP()
- afx_msg int OnCreate(LPCREATESTRUCT pcs);
- afx_msg void OnPaint();
- virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
- afx_msg void OnNew();
- private:
- CSplitterWnd m_split; //不规则框架窗口
- };
- BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
- ON_WM_CREATE()
- ON_WM_PAINT()
- ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
- int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
- {
- return CFrameWnd::OnCreate(pcs);
- }
- void CMyFrameWnd::OnPaint()
- {
- PAINTSTRUCT ps = {0};
- HDC hdc = ::BeginPaint(m_hWnd, &ps);
- ::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
- ::EndPaint(m_hWnd, &ps);
- }
- BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
- {
- //创建两个视图窗口
- m_split.CreateStatic(this, 1, 2);
- m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
- m_split.CreateView(0, 1, pContext->m_pNewViewClass, CSize(100, 100), pContext);
- m_pViewActive = (CView*)m_split.GetPane(0,0); //设置活动窗口
- return TRUE;
- }
- void CMyFrameWnd::OnNew()
- {
- AfxMessageBox("CMyFrameWnd::OnNew");
- }
- class CMyWinApp:public CWinApp
- {
- DECLARE_MESSAGE_MAP()
- public:
- virtual BOOL InitInstance();
- afx_msg void OnNew();
- };
- BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
- ON_COMMAND(ID_NEW, OnNew)
- END_MESSAGE_MAP()
-
- void CMyWinApp::OnNew()
- {
- AfxMessageBox("CMyWinApp::OnNew");
- }
-
- BOOL CMyWinApp::InitInstance()
- {
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- CCreateContext cct;
- CMyDoc* pDoc = new CMyDoc;
- cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
- cct.m_pCurrentDoc = pDoc;
- pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
- m_pMainWnd = pFrame;
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
- return TRUE;
- }
- CMyWinApp theApp;
2、处理顺序
视图类 -》文档类 -》框架列 -》 应用类
3、消息执行流程
- //WM_COMMAND消息的路线
- OnCommand(wParam, lParam)//函数内部this为pFrame
- {
- CWnd::OnCommand(..)//函数内部this为pFrame
- {
- OnCmdMsg(...)//函数内部this为pFrame *****CFrameWnd::OnCmdMsg 起点
- {
- CView* pView = GetActiveView()//函数内部this为pFrame
- {
- return this->m_pViewActive;//活动视图窗口对象地址
- }对象
- pView->OnCmdMsg(..) ===>终点 CCmdTarget::OnCmdMsg 此函数内部this为pView
- m_pDocument->OnCmdMsg(.)==>终点CCmdTarget::OnCmdMsg 此函数内部this为文档类对象
- CWnd::OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为pFrame
-
- CWinApp* pApp = AfxGetApp();//获取&theApp
- pApp->OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为&theApp
- }
- }
- }