当前位置:网站首页>五、MFC视图窗口和文档
五、MFC视图窗口和文档
2022-07-27 00:18:00 【[T]】
一、视图窗口
提供一个用于显示数据的窗口
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 <afxwin.h>
#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 <afxwin.h>
#include <afxext.h>
#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 <afxwin.h>
#include <afxext.h>
#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);
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;
边栏推荐
- ansible系列之:不收集主机信息 gather_facts: False
- 解决小程序报错getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json
- Getlocation:fail the API need to be declared in the requiredprivateinfo field in app.json
- 贪心——376. 摆动序列
- 银河证券基金低佣金开户靠谱吗,可靠安全吗
- 数据库读写分离和分库分表
- Tabbar of customized wechat applet on uni app
- Dynamically set the height of applet swiper
- 从ACL 2022 Onsite经历看NLP热点
- I heard that you knelt on the interface test during the interview?
猜你喜欢

Time module: acquisition and mutual transformation of timestamp, structured time and formatted time

云开发寝适闹钟微信小程序源码

Inftnews | ggac and China Aerospace ases exclusively produce "China 2065 Collection Edition"

解决小程序报错getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json

Rust Web(一)—— 自建TCP Server

If you want to thoroughly optimize the performance, you must first understand the underlying logic~

C language program compilation (preprocessing)

Okaleido Tiger 7.27日登录Binance NFT,首轮已获不俗成绩
![[Li Kou] 1859. Sort sentences](/img/0c/f7f698ad0052d07be98e5f888d7da9.png)
[Li Kou] 1859. Sort sentences

Blog competition dare to try BAC for beginners
随机推荐
从ACL 2022 Onsite经历看NLP热点
[Li Kou] 1859. Sort sentences
Dynamically set the height of applet swiper
Non global function of lua function
八皇后编程实现
Invalid target distribution: solution for 17
Cs224w fall course - --- 1.1 why graphs?
I heard that you knelt on the interface test during the interview?
[nisactf 2022] upper
小程序怎样助力智能家居生态新模式
How small programs help the new model of smart home ecology
Debezium series: the binlog file cannot be recovered after the record is hung from the library server, and the task is switched to the main library to ensure that the data is not lost
确定了,2022下半年软考报名8月开始
面试突击68:为什么 TCP 需要 3 次握手?
Rust web (I) -- self built TCP server
杀毒软件 clamav 的安装和使用
解决小程序报错getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json
数据库读写分离和分库分表
F8 catch traffic, F9 catch rabbits, f10turttle
Arduino UNO +74HC164流水灯示例