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

来源:互联网 发布:programming python 编辑:程序博客网 时间:2024/05/22 07:51
// 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// CMyMFC4ViewIMPLEMENT_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 _DEBUGvoid 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;  //创建兼容DCdcCompatible.CreateCompatibleDC(pDC);dcCompatible.SelectObject(&bitmap);  //将位图选入兼容DCCRect 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
原创粉丝点击