MFC Static控件派生类,实现对函数图像的绘制。
功能设计:
头文件
/*********************************************************************************
*FileName: GraphControl
*Author: FMX
*Version: 1.0
*Date: 2014-8-22
*Description:
*Others: //其他内容说明
*Function List: void drawBK(); //绘制背景和坐标系void setGraphTitle(CString str); //设置图表文件的标题void addLine(CString str); //添加曲线的图例void addLine(CString* arr, int n); //一次添加多个图例,最大图例数量为8void setRange(int ixl, int ixr, int iyl, int iyt); //设定逻辑坐标的范围void addLineData(std::vector<CPoint> arr); //输入绘制点的逻辑数据void transPos(CPoint *point, bool bIn); //逻辑坐标,物理坐标转换void add(CString legName, std::vector<CPoint> line);//该方法可以添加完一个线条void getBitmap(); //获取可以保存的位图文件
*History: //修改历史记录列表,每条修改记录应包含修改日期、修改者及修改内容简介
1.Date:
Author:
Modification:
2.…………
**********************************************************************************/
#pragma once#include <vector>// CGraphControlclass CGraphControl : public CStatic
{DECLARE_DYNAMIC(CGraphControl)public:CGraphControl();virtual ~CGraphControl();添加的方法/绘图所使用的方法void drawBK(); //绘制背景和坐标系void setGraphTitle(CString str); //void addLine(CString str); //添加曲线的图例void addLine(CString* arr, int n); //一次添加多个图例,最大图例数量为8void setRange(int ixl, int ixr, int iyl, int iyt); //设定逻辑坐标的值void addLineData(std::vector<CPoint> arr); //输入绘制点的逻辑数据void transPos(CPoint *point, bool bIn); //逻辑坐标,物理坐标转换void transPos(std::vector<CPoint> *arr, bool bIn);//批量转换坐标void add(CString legName, std::vector<CPoint> line);//对于添加线条,整理逻辑,一个方法即可完成一次对线条的添加void getBitmap(); //获取可以保存的位图文件
private:CRect m_rect; //控件的大小int marginL, marginR, marginT, marginB, marginInter; //分别对应于图和空间边缘的距离,最后的一个变量指的是图表的主体和图例区域间的距离。int xl, xr, yb, yt; //坐标范围,从X轴到Y轴的所有范围double ratioX; //该比值表示的是X轴上逻辑坐标单位和物理坐标单位的比值,若该值为20则表示20个逻辑坐标对应屏幕上的物理坐标。double ratioY; //该比值表示的是X轴上逻辑坐标单位和物理坐标单位的比值,若该值为20则表示20个逻辑坐标对应屏幕上的物理坐标。CString graphTitle; //图表的标题int legendAreaWidth = 120; //图例区域的宽度CBitmap m_axis; //该位图上包含了主要图表CDC *axisDC; //和轴位图搭配起来的绘图上下文//CBitmap m_graph; //该位图上包含了主要图表,以及最后将整张图片合成后的结果//CDC *graphDC; //对上一张位图绘图的设备上下文CRect graphRc; //记录下图表区域的坐标信息CRect legRc; //图例区域所在的位置CPoint origin; //物理坐标系原点对应的物理坐标信息CPoint logOri; //物理坐标系原点处逻辑坐标CString Title; //图表的标题//图例的字符串已经颜色CString legs[8];COLORREF colors[8];int lineNum = 0; //标记图表中有几条曲线std::vector<CPoint> lineData[8];
protected:DECLARE_MESSAGE_MAP()public:afx_msg void OnPaint();afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnSize(UINT nType, int cx, int cy);// afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);// afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
};
实现文件
// GraphControl.cpp : 实现文件
//#include "stdafx.h"
#include "GraphControl.h"// CGraphControlIMPLEMENT_DYNAMIC(CGraphControl, CStatic)CGraphControl::CGraphControl()
{marginL = marginB = 10;marginB = 20;marginT = 20;marginInter = 10;graphTitle = L"TEST GRAPH";//初始化所有图例文字for (int i = 0; i < 8; i++){legs[i] = L"TEST";}//初始化所有图例色彩colors[0] = RGB(18, 35, 65);colors[1] = RGB(22, 138, 154);colors[2] = RGB(37, 19, 20);colors[3] = RGB(117, 34, 87);colors[4] = RGB(83, 98, 128);colors[5] = RGB(40, 54, 160);colors[6] = RGB(51, 124, 243);colors[7] = RGB(180, 53, 16);//初始化线条数据}CGraphControl::~CGraphControl()
{m_axis.DeleteObject();axisDC->DeleteDC();
}BEGIN_MESSAGE_MAP(CGraphControl, CStatic)ON_WM_PAINT()ON_WM_ERASEBKGND()ON_WM_SIZE()// ON_WM_LBUTTONDBLCLK()ON_WM_LBUTTONDOWN()// ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()// CGraphControl 消息处理程序void CGraphControl::OnPaint()
{CPaintDC dc(this); // device context for painting// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CStatic::OnPaint()//确定屏幕比例ratioX = (double)(xr - xl) / graphRc.Width();ratioY = (double)(yt - yb) / graphRc.Height();//开始绘图GetClientRect(m_rect);drawBK();dc.BitBlt(0, 0, m_rect.Width(), m_rect.Height(), axisDC, 0, 0, SRCCOPY);m_axis.DeleteObject();axisDC->DeleteDC();
}BOOL CGraphControl::OnEraseBkgnd(CDC* pDC)
{//可以设置不自动擦除背景return CStatic::OnEraseBkgnd(pDC);
}void CGraphControl::OnSize(UINT nType, int cx, int cy)
{//修改这里使得空间可以自适应大小变化return CWnd::OnSize(nType, cx, cy);}void CGraphControl::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值CStatic::OnLButtonDown(nFlags, point);if (point.x > graphRc.left&&point.x < graphRc.right&&point.y<graphRc.bottom&&point.y > graphRc.top){CString str;str.Format(L"%d,%d", point.x, point.y);MessageBox(str);}
}void CGraphControl::drawBK()
{axisDC = new CDC();axisDC->CreateCompatibleDC(NULL);m_axis.CreateCompatibleBitmap(axisDC, m_rect.Width(), m_rect.Height());axisDC->SelectObject(&m_axis);axisDC->FillSolidRect(m_rect, RGB(255, 255, 255));//axisDC->Rectangle(marginL, marginR, m_rect.right - marginR, m_rect.bottom - marginB);axisDC->TextOutW(m_rect.CenterPoint().x - 45, 1, graphTitle);//确定下图表的区域以及图例的区域legRc.left = m_rect.right - marginR - 120;legRc.top = marginT;legRc.right = m_rect.right - marginR;legRc.bottom = m_rect.bottom - marginB;axisDC->Rectangle(legRc);//日期文字输出//图例文字输出int legsVerticalDif = 25;//int fontHeight = 15;int legsTop = legRc.top + legsVerticalDif;int legsLeft = legRc.CenterPoint().x - 20;axisDC->TextOutW(legRc.CenterPoint().x - 15, legRc.top + 1, L"图例");for (int i = 0; i < 8; i++){//axisDC->SetTextColor(colors[i]); //为文字设置色彩,没有成功,还在思考中。axisDC->SetTextColor(colors[i]);axisDC->TextOutW(legsLeft, legsTop, legs[i]);//axisDC->drawtelegsTop += 35;if (legsTop + 9 >= legRc.bottom){break;}}axisDC->SetTextColor(RGB(0, 0, 0)); //恢复字体色彩为黑色//确定主要图表区域的方块graphRc.left = m_rect.left + marginL;graphRc.top = m_rect.top + marginT;graphRc.right = m_rect.right - marginR - 120 - marginInter;graphRc.bottom = m_rect.bottom - marginB;axisDC->Rectangle(graphRc);//坐标轴int dif = 30;//X 方向CPen pen;pen.CreatePen(PS_DOT, 1, RGB(0, 0, 255));axisDC->SelectObject(pen);int m = graphRc.bottom;int linesCount = 0;for (int i = 1; m > graphRc.top + dif; i++){axisDC->MoveTo(graphRc.left, graphRc.bottom - i * dif);axisDC->LineTo(graphRc.right, graphRc.bottom - i * dif);m = graphRc.bottom - i * dif;linesCount++;}//Y 方向int n = graphRc.left;for (int i = 1; n < graphRc.right - dif; i++){axisDC->MoveTo(graphRc.left + i*dif, graphRc.bottom);axisDC->LineTo(graphRc.left + i*dif, graphRc.top);n = graphRc.left + i*dif;}//初始化坐标原点origin.x = graphRc.left;origin.y = graphRc.bottom;//初始化逻辑坐标远点logOri = xl, yb;//开始绘制点的数据for (int i = 0; i < 8; i++){if (lineData[i].size() == 0){break;}for (int j = 0; j < lineData[i].size(); j++){axisDC->SetPixel(lineData[i][j], colors[i]); //画的是散点图}}}void CGraphControl::setGraphTitle(CString str)
{graphTitle = L"TEST GRAPH";
}void CGraphControl::addLine(CString str)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}legs[lineNum++] = str;}void CGraphControl::addLine(CString* arr, int n)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}for (int i = 0; i < n; i++){if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}legs[lineNum++] = arr[i];}
}void CGraphControl::setRange(int ixl, int ixr, int iyl, int iyt)
{xl = ixl;xr = ixr;yb = iyl;yt = iyt;Invalidate();
}void CGraphControl::addLineData(std::vector<CPoint> arr)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}}
void CGraphControl::getBitmap() //获取可以保存的位图文件
{CFileDialog* fileDlg = new CFileDialog(false);CString str;if (fileDlg->DoModal() == IDH_OK){str = fileDlg->GetFileName();}CImage image;image.Attach(m_axis.operator HBITMAP());image.Save(str);delete fileDlg;
}void CGraphControl::add(CString legName, std::vector<CPoint> line)
{addLine(legName);addLineData(line);transPos(&line, true);
}void CGraphControl::transPos(CPoint *point, bool bIn) //逻辑坐标,物理坐标转换
{CPoint tmpPoint;memcpy_s(&tmpPoint, sizeof(CPoint), point, sizeof(CPoint));if (bIn) //逻辑坐标->物理坐标{point->x = (tmpPoint.x - logOri.x) / ratioX + origin.x;point->y = (tmpPoint.y - logOri.y) / ratioY + origin.y;}else //物理坐标->逻辑坐标{point->x = (tmpPoint.x - logOri.x) * ratioX + logOri.x;point->y = (logOri.y - tmpPoint.y) * ratioY + logOri.y;}}void CGraphControl::transPos(std::vector<CPoint> *arr, bool bIn)//批量转换坐标
{for (int i = 0; i < arr->size(); i++){transPos(&arr[i], bIn);}}
MFC Static控件派生类,实现对函数图像的绘制。相关推荐
- 使用CvvImage类在MFC的static控件显示图片
使用OpenCV的库,可以非常便捷地实现对图像的各种操作.在CTestDlg对话框中放置一个picture static控件,ID为IDC_STATIC,如下函数即可实现显示图片的功能.根据此方法,可 ...
- MFC的Button和Static控件
最近要写一个MFC的对话框程序,发现要把MFC的对话框写的有色彩点并不容易,不像在C#里设置属性指就好,而是要自己去写一些代码完成对话框的绘画操作.比如一个简单的鼠标移入.移出操作,都要自己去写代码. ...
- MFC常见控件:滚动条控件
MFC常见控件:滚动条控件 1. 滚动条控件简介 滚动条大家也很熟悉了,Windows窗口中很多都有滚动条.列表框和组合框设置了相应属性后,如果列表项显示不下也会出现滚动条.滚动条分为水平滚动条(Ho ...
- MFC ListBox控件设置字体颜色
文章目录 描述 需要解决的问题 方案 设置 Item 颜色 鼠标双击事件 调用 Static 控件的背景颜色设置 描述 最近的项目中需要用到 MFC 的列表控件,列表控件中需要动态插入产品不同的测试状 ...
- MFC工具箱控件的一些用法
转自https://blog.csdn.net/qq_34174814/article/details/51419967 控件工具箱: 2 图形控件(picture):常用于显示位图(Bitmap)和 ...
- MFC对话框控件成员变量编程熟悉 - 开发一个简单天线长度计算器
新建一个对话框工程:VC6:VC2010类似:版本不同略有些差别: 新建完如下:对话框默认有三个控件,自己添加的: 右击 确定 按钮,建立类向导:进入类向导: Class name下拉选中对话框类:类 ...
- MFC列表控件ListControl和树控件TreeControl
列表控件 列表相关的类:CListCtrl-父类是CWnd,本质是一个控件: CListView-父类是CView,本质是一个视图.相当于在视图中嵌入了一个CListCtrl控件 列表控件的使用 1. ...
- MFC high-speed-charting控件使用(添加垂直游标,两个控件的联动)
MFC high-speed-charting控件使用(添加垂直游标,两个控件的联动) 应用场景 最近参与的一个项目中涉及到在一个对话框中添加两个high-speed-charting控件,在两个控件 ...
- mfc随记:基于vs2010创建MFC ActiveX控件并测试
一.新建一个空项目 以管理员打开vs2010,选择新建一个mfc activeX控件,填写项目名称和路径,其他无需修改,直接默认一直下一步即可 二. 添加测试方法 在底部tab栏切换到类视图,右键添加 ...
最新文章
- 前端必备,JavaScript面试问题及答案
- 谷歌浏览器mac_Mac用户浏览网页不可少的浏览器-谷歌Chrome
- java面试常见问题
- sh: lmstat: 没有那个文件或目录_没有天生的合适,只有磨合出来的感情
- 数字统计2(依然是数组下标法)
- 蚂蚁金服王旭:开源的意义是把社区往前推进一步
- 本地项目怎么推送到码云_【重谈npm】当下载一个项目到本地执行npm install报错时应该怎么办...
- C/C++排序算法(2)希尔排序
- ASP.NET- 执行SQL超时的解决方案
- C#实现文件二进制存储
- 9-21 调试javaweb 数据库连接感想
- 小米路由器的linux命令,小米路由器pro安装mt工具箱
- macOS镜像下载(ISO、DMG)
- 云原生日志管理瑞士军刀 Fluent Operator 中文入门教程
- DSP 6678 多核CACHE一致性操作
- 阵列卡在服务器什么位置,阵列卡是什么
- 公司银行考试有C语言程序吗,银行春季校园招聘计算机岗笔试考什么?会考编程吗?...
- 关于学习Android的三个终极问题
- 高分辨透射电镜(HRTEM)样品怎么制?看这一篇就够了
- 人工智能写歌词?看我是如何用Python来C位出道的……