最近接手了一个项目,其中涉及到MFC和实时曲线显示的问题,由于我之前从未接触过此类技术,现学现搞,把其间用到的觉得对初学者有用的东西,总结一下。 尤其是关于TeeChart控件部分,网上资料零碎,且很多不全面,代码难以使用。我苦寻数周在外国一些网站上寻到了一些有用的信息,把相关的可运行的代码示例贴在文中,希望能帮到后来者。 (如有疑问可在帖子后面留言)
MFC部分:
一、 分割窗体
新建一个单文档的MFC工程(注意在向导中设置窗口最大化和分割窗口支持)。 新建两个对话框,用于分割窗口 【注意】对话框的样式(Style)属性改为下层(Child),边框(Border)属性改为None,最开始没有改这个,程序运行的时候报错了。 【注意】将两个对话框生成从CFormView派生的类。
在CMainFrame的OnCreateClient中添加 【例1】把框架分割成两列,右边的一列和对话框绑定。
【例2】在分割后的子窗口上继续分割 在CMainFrame中添加两个成员变量,类型为CSplitterWnd,如下所示 CSplitterWnd m_splitterWnd1; CSplitterWnd m_splitterWnd2;
添加虚函数virtualBOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); 程序代码修改部分如下:
//初始左右分割框架,要调用函数SetColumnInfo来设定分割线位置 对分割出来的一列再进行分割,则是由CreateView中CSize的高度来确定分割线位置
*总结: * 给框架窗口添加静态拆分视图的过程如下: * 1. 给框架窗口类添加一个CsplitterWnd数据成员。 * 2. 覆盖框架窗口的OnCreateClient函数,并调用CsplitterWnd::CreateStatic来创建静态拆分视图。 * 3. 使用CsplitterWnd::CreateView在每个静态拆分窗口的窗格中创建视图 * 使用静态拆分窗口的一个优点是由于您自己给窗格添加视图,所以可以控制放入视图的种类
二、 添加自定义消息响应
1、在Resource.h中添加 #define WM_MY_MESSAGE (WM_USER+100)
2、在CMyView的定义中添加: //CMyView是要响应自定义消息的我们的视图类 //{{AFX_MSG(CMyView) afx_msg LRESULT OnMyMsg(WPARAM, LPARAM) ; DECLARE_MESSAGE_MAP() //}}AFX_MSG
3、在CMyView的实现cpp文件中添加 BEGIN_MESSAGE_MAP(CMyView, CFormView) //{{AFX_MSG_MAP(CMyView) ON_MESSAGE(WM_MY_MESSAGE, OnMyMsg) //添加消息映射 //}}AFX_MSG_MAP END_MESSAGE_MAP()
4、实现消息映射函数LRESULT CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)
5、发送消息,触发消息响应函数 pMyView->PostMessage(WM_MY_MESSAGE,0, 0); //至于PostMessage和SendMessage的区别 请百度之。 //pMyView是CMyView类对象的指针。
TeeChart部分(以VC++6.0 TeeChart8.0为例)
至于如何获取TeeChart控件,如何注册控件,请百度之,网上有很多。
零
在相应的源文件中添加TeeChart的头文件 (有需要的自己再添加) #include "tchart.h" #include "series.h" #include "valuelist.h" #include "axes.h" #include "axis.h" #include "pen.h" #include "axislabels.h" #include "teefont.h" #include "axistitle.h" #include "aspect.h" #include "fastlineseries.h" #include "titles.h" #include "fastlineseries.h" #include "panel.h" #include "legend.h" #include "annotationtool.h" #include "page.h" #include "strings.h" #include "gradient.h" #include "IsoSurfaceSeries.h"
一、 在视图类中动态添加TeeChart控件。(解决手工拖动添加控件,编译报”Debug Assertion Failed” 错的问题)
我们添加对话框资源让其继承自CFromView。首先手工静态把控件拖到对话框上,然后建立类向导,生成一个对象m_chart。
在主框架CMainFrame::OnCreateClient()或OnCreate()中【看在哪个函数中分割窗口 产生视图】 RecalcLayout(); //这一句很重要,没有它,会报错。 pView->OnInitialUpdate(); //pView是我们分割窗口得到的CMyDlgView视图的指针。
在视图类CMyDlgView中添加OnInitialUpdate()函数 CRect rect; GetClientRect(&rect); m_chart.MoveWindow(&rect, TRUE);
在视图类CMyDlgView中添加WM_CREATE消息响应函数OnCreate()在其中添加 m_chart.Create("",WS_VISIBLE, CRect(0, 0, 0, 0), this, 1234) ;//动态生成控件 m_chart.AddSeries(0);//操作控件 m_chart.Series(0).FillSampleValues(50); //m_chart是我们的控件TeeChart
即可。 //但此为动态添加的控件,所有设置操作都得通过代码操作。
二、 绘制2D曲线
这个在网上有很多资料了。我在这里再简单总结一下其过程。
A、初始化部分: 在TeeChart控件所在的视图类的OnCreate函数中,进行TeeChart控件的初始化工作。
B、绘制部分: 在TeeChart控件所在的视图类的自定义消息响应函数OnMyMsg中,或是在定时器中,添加:
由于TeeChart绘制曲线点的函数Add,每调用一次才绘制一次,故需要有外部消息激发消息响应函数,才能把曲线动态绘制出来。 可以用设置定时器和自定义消息响应函数的方式来实现。(定时器比较简单,消息响应函数上面MFC部分已经讲过)
三、 绘制3D曲线
解决TeeChart8中绘制3D图形报”Invalid class typecast” 错的问题。
A、在承载TeeChart的对话框类Dlg的类定义中,添加:VARIANT SeriesIndex;
B、在类的相关方法中绘制,添加代码: m_chart.RemoveAllSeries();
//下面的设置很重要(没有的话,会出错) SeriesIndex.vt=VT_INT; SeriesIndex.intVal=m_chart.AddSeries(scWaterfall);//scWaterfall=33瀑布图的编号 m_chart.Series(0).GetAsWaterfall().SetIrregularGrid(true);
m_chart.Series(0).GetAsWaterfall().AddXYZ(x,y, z, NULL, RGB(255,0,0));
(TeeChart的3D图有很多种,上面是以瀑布图为例的,其他图种的编号如下:) const unsigned long scLine = 0; const unsigned long scBar = 1; const unsigned long scHorizBar = 2; const unsigned long scArea = 3; const unsigned long scPoint = 4; const unsigned long scPie = 5; const unsigned long scFastLine = 6; const unsigned long scShape = 7; const unsigned long scGantt = 8; const unsigned long scBubble = 9; const unsigned long scArrow = 10; const unsigned long scCandle = 11; const unsigned long scPolar = 12; const unsigned long scSurface = 13; const unsigned long scVolume = 14; const unsigned long scErrorBar = 15; const unsigned long scBezier = 16; const unsigned long scContour = 17; const unsigned long scError = 18; const unsigned long scPoint3D = 19; const unsigned long scRadar = 20; const unsigned long scClock = 21; const unsigned long scWindRose= 22; const unsigned long scBar3D = 23; const unsigned long scImageBar = 24; const unsigned long scDonut = 25; const unsigned long scTriSurface = 26; const unsigned long scBox = 27; const unsigned long scHorizBox = 28; const unsigned long scHistogram = 29; const unsigned long scColorGrid = 30; const unsigned long scBarJoin = 31; const unsigned long scHighLow = 32; const unsigned long scWaterfall = 33; const unsigned long scSmith = 34; const unsigned long scPyramid = 35; const unsigned long scMap = 36; const unsigned long scHorizLine = 37; const unsigned long scFunnel = 38; const unsigned long scCalendar = 39; const unsigned long scHorizArea = 40; const unsigned long scPointFigure = 41; const unsigned long scGauge = 42; const unsigned long scVector3D = 43; const unsigned long scTower = 44; const unsigned long scPolarBar = 45; const unsigned long scBubble3D = 46; const unsigned long scHorizHistogram = 47; const unsigned long scVolumePipe = 48; const unsigned long scIsoSurface = 49; const unsigned long scDarvas = 50; const unsigned long scHighLowLine = 51; const unsigned long scPolarGrid = 52; const unsigned long scDeltaPoint = 53; const unsigned long scImagePoint = 54; const unsigned long scOrganizational = 55; const unsigned long scWorld = 56; const unsigned long scTagCloud = 57; const unsigned long scKagi = 58; const unsigned long scRenko = 59; const unsigned long scNumericGauge = 60; const unsigned long scLinearGauge = 61; const unsigned long scCircularGauge = 62; const unsigned long scBigCandle = 63; const unsigned long scLinePoint = 64;
//如需要相关图种,只需把上面代码 SeriesIndex.intVal= m_chart.AddSeries(scWaterfall);//把scWaterfall改为你所需图种的编号 m_chart.Series(0).GetAsWaterfall().SetIrregularGrid(true);// GetAsWaterfall改为你所需图种的相关函数名
---------------- 一个完整的例子:
A、在CMyView(承载TeeChart的对话框视图)的定义中,添加VARIANTSeriesIndex;
B、在int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中:
C、在自定义的消息处理函数中:
四、 用AddArray一次把数组中的值绘制出来
1、先在TeeChart所在的类中 添加: COleSafeArray XValues; COleSafeArray YValues;
2、再在TeeChart的初始化设置函数添加:
3、在相应的位置添加: m_chart.Series(0).AddArray(200000,YValues,XValues);
//附赠:本人搜集的一些TeeChart的相关资料。链接:http://download.csdn.net/detail/yang_yulei/7685021
//此文为网上首发,转载请注明出处,谢谢!
|
|