www.pudn.com > NetTraffic.rar > mftrafficbutton.cpp


#include "stdafx.h" 
#include "MFTrafficButton.h" 
#include "MemDC.h" 
#include  
 
#ifndef _WIN32_IE 
	#define _WIN32_IE 0x0500 
#endif 
 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
///////////////////////////////////////////////////////////////////////////// 
// MFTrafficButton 
 
MFTrafficButton::MFTrafficButton() 
{ 
	brushInitalized = FALSE; 
	interfaceCallBack = NULL; 
	useAdaptiveScale = FALSE; 
	gridxstartpos = 0; 
	gridystartpos = 0; 
	gridxresolution		=	GRIDXRESOLUTION; 
	gridyresolution		=	GRIDYRESOLUTION; 
	gridscrollxspeed	=	GRIDSCROLLXSPEED; 
	gridscrollyspeed	=	GRIDSCROLLYSPEED;  
	plotgranularity		=	PLOTGRANULATRITY; 
	netupdatespeed		=	NETUPDATESPEED; 
	gridupdatespeed		=	GRIDUPDATESPEED; 
	ToggleStatusText	=	"局部最大值"; 
} 
 
MFTrafficButton::~MFTrafficButton() 
{ 
 
} 
 
 
BEGIN_MESSAGE_MAP(MFTrafficButton, CButton) 
	//{{AFX_MSG_MAP(MFTrafficButton) 
	ON_WM_TIMER() 
	ON_WM_RBUTTONDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// MFTrafficButton message handlers 
 
 
 
