MyMFC(10-11)绘图控制和保存 CMyMFC4View

// MyMFC4View.cpp : CMyMFC4View 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MyMFC4.h"
#endif

#include "MyMFC4Doc.h"
#include "MyMFC4View.h"
#include "SettingDlg.h"
#include "resource.h"
#include "Graph.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMyMFC4View

IMPLEMENT_DYNCREATE(CMyMFC4View, CScrollView)

BEGIN_MESSAGE_MAP(CMyMFC4View, CScrollView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview)
	ON_COMMAND(IDM_DOT, &CMyMFC4View::OnDot)
	ON_COMMAND(IDM_LINE, &CMyMFC4View::OnLine)
	ON_COMMAND(IDM_RECTANGLE, &CMyMFC4View::OnRectangle)
	ON_COMMAND(IDM_ELLIPSE, &CMyMFC4View::OnEllipse)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_COMMAND(IDM_SETTING, &CMyMFC4View::OnSetting)
	ON_COMMAND(ID_COLOR, &CMyMFC4View::OnColor)
	ON_COMMAND(IDM_FONT, &CMyMFC4View::OnFont)
	ON_WM_ERASEBKGND()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
END_MESSAGE_MAP()

// CMyMFC4View 构造/析构

CMyMFC4View::CMyMFC4View()
: m_nDrawType(0)
, m_ptOrigin(0)
, m_strFontName(_T(""))
{
	// TODO:  在此处添加构造代码

	m_nLineWidth = 0;
	m_nLineStyle = 0;
	m_clr = RGB(255, 0, 0);
}

CMyMFC4View::~CMyMFC4View()
{
}

BOOL CMyMFC4View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO:  在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CScrollView::PreCreateWindow(cs);
}

// CMyMFC4View 绘制

void CMyMFC4View::OnDraw(CDC* pDC)
{
	CMyMFC4Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO:  在此处为本机数据添加绘制代码
/******************************************************************************************************************/
	//在屏幕上显示你所选择的字体
	CFont *pOldFont = pDC->SelectObject(&m_font);
	pDC->TextOut(0, 0, m_strFontName);
	pDC->SelectObject(pOldFont);



/************************************************************************************************************/
	//当窗口重绘时,再次绘制之前所绘制的图形,从而实现所绘图形不消失
	CPen pen(m_nLineStyle, m_nLineWidth, m_clr);  //由于CGraph类中没有保存线宽和颜色的信息。所以重绘之后,线型和颜色为最后一次选择的
	pDC->SelectObject(&pen);
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
	pDC->SelectObject(pBrush);

	for (int i = 0; i<m_ptrArray.GetSize(); i++)
	{
		switch (((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)
		{
		case 1:
			pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd, m_clr);
			break;
		case 2:
			pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);
			pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);
			break;
		case 3:
			pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
				((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
			break;
		case 4:
			pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
				((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
			break;
		}	
	}








	

}


// CMyMFC4View 打印

BOOL CMyMFC4View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMyMFC4View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加额外的打印前进行的初始化过程
}

void CMyMFC4View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加打印后进行的清理过程
}


// CMyMFC4View 诊断

#ifdef _DEBUG
void CMyMFC4View::AssertValid() const
{
	CScrollView::AssertValid();
}

void CMyMFC4View::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CMyMFC4Doc* CMyMFC4View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyMFC4Doc)));
	return (CMyMFC4Doc*)m_pDocument;
}
#endif //_DEBUG


// CMyMFC4View 消息处理程序


void CMyMFC4View::OnDot()
{
	// TODO:  在此添加命令处理程序代码
	m_nDrawType = 1;
}


void CMyMFC4View::OnLine()
{
	// TODO:  在此添加命令处理程序代码
	m_nDrawType = 2;
}


void CMyMFC4View::OnRectangle()
{
	// TODO:  在此添加命令处理程序代码
	m_nDrawType = 3;
}


void CMyMFC4View::OnEllipse()
{
	// TODO:  在此添加命令处理程序代码
	m_nDrawType = 4;
}


void CMyMFC4View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	m_ptOrigin = point;



	CScrollView::OnLButtonDown(nFlags, point);
}


void CMyMFC4View::OnLButtonUp(UINT nFlags, CPoint point)  //注意是在左击UP时,进行绘制,而不是左击down
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

