一、单文档视图架构程序
1、单文档视图架构使用
(1)参与架构的类
CFrameWnd / CWinApp / CView / CDocument
(2)使用到的类
CDocTemplate(文档模板类)
CSingleDocTemplate(单文档模板类)
CDocManager(文档管理类)
(3)参与架构的四个类,除了应用程序类,其余单个类均支持动态创建机制
2、创建项目
(1)创建项目(MFCSdi)
(2)编写程序
- #include
- #include "resource.h"
-
- class CMyDoc:public CDocument
- {
- DECLARE_DYNCREATE(CMyDoc)
- };
- IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
-
-
- class CMyView:public CView
- {
- DECLARE_DYNCREATE(CMyView)
- public:
- virtual void OnDraw(CDC* pDC);
- };
- IMPLEMENT_DYNCREATE(CMyView, CView)
-
- void CMyView::OnDraw(CDC* pDC)
- {
- pDC->TextOut(100, 100, "视图窗口");
- }
-
- class CMyFrameWnd:public CFrameWnd
- {
- DECLARE_DYNCREATE(CMyFrameWnd)
- };
- IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd)
-
-
-
-
- class CMyWinApp:public CWinApp
- {
- virtual BOOL InitInstance();
- };
-
- BOOL CMyWinApp::InitInstance()
- {
- CSingleDocTemplate* pTemplate = new CSingleDocTemplate(IDR_MENU1,
- RUNTIME_CLASS(CMyDoc),
- RUNTIME_CLASS(CMyFrameWnd),
- RUNTIME_CLASS(CMyView));
- AddDocTemplate(pTemplate);
- OnFileNew();
- m_pMainWnd->ShowWindow(SW_SHOW);
- m_pMainWnd->UpdateWindow();
- return TRUE;
- }
-
- CMyWinApp theApp;
-
(3)创建资源(.rc文件)与菜单
(4)创建字符串资源,创建(AFX_IDS_UNTITLED),否则程序无法运行
3、执行过程
- //单文档模板类构造
- CSignleDocTemplate* pTmplate
- m_pOnlyDoc //唯一的文档类对象地址
- m_pDocClass // RUNTIME_CLASS(CMyDoc)
- m_pFrameClass // RUNTIME_CLASS(CMyFrameWnd)
- m_pViewClass // RUNTIME_CLASS(CMyView)
-
- //AddDocTemplate(pTmplate)
- theApp
- m_pDocManager=new CDocManager //文档管理类
- m_templateList.AddTail(pTmplate) //模板列表,保存单文档模板类
-
- //OnFileNew()
- OnFileNew()
- {
- m_pDocManager->OnFileNew() //文档管理类
- {
- CDocTemplate* pTemplate = m_templateList.GetHead();//取出单文档模板类对象地址
- pTemplate->OpenDocumentFile()//函数内部this为单文档模板类对象地址
- {
- OpenDocumentFile(..)//函数内部this为单文档模板类对象地址
- {
- pDocument = CreateNewDocument()//函数内部this为单文档模板类对象地址
- {
- CDocument* pDocument = m_pDocClass->CreateObject();
- //动态创建文档类对象,并返回对象地址
- AddDocument(pDocument)//函数内部this为单文档模板类对象地址
- {
- m_pOnlyDoc = pDocument;
- }
- }
- pFrame = CreateNewFrame(pDocument..)//函数内部this为单文档模板类对象地址
- {
- CCreateContext context;
- ...
- context.m_pCurrentDoc = pDocument;//文档类对象地址
- context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
- CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
- //动态创建框架类对象,并返回对象地址
- pFrame->LoadFrame(...., &context);//创建框架窗口
- }
- }
- }
- }
- }
4、生成向导生成的单文档框架(参考第一篇文章)
5、类向导(通过向导实现MFC部分功能)
(1)选中项目右键,打开类向导
(2)选择项目和类名称
(3)添加一个处理鼠标消息的函数,双击消息、双击函数,即可创建处理函数
二、多文档视图架构
可以同时管理多个文档,可以有多个文档类对象
1、多文档视图架构使用
(1)参与架构的类
CMDIFrameWnd / CMDIChileWnd / CWinApp / CView / CDocument
(2)需要用到的类
CDocTemplate(文档模板类)
CMultiDocTemplate(多文档模板类)
CDocManager(文档管理类)
2、创建项目
(1)创建项目(MFCMdi)
(2)编写程序
- #include
- #include "resource.h"
-
- class CMyDoc:public CDocument
- {
- DECLARE_DYNCREATE(CMyDoc)
- };
- IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
-
- class CMyView:public CView
- {
- DECLARE_DYNCREATE(CMyView)
- public:
- virtual void OnDraw(CDC* pDC);
- };
- IMPLEMENT_DYNCREATE(CMyView, CView)
- void CMyView::OnDraw(CDC* pDC)
- {
- pDC->TextOutA(100, 100, "视图窗口");
- }
-
- class CMyChild:public CMDIChildWnd
- {
- DECLARE_DYNCREATE(CMyChild)
- };
- IMPLEMENT_DYNCREATE(CMyChild, CMDIChildWnd)
-
-
- class CMyFrameWnd:public CMDIFrameWnd
- { //不支持动态创建
-
- };
-
- class CMyWinApp:public CWinApp
- {
- virtual BOOL InitInstance();
- };
- BOOL CMyWinApp::InitInstance()
- {
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- pFrame->LoadFrame(IDR_MENU1);
- m_pMainWnd = pFrame;
- pFrame->ShowWindow(SW_SHOW);
- pFrame->UpdateWindow();
-
- CMultiDocTemplate* pTemplate = new CMultiDocTemplate(IDR_MENU2,
- RUNTIME_CLASS(CMyDoc),
- RUNTIME_CLASS(CMyChild),
- RUNTIME_CLASS(CMyView));
- AddDocTemplate(pTemplate);
- OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
- OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
- OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
-
- return TRUE;
- }
-
- CMyWinApp theApp;
(3)添加菜单项(IDR_MENU1, IDR_MENU2)
(4)添加字符串资源(AFX_IDS_UNTITLED)
3、创建流程
- CMultiDocTemplate* pTemplate //多文档模板类
- m_docList //保存多个文档对象地址
- m_DocClass // RUNTIME_CLASS(CMyDoc)
- m_pFrameClass // RUNTIME_CLASS(CMyChild)
- m_pViewClass // RUNTIME_CLASS(CMyView)
-
- theApp
- m_pDocManager=new CDocManager //文档管理类对象
- m_templateList.AddTail(pTemplate)
-
- CMyFrameWnd* pFrame = new CMyFrameWnd;
- pFrame->LoadFrame( IDR_MENU1 )//函数内部this为pFrame
- {
- CFrameWnd::LoadFrame(..)//函数内部this为pFrame
- {
- Create(..)//函数内部this为pFrame
- {
- CreateEx(..)//函数内部this为pFrame
- {
- //就会主框架窗口。
- }
- }
- }
- }
-
- OnFileNew( )//函数内部this为&theApp
- {
- m_pDocManager->OnFileNew()//函数内部this为文档管理类对象地址
- {
- CDocTemplate* pTemplate = m_templateList.GetHead();//取出多文档模板类对象地址
- pTemplate->OpenDocumentFile()//函数内部this为多文档模板类对象地址
- {
- OpenDocumentFile(..)//函数内部this为多文档模板类对象地址
- {
- pDocument = CreateNewDocument()//函数内部this为多文档模板类对象地址
- {
- CDocument* pDocument = m_pDocClass->CreateObject();
- //动态创建文档类对象,并返回对象地址
- AddDocument(pDocument)//函数内部this为多文档模板类对象地址
- {
- m_docList.AddTail(pDoument);//将文档类对象扔到多文档模板类的链表成员中
- }
- }
- pFrame = CreateNewFrame(pDocument..)//函数内部this为多文档模板类对象地址
- {
- CCreateContext context;
- ...
- context.m_pCurrentDoc = pDocument;//文档类对象地址
- context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
- CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
- //动态创建框子架类对象,并返回对象地址
- pFrame->LoadFrame(...., &context);//创建子框架窗口
- }
- }
- }
- }
- }
三、MFC绘图
1、绘图实现
(1)WIN32
绘图设备句柄(HDC)
(2)MFC
类对象(绑定了绘图设备句柄 HDC)
CDC类,绘图设备类,m_hDC,m_hAttribDC
CPaintDC类,CDC的子类,封装了WM_PAINT消息中绘图的绘图设备
CClientDC类,CDC的子类,封装了客户区绘图的绘图设备
2、创建项目
(1)创建项目(MFCDraw),MFC单文档架构程序
(2)使用类向导,在视图类添加绘图消息处理函数
3、通过CPaintDC在绘图处理函数绘图
(1)在OnPaint处理函数绘图
- void CMFCDrawView::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- dc.Rectangle(100, 100, 200, 200); //绘制一个矩形
- }
(2)CPaintDC构造过程
- CPaintDC dc(CWnd* pView)
- {
- Attach(::BeginPaint(pView->m_hWnd, &m_ps))//函数内部this为&dc
- {
- m_hDC = hDC;//将BeginPaint获取的绘图设备句柄 保存到dc对象的一个成员变量中
- SetAttribDC(m_hDC)//函数内部this为&dc
- {
- m_hAttribDC = m_hDC;//dc对象的另一个成员变量也保存了绘图设备句柄
- }
- }
- }
3、使用CClientDC绘图
(1)添加菜单项
(2)使用类向导创建命令处理函数
(3)在命令处理函数绘图,点击绘图命令就会绘制圆形(窗口大小改变会消失,改变窗口时会重绘)
- void CMFCDrawView::OnClient()
- {
- CClientDC dc(this);
- dc.Ellipse(200, 200, 300, 300); //画圆
- }
- CPaintDC dc(pView) === CPaintDC::CPaintDC(...)//函数内部this为&dc
- {
- Attach(::BeginPaint(pView->m_hWnd, &m_ps))//函数内部this为&dc
- {
- m_hDC = hDC;//将BeginPaint获取的绘图设备句柄 保存到dc对象的一个成员变量中
- SetAttribDC(m_hDC)//函数内部this为&dc
- {
- m_hAttribDC = m_hDC;//dc对象的另一个成员变量也保存了绘图设备句柄
- }
- }
- }
4、绘图相关类
CGdiObject类(绘图对象类),m_hObject
CPen类(父类为CGdiObject),封装了画笔的操作
CBrush类(父类为CGdiObject),封装了画刷的操作
CFont类(父类为CGdiObject),封装了字体的操作
CBitmap类(父类为CGdiObject),封装了为图的操作
(1)添加菜单项
(2)使用类向导创建目录处理函数
- void CMFCDrawView::OnPen()
- {
- // TODO: 在此添加命令处理程序代码
- CClientDC dc(this);
- CPen pen(PS_SOLID, 2, RGB(255,0,0));
- CPen* oldPen = dc.SelectObject(&pen);
- dc.Rectangle(100, 100, 200, 200);
- dc.SelectObject(oldPen);
- pen.DeleteObject();
- }
- CPen pen(PS_SOLID, 2, RGB(255,0,0)) === CPen::CPen(PS_SOLID, 2, RGB(255,0,0))
- //函数内部this &pen
- {
- Attach(::CreatePen(PS_SOLID, 2, RGB(255,0,0)))//函数内部this &pen
- {
- m_hObject = hObject;//将::CreatePen获取的画笔句柄,保存到pen对象的一个成员变量中
- }
- }
- void CMFCDrawView::OnBrush()
- {
- // TODO: 在此添加命令处理程序代码
- CClientDC dc(this);
- CBrush brush(RGB(0,255,0));
- CBrush* oldBrush = dc.SelectObject(&brush);
- dc.Ellipse(100, 100, 200, 200);
- dc.SelectObject(oldBrush);
- brush.DeleteObject();
- }
void CMFCDrawView::OnFont()
{
// TODO: 在此添加命令处理程序代码
CClientDC dc(this);
CFont font;
font.CreatePointFont(300,"黑体");
CFont* oldBrush = dc.SelectObject(&font);
dc.TextOut(100, 100, "你好");
dc.SelectObject(oldBrush);
font.DeleteObject();
}
位图绘制:
创建位图资源
- void CMFCDrawView::OnBmp()
- {
- //添加位图资源
- //创建一个当前DC相匹配的内存DC
- CClientDC dc(this);
- CDC memdc;
- memdc.CreateCompatibleDC(&dc);
- //将位图的数据送给内存DC
- CBitmap bmp;
- bmp.LoadBitmap(IDB_BITMAP1);
- CBitmap* oldBmp = memdc.SelectObject(&bmp);
- //成像
- dc.BitBlt(100, 100, 48, 48, &memdc, 0, 0, SRCCOPY);
- //将位图数据要回来
- memdc.SelectObject(oldBmp);
- //销毁位图
- bmp.DeleteObject();
- //销毁内存DC
- memdc.DeleteDC();
- }