Chinaunix首页 | 论坛 | 博客
  • 博客访问: 537467
  • 博文数量: 576
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5020
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(576)

文章存档

2011年(1)

2008年(575)

我的朋友

分类:

2008-10-14 14:54:21

模拟 Windows 下 CPU 占用率的控件及其实现

作者:



一、前言

  在 的看到网友 xingxueping 的一篇名为“”的文章。感觉很不错。唯一不足的是外观不太完美, 所以有了要改进的想法。我又参考了一下Windows任务管理器(图一),于是模仿MS的东西,做了这个控件(图二)。


图一 Windwows管理器


图二 我的 Control


二、功能说明

  我把这个东东做成了ActiveX控件,为的是通用性,这样,其他的开发工具(VB、Delphi等)也能使用它,而不仅限于VC。 我是用MFC来写的这个控件,该控件提供的大致功能有:设置占用比率颜色、未占用比率颜色、设置占用率、设置背景颜色、字体颜色,等等。 控件的方法列表如下:

			void SetFreeColor(OLE_COLOR m_Color);          //设置未占用部分的颜色
			void SetUsedColor(OLE_COLOR m_Color);          //设置占用部分的颜色
			void RestoreDefaultColor();                    //恢复默认颜色设置
			void SetUsedRate(short iRate);                 //设置占用率
			void SetBKColor(OLE_COLOR m_Color);            //设置背景颜色
			void SetFontColor(OLE_COLOR m_Color);          //设置字体颜色
      
三、主要代码分析

  这个控件的重点,当然是控件的绘制。核心的绘制函数代码如下(必要的部分,我添加了注释):
void CCPURateControlCtrl::ReDrawControl()
{
	CDC  memDC; 
	CClientDC dc(this);
	CBitmap memBitmap;
	CBitmap *pOldBitmap=NULL;

	CString strUsges;
	CPen FreePen;
	CPen UsedPen;
	CPen *pOldPen    = NULL;
	CPen *pOldMemPen = NULL;

	CRect m_rect;
	GetClientRect(&m_rect);

	FreePen.CreatePen(PS_SOLID,2,m_FreeColor);
	UsedPen.CreatePen(PS_SOLID,2,m_UsedColor);

	memDC.CreateCompatibleDC(&dc);
	pOldMemPen=memDC.SelectObject(&FreePen);
	memBitmap.CreateCompatibleBitmap(&dc,m_rect.right,m_rect.bottom);
	
	pOldBitmap=memDC.SelectObject(&memBitmap);
	
	memDC.FillSolidRect(&m_rect, m_BackColor);

	//绘制未占用比率的线条

	for(int i=0;i<=15;i+=3)   //总共6行,12条
	{
		memDC.MoveTo(m_rect.left+15,m_rect.top+15+i);
		memDC.LineTo(m_rect.Width()/2-2,m_rect.top+15+i);

		memDC.MoveTo(m_rect.Width()/2+2,m_rect.top+15+i);
		memDC.LineTo(m_rect.right-15,m_rect.top+15+i);
	}

         //绘制显示比率的百分比文字
	CString str;
	str.Format("%3d%%",iUsedRate);
	memDC.SelectObject(&UsedPen);
	
	CFont m_Font;
	m_Font.CreateFont(14,          // nHeight
		5,                         // nWidth
		0,                         // nEscapement
		0,                         // nOrientation
		FW_NORMAL,                 // nWeight
		FALSE,                     // bItalic
		FALSE,                     // bUnderline
		0,                         // cStrikeOut
		ANSI_CHARSET,              // nCharSet
		OUT_DEFAULT_PRECIS,        // nOutPrecision
		CLIP_DEFAULT_PRECIS,       // nClipPrecision
		DEFAULT_QUALITY,           // nQuality
		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
		"Arial"
	);
	
	CFont *pFont=memDC.SelectObject(&m_Font);
	memDC.SetTextColor(m_FontColor);
	memDC.SetBkMode(TRANSPARENT);
	memDC.TextOut(m_rect.Width()/2-12,m_rect.bottom-20,str);

	int iAmount=0,k;

	//判断占用率,分段。

	if(iUsedRate>5 && iUsedRate<=20)
		iAmount=1;
	if(iUsedRate>20 && iUsedRate<=33)
		iAmount=2;
	if(iUsedRate>34 && iUsedRate<=50)
		iAmount=3;
	if(iUsedRate>51 && iUsedRate<=70)
		iAmount=4;
	if(iUsedRate>71 && iUsedRate<=90)
		iAmount=5;
	if(iUsedRate>91 && iUsedRate<=100)
		iAmount=6;
	
         //确定绘制的偏移位置
	switch(iAmount)
	{
		case 1:	  k=0;break;
		case 2:   k=-3;break;
		case 3:   k=-6;break;
		case 4:   k=-9;break;
		case 5:   k=-12;break;
		case 6:   k=-16;break;
		default:   k=1;break;
	}

	//绘制已占用的条数
	for(int j=0;j>=k;j-=3)
	{
		memDC.MoveTo(m_rect.left+15,m_rect.top+15+15+j);
		memDC.LineTo(m_rect.Width()/2-2,m_rect.top+15+15+j);
		
		memDC.MoveTo(m_rect.Width()/2+2,m_rect.top+15+15+j);
		memDC.LineTo(m_rect.right-15,m_rect.top+15+15+j);
	}
	
	//从内存DC拷贝到当前DC。这样做的好处是速度快,防止闪烁。
	dc.BitBlt(m_rect.left,m_rect.top,m_rect.right,m_rect.bottom,&memDC,0,0,SRCCOPY);
	
	memDC.SelectObject(pOldBitmap);
	memDC.SelectObject(pOldMemPen);
	memDC.DeleteDC();
	memBitmap.DeleteObject();
}      
四、控件的测试

  编译完成后,我们得到CPURateControl.ocx控件。一般在编译后,VC会自动帮你注册这个控件,你也可以在命令行下用regsvc32.exe来注册。 关于测试,我们可以在Visual Studio自带的工具ActiveX Control Test Container中进行测试。也可以自己写一个小程序来测试。我在VC中 做了个测试的小程序。如图三:


图三 测试小程序

  测试程序中,我用了一个自己封装的DLL来分别获取CPU和内存的占用率。是在一个Timer中定时刷新获取的。这个DLL你也可以拿来自己用, DLL导出函数为2个:
UINT GetCpuUseage();    //返回CPU占用率
UINT GetMemUseage();    //返回内存占用率      
返回的是多少,就表示占用了百分之多少。

五、结束语

  这个控件其实不光可以用来显示CPU占用率,还可以用在其他的用途,只要和百分比显示有关的场合都可以。控件附上所有的源代码,希望对大 家有用处。有问题探讨,欢迎访问 VC源动力


--------------------next---------------------

感谢网友timlyee的意见,这个控件线数就是固定的,没有继续完善。可以根据对控件的调整,获取当前控件大小,然后自动生成合适的线数。感谢你的意见和代码。 ( yexiaozhou2003 发表于 2006-4-11 17:16:00)
 
这个孔件非常不错,但有个确定 线数是固定的
一旦孔件高度改变就乱了,把代码要稍微修改下,简单实现如下:

int h = m_rect.Height()-30;
for(int i=0;i<=h;i+=3)
{
memDC.MoveTo(m_rect.left+15,m_rect.bottom-15-i);
memDC.LineTo(m_rect.Width()/2-2,m_rect.bottom-15-i);
memDC.MoveTo(m_rect.Width()/2+2,m_rect.bottom-15-i);
memDC.LineTo(m_rect.right-15,m_rect.bottom-15-i);
}
..........中间代码省略.............
h = h*iUsedRate/100;
for(int m=0;m{
memDC.MoveTo(m_rect.left+15,m_rect.bottom-15-m);

memDC.LineTo(m_rect.Width()/2-2,m_rect.bottom-15-m);

memDC.MoveTo(m_rect.Width()/2+2,m_rect.bottom-15-m);
memDC.LineTo(m_rect.right-15,m_rect.bottom-15-m);
} ( timlyee 发表于 2006-3-14 14:24:00)
 
你好,你的工程是否使用了UNICODE模式?
在编译器选项下面,把_UNICODE 改为 _MBCS即可。 ( yexiaozhou2003 发表于 2006-2-26 23:00:00)
 
为什么我用你的源代码编译不能通过?

E:\Downloads\cpuratecontrol\CPURateControl\CPURateControlCtl.cpp(238) : error C2664: 'void __cdecl CString::Format(const unsigned short *,...)' : cannot convert parameter 1 from 'char [6]' to 'const unsigned short *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
E:\Downloads\cpuratecontrol\CPURateControl\CPURateControlCtl.cpp(256) : error C2664: 'CreateFontW' : cannot convert parameter 14 from 'char [6]' to 'const unsigned short *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

CPURateControl.ocx - 2 error(s), 1 warning(s)
( laoli_no1 发表于 2006-2-24 20:28:00)
 
.......................................................

--------------------next---------------------

阅读(654) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~