/*****************************************************************************************************************************************/
	//绘制点、直线、矩形、椭圆
	CClientDC dc(this);
	CPen pen(m_nLineStyle, m_nLineWidth, m_clr);  //设置线型、线宽、颜色的变量。这里的线型由于实线(PS_SOLID)为1,虚线(PS_DASH)为2,点线(PS_DOT)为3。
												  //它们一一对应,所以这里不再用switch,case语句来选择
	dc.SelectObject(&pen);  //载入画笔
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));  //设置透明笔刷
	dc.SelectObject(pBrush);  //载入笔刷
	switch (m_nDrawType)  //判断是选择了画点、直线、矩形、椭圆的类别
	{
	case 1:
		dc.SetPixel(point, m_clr);  //设置一个点。第一个参数指定点的位置,(可见是绘制鼠标左击UP时位置的点,而不是down时)第二个参数指定颜色
		break;
	case 2:
		dc.MoveTo(m_ptOrigin);  //移动到鼠标左击down时的位置
		dc.LineTo(point);  //画直线
		break;
	case 3:
		dc.Rectangle(CRect(m_ptOrigin, point));  //根据起始点和终止点,即左上角和右下角的点,绘制矩形
		break;
	case 4:
		dc.Ellipse(CRect(m_ptOrigin, point));  //绘制椭圆
		break;
	}



/********************************************************/
	//实现所绘制的图形,当窗口重绘时,不会消失
	//用于保存所绘制的信息,线类型、起点、终点。用这些数据在OnDraw函数中进行重绘,从而实现重绘时不消失
	CGraph *graph=new CGraph(m_nDrawType, m_ptOrigin, point); 
	m_ptrArray.Add(graph);  //把这些对象放到m_ptrArray数组中。因为CPtrArray可以存储多个对象的地址
	//见OnDraw函数



/*****************************************************************************************************************/
	//当添加了滚动窗口后,纠正图形错位的问题
	//让视口的原点随着滚动条的位置不同而变化
	OnPrepareDC(&dc);
	dc.DPtoLP(&m_ptOrigin);
	dc.DPtoLP(&point);








	CScrollView::OnLButtonUp(nFlags, point);
}

/*****************************************************/
void CMyMFC4View::OnSetting()  //设置线宽和线型
{
	// TODO:  在此添加命令处理程序代码
	
		SettingDlg dlg;  //声明所建对话框类的变量
		dlg.m_nLineWidth = m_nLineWidth;  //这两句的作用是:在选择的线宽和线型进行绘画后,要再次进行选择。这时打开对话框会保存上一次的选择
		dlg.m_nLineStyle = m_nLineStyle;
		dlg.m_clr = m_clr;  //###########这个的作用是为,示例对话框保存的颜色。不是为绘制线时保存的颜色。#############要在DoModal函数之前		
		if (IDOK == dlg.DoModal())  //含义:首先用DoModal绘制模态对话框,然后判断是否点击了“确定”按钮
		{
			m_nLineWidth = dlg.m_nLineWidth;  //这才是把在对话框中做的选择进行赋值保存
			m_nLineStyle = dlg.m_nLineStyle;  //(注意)在对话框的线型中,一定要把他们设为一个Group,即把第一个线型属性中的Group设为TRUE
		}
	}

/*******************************************************************************/
void CMyMFC4View::OnColor()  //颜色对话框资源,由MFC提供的一个类CColorDialog
{
	// TODO:  在此添加命令处理程序代码
	CColorDialog dlg;
	dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;  //CC_RGBINIT用于初始选择对话框的颜色,只有设置了,下面的那条语句才能生效,才能够保存上一次的颜色选择
											     //CC_FULLOPEN的作用是:让对话框完全展开
	dlg.m_cc.rgbResult = m_clr;  //保存上一次的颜色选择
	if (IDOK == dlg.DoModal())
	{
		m_clr = dlg.m_cc.rgbResult;  //m_cc.rgbResult变量保存用户选择的颜色
	}
}

