您的位置:首页 > 理论基础 > 计算机网络

VC++如何使用Mschart 实例-------网络流量监控程序

2013-04-24 17:23 483 查看
源代码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下不可以注册这个控件。
转载:/article/11029186.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: