六、MFC文档类(单文档和多文档)

一、单文档视图架构程序

1、单文档视图架构使用

(1)参与架构的类

        CFrameWnd / CWinApp / CView / CDocument

(2)使用到的类

        CDocTemplate(文档模板类)

                CSingleDocTemplate(单文档模板类)

        CDocManager(文档管理类)

(3)参与架构的四个类,除了应用程序类,其余单个类均支持动态创建机制

2、创建项目

(1)创建项目(MFCSdi)

(2)编写程序

#include <afxwin.h>
#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 <afxwin.h>
#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();
}

程序源代码:https://download.csdn.net/download/liutit/86738806

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值