/****************************************************************************/
void CMyMFC4View::OnFont()  //设置字体,字体对话框MFC中提供的一个类CFontDialog
{
	// TODO:  在此添加命令处理程序代码
	CFontDialog dlg;
	if (IDOK == dlg.DoModal())
	{
		if (m_font.m_hObject)  //如果m_font对象已经与一个字体资源相关联了,那么首先就要切断这种关联,释放该字体资源,然后才能与新资源相关联
			m_font.DeleteObject();  //释放先前的资源
		m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);  //m_cf.lpLogFont是指向逻辑字体的指针。CreateFontIndirect函数根据指定特征的逻辑字体来初始化这个字体对象
		m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;  //lfFaceName中存放字体的名称
		Invalidate();
	}
}

/*******************************************************************************************************************************/
	//位图的显示(添加背景位图)
	//首先要擦除窗口背景,然后在对窗口重新进行绘制。当擦除窗口背景时,程序会发送一个WM_ERASEBKGND消息
BOOL CMyMFC4View::OnEraseBkgnd(CDC* pDC)  //由为该类添加WM_ERASEBKGND消息响应得到
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	CBitmap bitmap;
	bitmap.LoadBitmap(IDB_BITMAP1);  //先要加载一副bitmap的图像。超过256色的位图就不能被加载

	BITMAP bmp;
	bitmap.GetBitmap(&bmp); //用于得到加载位图的信息,高和宽

	CDC dcCompatible;  //创建兼容DC
	dcCompatible.CreateCompatibleDC(pDC);

	dcCompatible.SelectObject(&bitmap);  //将位图选入兼容DC

	CRect rect;
	GetClientRect(&rect);  //得到客户区的大小

	//将兼容DC中的位图贴到当前DC中
	//pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);  //不好,按1:1进行复制,所以图像不能完整显示
	pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); //实现位图的拉伸和压缩,以合适目的矩形区域的尺寸
	//StretchBlt参数
	//1,2.指定目标矩形区域左上角x,y坐标
	//3,4.指定源和目标矩形区域的逻辑宽度和高度
	//5.指向源设备上下文对象
	//6,7.指定源矩形区域左上角的x,y坐标
	//8,9.指定源矩形区域的宽度和高度
	//10.指定复制的模式
	return TRUE; //必须有,不然位图只显示一下,就会消失

	return CScrollView::OnEraseBkgnd(pDC);
	} 



/******************************************************************************************************************************************************/
	//注意::OnDraw函数之所在窗口重绘时调用,是因为,在窗口重绘时会发送WM_PAINT消息,调用响应函数OnPaint。在基类中的
	//OnPaint函数中调用了OnDraw函数。##############所以,若是在程序中定义了WM_PAINT消息,那么就不会响应基类中的OnPaint函数了
	//从而,也不会再调用OnDraw函数了。###################若想调用OnDraw函数应该在OnPaint函数中加上下面的语句
void CMyMFC4View::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO:  在此处添加消息处理程序代码
	// 不为绘图消息调用 CScrollView::OnPaint()

	OnPrepareDC(&dc);
	OnDraw(&dc);    //这两句程序,实现调用OnDraw函数
}



/**********************************************************************************************************************************/
	//窗口滚动功能的实现
	//在建立工程时,把View类的基类选择为CScrollView。也可以在建完之后把视类.h和.cpp中的CView全部替换为CScrollView,即可带有滚动条
	//然后再在OnInitialUpdate()虚函数中对滚动窗口进行初始设置。
	//因为SetScrollSizes函数是在视类窗口创建之后再调用的,所以在虚函数OnInitialUpdate中调用,因为该函数是在窗口完全创建完成之后第一个调用的函数,在第一次调用OnDraw函数之前
void CMyMFC4View::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	// TODO:  在此添加专用代码和/或调用基类

	SetScrollSizes(MM_TEXT,CSize(800, 600));  //设置滚动窗口的大小
	//1.指定映射模式
	//2.设置滚动视图窗口总的尺寸
	//3.设置鼠标单击滚动"条"的轴时水平和垂直方向滚动的量 
	//4.设置鼠标单击滚动"箭头"的轴时水平和垂直方向滚动的量
	//3,4可以省略

	//但,这样存在问题,图形错位现象。当把滚动条移动到下面时,视口原点的坐标会发生变换,如(0,-150),从而重绘时图形会垂直向上移动
	//还需要在OnLButtonUp中添加相应代码
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值