void MFTrafficButton::PreSubclassWindow()  
{ 
 
	CButton::PreSubclassWindow(); 
	// 这个函数确保这个button是用来绘制的而不是接收按下的消息的 
	ModifyStyle( 0 , BS_OWNERDRAW ); 
 
	this->GetWindowRect(&TrafficDrawRectangle); 
	this->GetWindowRect(&TrafficDrawUpdateRectangle); 
	ScreenToClient(&TrafficDrawUpdateRectangle); 
	ScreenToClient(&TrafficDrawRectangle); 
 
	TGSize.cx = TrafficDrawRectangle.right - TrafficDrawRectangle.left; 
	TGSize.cy = TrafficDrawRectangle.bottom - TrafficDrawRectangle.top; 
 
	initalized = FALSE; 
	MaxTrafficAmount = 0.0; 
	SelectedInterface = 0; 
	 
	smallFont.CreateFont(-10,0,0,0,FW_THIN, FALSE, FALSE, FALSE, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH, "Times New Roman"); 
 
	red		= RGB(255,125,125); 
	green	= RGB(125,255,125); 
	cyan	= RGB(0,255,255); 
	darkblue= RGB(0,0,75); 
//	darkblue= RGB(255,255,255); 
	darkgray= RGB(50,50,50); 
	white	= RGB(255,255,255); 
	black	= RGB(0,0,0); 
	lightgreen	= RGB(156,255,156); 
	darkgreen	= RGB(32,64,32); 
//	darkgreen    =0; 
	greenbrush.CreateSolidBrush(green); 
	redbrush.CreateSolidBrush(red); 
	GridPen.CreatePen(PS_SOLID ,1 , darkgreen); 
	GetWindowRect(&TrafficDrawRectangle); 
	ScreenToClient(&TrafficDrawRectangle); 
 
	 
	TGSize.cx = TrafficDrawRectangle.right - TrafficDrawRectangle.left; 
	TGSize.cy = TrafficDrawRectangle.bottom - TrafficDrawRectangle.top; 
	 
	 
	TrafficEntries = TGSize.cx / plotgranularity; 
	TrafficStats = new TRAFFICENTRY[TrafficEntries+1]; 
	 
	for(DWORD x=0; xSetWindowRgn((HRGN)ShapeWNDRegion, TRUE); 
	initalized = TRUE; 
 
	SetTimer(GRIDTIMER,	gridupdatespeed,	0); 
	SetTimer(NETTIMER,	netupdatespeed,		0); 
 
} 
 
 
void MFTrafficButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	// TODO: Add your message handler code here and/or call default 
//	CButton::OnDrawItem(nIDCtl, lpDrawItemStruct); 
 
	ASSERT( lpDrawItemStruct != NULL ); 
 
	CDC * pDC   = CDC::FromHandle( lpDrawItemStruct -> hDC ); 
	int erg = pDC->SelectClipRgn(&ShapeDCRegion); 
 
	CRect rect = lpDrawItemStruct -> rcItem; 
	UINT state = lpDrawItemStruct -> itemState; 
	UINT nStyle = GetStyle( ); 
 
	int nSavedDC = pDC -> SaveDC( ); 
 
	// Create the brush for the color bar 
	if(brushInitalized == FALSE) 
	{ 
		CBitmap bmp; 
		CMemDC *memDC = new CMemDC(pDC); 
		 
		RECT clipRect; 
		memDC->GetClipBox(&clipRect); 
 
		if(clipRect.right - clipRect.left > 1) 
		{ 
			bmp.CreateCompatibleBitmap(memDC,plotgranularity, TGSize.cy); 
			CBitmap *pOld = memDC->SelectObject(&bmp); 
			 
			CSize bmps = bmp.GetBitmapDimension();		 
			 
			double factor = 255.0 / (float)TGSize.cy; 
			BYTE r,g,b; 
			for(int x = 0; xSetPixelV(0,x,RGB(r,g,b)); 
				memDC->SetPixelV(1,x,RGB(r,g,b)); 
			} 
			memDC->SelectObject(pOld); 
 
			colorbrush.CreatePatternBrush(&bmp);	 
			brushInitalized = TRUE; 
		} 
	} 
	if(initalized == TRUE) 
	{ 
		COLORREF backcolor = GetSysColor(COLOR_BTNFACE); 
		 
		CBrush brush; 
		CMemDC *memDC = new CMemDC(pDC); 
		 
		RECT clipRect; 
		memDC->GetClipBox(&clipRect); 
		memDC->FillSolidRect(&clipRect,backcolor); 
		 
		CFont *oldFont; 
		int xp, yp, xx, yy; 
		orgBrushOrigin = memDC->GetBrushOrg(); 
		 
		oldFont = memDC->SelectObject(&smallFont); 
		 
		double scale = (double)TGSize.cy / (double)MaxTrafficAmount; 
		 
		yp = TrafficDrawRectangle.bottom; 
		xp = TrafficDrawRectangle.left; 
		 
		RECT fillrect; 
		 
		CString tmp; 
		 
		// 填充背景 
		back = memDC->GetBkColor(); 
		brush.CreateSolidBrush(darkblue); 
		memDC->FillRect(&TrafficDrawRectangle, &brush); 
 
		// 画网格 
		int xgridlines, ygridlines; 
		 
		xgridlines = TGSize.cx / gridxresolution; 
		ygridlines = TGSize.cy / gridyresolution; 
		CPen* oldPen = memDC->SelectObject(&GridPen); 
		// 创建垂直线 
		for (int x=0; x<= xgridlines; x++) 
		{ 
			memDC->MoveTo(x*gridxresolution + gridxstartpos, 0			); 
			memDC->LineTo(x*gridxresolution + gridxstartpos, TGSize.cy	); 
		} 
		// 添加水平线 
		for (int y=0; y<= ygridlines; y++) 
		{ 
			memDC->MoveTo(0			, gridystartpos + TGSize.cy - y*gridyresolution - 2); 
			memDC->LineTo(TGSize.cx	, gridystartpos + TGSize.cy - y*gridyresolution - 2); 
		} 
 
		gridxstartpos += gridscrollxspeed; 
		gridystartpos += gridscrollyspeed; 
		if(gridxstartpos < 0				) gridxstartpos = gridxresolution; 
		if(gridxstartpos > gridxresolution	) gridxstartpos = 0; 
		if(gridystartpos < 0				) gridystartpos = gridyresolution; 
		if(gridystartpos > gridyresolution	) gridystartpos = 0; 
 
 
		memDC->SelectObject(oldPen ); 
 
		for(DWORD cnt=0; cntSetBrushOrg(xx,yp); 
				if(TrafficStats[cnt].value > 0.0)  
				{ 
					memDC->FillRect(&fillrect, &colorbrush); 
					memDC->SetPixelV(xx, yy, cyan); 
				} 
			} 
		} 
		 
		tmp.Format("%8.1f",TrafficStats[TrafficEntries-1].value); 
		COLORREF textcolor = memDC->GetTextColor(); 
		int bkmode = memDC->GetBkMode(); 
		memDC->SetBkMode(TRANSPARENT); 
		memDC->SetTextColor(darkblue); 
		memDC->TextOut(6,5,AllTraffic); 
		memDC->SetTextColor(cyan); 
//		memDC->SetTextColor(darkblue); 
		memDC->TextOut(5,5,AllTraffic);  
		memDC->SetTextColor(textcolor); 
		memDC->SetBkMode(bkmode); 
		 
		memDC->SelectObject(oldFont); 
		memDC->SetBrushOrg(orgBrushOrigin.x, orgBrushOrigin.y); 
	 
		delete memDC; 
	}	 
	pDC -> RestoreDC( nSavedDC ); 
 
} 
 
