现在的位置: 首页 > 综合 > 正文

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

2018年07月14日 ⁄ 综合 ⁄ 共 5827字 ⁄ 字号 评论关闭

源代码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

抱歉!评论已关闭.