源代码http://download.csdn.net/source/2402219
我先简单介绍一下我的思路:
在初始化对话框中,添加一个InitChart函数,功能是初始化Mschart。同时开启设计器settimer
然后通过Ontimer这个定时器的相应函数,每一秒更新一下Mschart。
这里面的数据是通过GetNetspeed的函数获得。
第一步Mschart使用
1.插入MsChart控件,
在工程中加入 mschart
菜单->Project->Add To Project->Components and Controls->Registered ActiveX Controls->Microsoft Chart Control, version 6.0 (OLEDB)
2.使用mschart的变量之前,一定要包含相应方法的头文件。
下面是我的IninChart函数
void CMschart_testDlg::InitChart()
{
VARIANT var;
m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetAuto(FALSE);//不自动标注y轴刻度
m_Chart.GetPlot().GetAxis(1, var).GetValueScale().SetMaximum(0.01);//y轴最大刻度
m_Chart.GetPlot().GetAxis(1, var).GetValueScale().SetMinimum(0);//y轴最小刻度
m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMajorDivision(10);//y轴刻度10等分
m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMinorDivision(1);//每刻度一个刻度线
m_Chart.SetColumnCount(2); //2个项,2条曲线
m_Chart.SetTitleText("网卡利用率");//设置标题栏
//m_Chart.SetRowLabel("第I行");//设置第i行标签
m_Chart.SetColumnLabel("发送速率");//设置第j列标签
m_Chart.SetColumn(2);
m_Chart.SetColumnLabel("接受速率");
// 下面两句改变背景色14:55:55
m_Chart.GetBackdrop().GetFill().SetStyle(1);
m_Chart.GetBackdrop().GetFill().GetBrush().GetFillColor().Set(255, 255, 255);//白色背景
// 显示图例
m_Chart.SetShowLegend(TRUE); //显示图例
m_Chart.GetPlot().GetSeriesCollection().GetItem(1).GetPen().GetVtColor().Set(0, 0, 255);
//线色,蓝色曲线
m_Chart.GetPlot().GetSeriesCollection().GetItem(2).GetPen().GetVtColor().Set(255, 0, 0);
//红色
m_Chart.GetPlot().GetSeriesCollection().GetItem(1).GetPen().SetWidth(2);//线宽
m_Chart.GetPlot().GetSeriesCollection().GetItem(2).GetPen().SetWidth(2);
m_Chart.SetRowCount(20); //一屏显示20个采样时刻
m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetAuto(FALSE);//不自动标注x轴刻度
m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerLabel(1);
//每时刻一个标注
m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerTick(1);
//每时刻一个刻度线
m_Chart.GetPlot().GetAxis(0,var).GetAxisTitle().SetText("时间"); // X轴名称
//初始化曲线值
for(int beginrow=1; beginrow<=20; ++beginrow){
m_Chart.GetDataGrid().SetData(beginrow, 1, 0, 0);//设置第一条曲线的第row个点
m_Chart.GetDataGrid().SetData(beginrow, 2, 0, 0);//设置第二条曲线的第row个点
}
m_Chart.Refresh(); //更新数据
SetTimer(1, 1000, NULL);//启动定时器,定时间隔1秒
//初始化这个全局变量
DWORD sedata0;
DWORD redata0;
DWORD totaldata0;
NetSpeed(totaldata0,sedata0,redata0); //获得网络数据
tmpsend= sedata0 ; //记载此次数据,为下次使用。
tmpreveive= redata0;
}
一些具体的MsChart使用,请看下面的博客。(我当时就是看他介绍的一些常用的方法与属性)
http://blog.csdn.net/sgdgoodboy/archive/2007/09/10/1778757.aspx
3.动态显示
用计时器 settimer,和Ontimer,
在对话框的的类向导,添加一个VM_TIMER的消息,会自动产生onTImer这个函数,次函数是用来响应settimer计时器的,可以在ontimer这个函数里添加画图函数的功能。
void CMschart_testDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
DrawPic();//调用函数,刷新曲线显示
CDialog::OnTimer(nIDEvent);//自动生成的
}
double i=0;
UINT row=1;
//全局变量数组,用来存放发送, 接受数据的
double datase[20]={0};
double datare[20]={0};
void CMschart_testDlg::DrawPic()
{
DWORD sedata;
DWORD redata;
DWORD totaldata;
NetSpeed(totaldata,sedata,redata); //获得网络数据
double total=totaldata;
double newsedata= (sedata-tmpsend)/total; //新的发送、接受数据
double newredata=(redata-tmpreveive)/total;
for (int i=0 ; i<19 ; i++) //向移前一位数据。
{
datare[i]=datare[i+1];
datase[i]=datase[i+1];
}
// datase[18]=tmpsend; //上次数据
// datare[18]=tmpreveive;
datare[19]=newredata; //新的数据
datase[19]=newsedata;
for (int j=0; j<20; j++) //画图
{
m_Chart.GetDataGrid().SetData(j+1, 1, datase[j], 0);//设置第一条曲线的第j+1个点
m_Chart.GetDataGrid().SetData(j+1, 2, datare[j], 0);//设置第二条曲线的第j+1个点
//TRACE("接受数据%f,发送数据%f /n",lastredata,lastsedata);
}
m_Chart.Refresh();
tmpsend= sedata ; //记载此次数据,为下次使用。
tmpreveive= redata;
}
注意:把我的程序放到别人的机器上运行,结果出错。
第二步 网络流量的获得
获得本机网络连接带宽,可以用GetIfTable()这个函数。
此函数应包含四个头文件和一个lib
#include <iphlpapi.h> ,<ipexport.h>,<iprtrmib.h>,<iptypes.h>
#pragma comment ( lib, "iphlpapi.lib" )
这个函数原型
DWORD WINAPI GetIfTable( OUT PMIB_IFTABLE pIfTable, IN OUT PULONG pdwSize, IN BOOL bOrder );
其中涉及到一个MIB_IFROW一个结构体,可以包含网卡信息。
dwspeed是网卡类型,100M还是10M等,总的数据量。
Dwinoctets, dwoutoctets,一个是网卡实际接受,发送的总的数据量。
我的这部分程序是这样的:做成了一个GetNetspeed函数
int CMschart_testDlg::GetNetSpeed(DWORD &speed,DWORD &sendtotal ,DWORD &retotal)
{
MIB_IFTABLE *pIfTable = NULL; //网络信息表
ULONG dwSize = 0; //接口个数
DWORD dwRet; //返回值
dwRet = GetIfTable( pIfTable, &dwSize, TRUE ); //dwsize获得接口个数
if ( dwRet == ERROR_INSUFFICIENT_BUFFER )
{
pIfTable = ( MIB_IFTABLE * ) new char[dwSize];
if ( pIfTable != NULL )
{
dwRet = GetIfTable( pIfTable, &dwSize, TRUE ); //获得真实接口信息
if ( dwRet == NO_ERROR )
{
TRACE( "dwNumEntries = %u/n", pIfTable->dwNumEntries );
for ( int i=0; i<pIfTable->dwNumEntries; i++ )
{
if((pIfTable->table[i]).dwType ==6
&& (pIfTable->table[i]).dwInOctets>0 && (pIfTable->table[i]).dwOutOctets>0 ){
//只保留dwtype为6是网卡信息,接受发送了数据。默认服务器只能用一个网卡,
TRACE( "table[%1d].dwIndex = %u/n", i, (pIfTable->table[i]).dwIndex );
TRACE( " dwType = %u/n", (pIfTable->table[i]).dwType );
TRACE( " dwSpeed = %u/n", (pIfTable->table[i]).dwSpeed );
//added (pIfTable->table[i]).dwInOctets=0;
TRACE("/t received data is %u/n",(pIfTable->table[i]).dwInOctets); //接口接受总数据
TRACE("/t send data is %u/n",(pIfTable->table[i]).dwOutOctets); // 接口发送总数据
speed=(pIfTable->table[i]).dwSpeed; //获得网卡数据类型,10M or100M
retotal=(pIfTable->table[i]).dwInOctets; //网卡接受到的总的数据字节
sendtotal=(pIfTable->table[i]).dwOutOctets; //网卡发送的
}
}
}
else {
TRACE( "Some error occured in netspeed!/n" );
}
}
else {
TRACE( "Memory allocate failue/n" );
}
}
else {
TRACE( "Some error occured in netspeed!/n" );
}
return 0;
}
解决方法:缺少mschart20.ocx这个控件。这个控件是在C盘windows目录的system32文件夹下面。运行程序之前,要注册一下这个控件。就ok了
注册方法是:在开始--运行—输入regsvr32在把这个控件托到这个对话框中即可。
注意Vista下不可以注册这个控件。
转载: http://blog.csdn.net/iblessu/article/details/5630847