void MFTrafficButton::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if(nIDEvent == NETTIMER) 
	{ 
		 
#ifdef _I_HAVE_PLATFORM_SDK_INSTALLED_		 
 
		DWORD flag, reserved; 
		BOOL erg; 
		flag = 0;//INTERNET_CONNECTION_OFFLINE ; 
		reserved = 0; 
		TCHAR connectionname[1024]; 
		erg =  InternetGetConnectedStateEx( 
			&flag,	//OUT LPDWORD lpdwFlags, 
			(LPTSTR)&connectionname,//OUT LPTSTR lpszConnectionName, 
			1024,//IN DWORD dwNameLen, 
			0//IN DWORD dwReserved 
			); 
		 
		isOnline = erg; 
#else 
		isOnline = TRUE; 
#endif		 
 
		// 得到当前的流量 
		double traffic = m_cTrafficClass.GetTraffic(SelectedInterface); 
		DWORD  totaltraffic = m_cTrafficClass.GetInterfaceTotalTraffic(SelectedInterface); 
		 
		double delta1; 
		double divisor = (1000.0/(double)NETUPDATESPEED); 
		delta1 = (double)(traffic * divisor) / 1024.0; 
		CurrentTraffic.Format("当前流量: %.1f KB/sec",delta1); 
		 
		 
		// Should we recalculate the local maximum per session or per display? 
		if(useAdaptiveScale==TRUE) 
		{ 
			MaxTrafficAmount = 0.0; 
		} 
		// Shift whole array 1 step to left and calculate local maximum 
		for(DWORD x=0; x MaxTrafficAmount) 
				MaxTrafficAmount = TrafficStats[x].value; 
		} 
		if(isOnline == TRUE) 
		{ 
			TrafficStats[TrafficEntries].connected = TRUE; 
			TrafficStats[TrafficEntries].value = traffic; 
			if(TrafficStats[TrafficEntries].value > MaxTrafficAmount) 
				MaxTrafficAmount = TrafficStats[TrafficEntries].value; 
		} 
		else 
		{ 
			TrafficStats[TrafficEntries].connected = FALSE; 
			TrafficStats[TrafficEntries].value = traffic; 
			if(TrafficStats[TrafficEntries].value > MaxTrafficAmount) 
				MaxTrafficAmount = TrafficStats[TrafficEntries].value; 
		} 
		 
		double delta2; 
		divisor = (1000.0/(double)NETUPDATESPEED); 
		delta2 = (double)(MaxTrafficAmount * divisor) / 1024.0; 
		MaximalTraffic.Format("最大流量:%.1f KB/sec",delta2); 
		AllTraffic.Format("总流量为: %.1f / %.1f KB/sec",delta1, delta2); 
		 
	} 
 
	// 绘制 
	Invalidate(FALSE); 
 
	CButton::OnTimer(nIDEvent); 
} 
 
//创建右键按下后产生的一个pop-up菜单 
void MFTrafficButton::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
#define STARTINDEX	2000 
#define ENDINDEX	2999 
#define SET_SCALING	3000 
 
	HMENU hMenu , hPopup; 
	long retId = 0; 
	int InterfaceIndex = STARTINDEX; 
	POINT pt; 
	 
	hMenu = CreatePopupMenu( );			   
	if( hMenu ) 
	{	 
		//  If the menu was created, add the item text 
		CString tmp, tmp2; 
		double tottraff = (double)m_cTrafficClass.GetInterfaceTotalTraffic(SelectedInterface) / (1024.0*1024.0); 
		m_cTrafficClass.GetNetworkInterfaceName(&tmp, SelectedInterface); 
		tmp2.Format("接口名称:%s : %.1f MB", tmp, tottraff); 
		 
		AppendMenu( hMenu , MF_STRING , 1001 , tmp2 ); 
		AppendMenu( hMenu , MF_SEPARATOR , 1000 , NULL ); 
		// Submenu 
		hPopup = CreatePopupMenu( );			  //  Create a new popup menu 
		if( hPopup ) 
		{ 
			CString tmp; 
			int cnt; 
			for(cnt=0; cnt<=m_cTrafficClass.GetNetworkInterfacesCount(); cnt++) 
			{ 
				CString tmp2; 
				double tottraff = (double)m_cTrafficClass.GetInterfaceTotalTraffic(cnt) / (1024.0*1024.0); 
				m_cTrafficClass.GetNetworkInterfaceName(&tmp, cnt); 
				 
				tmp2.Format("%s : %.1f MB", tmp, tottraff); 
				AppendMenu( hPopup , MF_STRING , InterfaceIndex++ , tmp2 ); 
			} 
			AppendMenu( hMenu , MF_POPUP , ( UINT )hPopup , "选择一个接口" ); 
			AppendMenu( hMenu , MF_SEPARATOR , 1000 , NULL ); 
			AppendMenu( hMenu , MF_STRING , SET_SCALING , "锁定的缩放比例:" + 	ToggleStatusText); 
		} 
	} 
	 
	GetCursorPos( & pt );			 
	//显示菜单 
	retId = TrackPopupMenu( hMenu , TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD ,  pt.x , pt.y , 0 , this -> m_hWnd , NULL );  //  start the menu 
	DestroyMenu( hMenu );			 
	if( retId == 0 ) 
	{ 
		return; 
	} 
	else 
	{ 
		if(retId == SET_SCALING) 
		{ 
			if(useAdaptiveScale == TRUE) 
			{ 
				useAdaptiveScale = FALSE; 
				ToggleStatusText = "全局最大值"; 
			} 
			else 
			{ 
				useAdaptiveScale = TRUE; 
				ToggleStatusText = "局部最大值"; 
			} 
		} 
		if((retId>=STARTINDEX) && (retId