// 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中添加相应代码
}
MyMFC(10-11)绘图控制和保存 CMyMFC4View
最新推荐文章于 2020-10-27 22:45:31 发布