当前位置:C++技术网 > 资讯 > 进度条中的进度百分比的显示设置

进度条中的进度百分比的显示设置

更新时间:2015-10-17 23:38:48浏览次数:1+次

在设计程序时,通常使用进度条来描述当前的操作进度,但是MFC提供进度条控件不能利用精确的数字或百分比来描述进度,因此我们写个小程序来实现这个。
我们用VC,基于对话框来创建对象,项目名为TextProgress,在MFC的基类中有个CProgressCtrl类,CProgressCtrl是“进度条控件”是一个窗口,应用程序可以使用这个窗口来表明一个冗长操作的进度。它由一个从左到右,用系统高亮色逐渐填充的矩形组成。我们基于它派生一个新类CTextProgress,这个就是我们实现代码的地方。然后我们在对话框中添加进度条控件,将其属性设为Smooth,并为它关联一个控件变量m_Progress,基于CTextProgress。当你关联变量成功时,会跳出个对话框,提示你在CTextProgressDlg的头文件中加上TextProgress的头文件,这是因为,我们的这个控件是基于对话框类(CTextProgressDlg)的尽管我们为进度条关联的是别的类型,但还是声明在CTextProgressDlg类的头文件中。因此我们需要告诉编译器,m_Progress变量是CTextProgress中。

我们需要为新类添加WM_PAINT消息,在这里面添加我们的实现代码,当我们添加消息成功后,添加如下代码,不过在头文件中先声明三个变量:


class CTextProgress : public CProgressCtrl
{
// Construction
public:
	CTextProgress();
	COLORREF m_crText;		//文本颜色
	COLORREF m_crProgress;	//进度颜色
	COLORREF m_crBlank;		//空白区域颜色
	
// Attributes
public:
........
}
接着我们在构造函数中,实例化变量:



CTextProgress::CTextProgress()
{
	m_crText	 = RGB(0, 255, 0);
	m_crBlank	 = RGB(255, 255, 255);
	m_crProgress = RGB(0, 255, 0);
}
最后就是代码了:
void CTextProgress::OnPaint() 
{
	PAINTSTRUCT ps;
	CDC* pDC = BeginPaint(&ps);						//开始绘制
	int nPos = GetPos();							//获取当前进度条的位置
	CString csPos;
	csPos.Format("%d%%", nPos);						//格式化字符串
	CRect clientRC;
	GetClientRect(clientRC);						//获取客户区域
	CSize sztext = pDC->GetTextExtent(csPos);		//获取字符串的高度和宽度
	int nX = (clientRC.Width() - sztext.cx) / 2;	//计算中心位置
	int nY = (clientRC.Height() - sztext.cy) / 2;
	int nMin, nMax;
	GetRange(nMin, nMax);							//获取进度条的显示范围
	//获取单位刻度
	double dFraction = (double)clientRC.Width() / (nMax-nMin);
	int nLeft = nPos * dFraction;					//计算左边距
	CRect leftRC  = clientRC;
	leftRC.right  = nLeft;
	CRect rightRC = clientRC;
	rightRC.left  = nLeft;
	pDC->FillRect(leftRC, &CBrush(m_crProgress));	//使用蓝色标识当前的进度
	pDC->FillRect(rightRC, &CBrush(m_crBlank));		//使用白色标识剩余的部分
	pDC->SetTextColor(m_crText);					//设置文本颜色
	pDC->TextOut(nX, nY, csPos);					//输出当前的进度
	ReleaseDC(pDC);									//释放设备上下文
	EndPaint(&ps);									//结束窗口绘制	
}
第一句代码是一个结构体:



PAINTSTRUCT定义
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
PAINTSTRUCT 结构体包含了用于绘制窗口客户区的信息。例如要更新的客户区的矩形区域的大小等等,MFC里的CPaintDC与之对应;
BeginPaint可以得到客户区设备描述表的句柄,GetDC也可以得到,MFC里的CClientDC与之对应。
hdc是用于绘制的句柄,
fErase如果为非零值则擦除背景,否则不擦除背景,
rcPaint 通过制定左上角和右下角的坐标确定一个要绘制的矩形范围,该矩形单位相对于客户区左上角,
后面三个参数都是系统预留的,编程一般用不到。
这是我们第二句代码Begin函数里的参数:
HDC BeginPaint(
HWND hwnd, // 窗口的句柄
LPPAINTSTRUCT lpPaint // 绘制信息
);
下面的代码我就不句句解释了,我在代码后面做了注释。
我们的进度条有了这个还不够哦!我们需要设置一个定时器,使得进度条移动。我们在CTextProgressDlg类中,设置个定时器,首先在InitInstance函数中设置定时器:
BOOL CTextProgressDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	......
	SetTimer(1, 100, NULL);
	return TRUE;  // return TRUE  unless you set the focus to a control
}
接着就是定时器消息了:



void CTextProgressDlg::OnTimer(UINT nIDEvent) 
{
	int nCurPos = m_Progress.GetPos();
	m_Progress.SetPos(nCurPos+1);	
	CDialog::OnTimer(nIDEvent);
}
其中的代码就是设置进度条中的进度一格一格的增加。
效果图: