本文仅供学习交流,严禁用于商业用途,如本文涉及侵权请及时联系本人将于及时删除
目录
1.实例内容
在使用进度条时,除了用文字显示进度以外,也可以通过渐变色来显示。本实例实现了一个渐变颜色的进度条(一个原进度条做对比),实例运行结果如图所示。
2.技术要点
CProgressCtrl类控件
进度条(Progress Bar)是一个向用户显示较长操作过程进度的控件,它由一个矩形窗口组成,随着操作的进行而逐渐被填充。
2.1进展条的风格
打开进展条的属性对话框,如图所示,可以看到它的风格属性并不是很多。其中,“边框”(Border)用来指定进展条是否有边框,“垂直”(Vertical)用来指定进展条是水平还是垂直的,不选中该属性,表示进展条从左到右水平显示。“平滑”(Smooth)表示平滑地填充进展条,若不选中则表示将用块来填充。
2.2进展条的基本操作
(1) 设置进度条的范围
SetRange():用来设置进度条的范围。其函数原型为:
void SetRange(int nLower,int nUpper);
其中,参数nLow和nUpper分别指定了进度条范围的最小和最大值。
(2) 设置进度条的当前进度
SetPos():用来设置进度条的当前进度。其函数原型为:
int SetPos(int nPos);
函数的返回值为进度条的前一个进度。
(3) 使进度条增加一个步长
StepIt():使进度增加一个步长。其函数原型为:
int StepIt();
其中,步长值是由SetStep函数设置的,缺省的步长值是10。函数的返回值为进度条的前一个进度。
(4) 设置进度条的步长值。
SetStep():用来设置进度条的步长值。其函数原型为:
int SetStep(int nStep);
其中,参数nStep为要设置的新步长值。函数的返回值为原来的步长值。
(5) 使进度条前进给定值。
OffsetPos():使进度条前进给定值。其函数原型为:
int OffsetPos(int nStep);
其中,参数nStep为前进的步长值。
2.3进度条渐变
在进度条控件中显示渐变色比较简单,只需要在进度条控件的OnPaint方法中使用循环控制颜色,然后使用FillRect填充区域就可以了。FillRect方法用指定的画刷填充区域,语法如下:
void FillRect(LPCRECT lpRect,CBrush* pBrush);
参数说明:
● lpRect:指向RECT结构的指针,包含被填充的矩形的逻辑坐标,可以为该参数传递CRect对象。
● pBrush:标识填充矩形的画刷。
3.实现过程
(1)新建一个基于对话框的应用程序。
(2)从CProgressCtrl类派生一个子类CColorProgress。(在项目文件头文件处右击菜单添加类)
(3)向对话框中添加一个进度条控件,设置控件的Border和Smooth属性,关联变量m_Progress,其类型为CColorProgress。(注意在dlg.cpp文件中引用相应头文件#include "ColorProgress.h")一个新进度条控件,设置控件的Border和Smooth属性,关联变量m_ProgressOriginal,其类型为CProgressCtrl。
(4)处理进度条的WM_PAINT消息,在其消息处理函数中绘制进度条的文本和当前进度。代码如下:
void CColorProgress::OnPaint()
{
// CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CProgressCtrl::OnPaint()
PAINTSTRUCT ps;
CDC*pDC = BeginPaint(&ps); //开始绘制
int nPos = GetPos(); //获取当前进度条的位置
CRect clientRC;
GetClientRect(clientRC); //获取客户区域
pDC->SetBkMode(TRANSPARENT); //将设备上下文的背景模式设置为透明
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;
//以渐变色填充区域
for (int m = 255; m>0; m--)
{
int x, y;
x = leftRC.Width() * m / 255;
pDC->FillRect(CRect(0, 0, x, leftRC.Height()), &CBrush(RGB(255, m, 0)));
}
pDC->FillRect(rightRC, &CBrush(RGB(255, 255, 255))); //使用白色标识剩余的部分
ReleaseDC(pDC); //释放设备上下文
EndPaint(&ps); //结束窗口绘制
}
(5)处理主窗口的WM_TIMER消息,在该消息的处理函数中设置进度条的显示进度。代码如下:
void CMFC_进度条Dlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int nCurPos = m_Progress.GetPos(); //获取进度条的当前位置
m_Progress.SetPos(nCurPos + 1); //设置进度条的位置
int nCurPos1 = m_ProgressOriginal.GetPos(); //获取进度条的当前位置
m_ProgressOriginal.SetPos(nCurPos1 + 1); //设置进度条的位置
CDialog::OnTimer(nIDEvent);
//CDialogEx::OnTimer(nIDEvent);
}
(6)在CMFC_进度条Dlg::OnInitDialog()中添加相应的初始化代码,代码如下:
BOOL CMFC_进度条Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_Progress.SetRange(0, 100); // 设置进展条范围
//m_Progress.SetStep(5);
m_Progress.SetPos(0);
m_ProgressOriginal.SetRange(0, 100);
//m_ProgressOriginal.SetStep(5);
m_ProgressOriginal.SetPos(0);
SetTimer(1, 1000, NULL);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
4.实例结果
5.示例拓展
根据本实例,读者可以:自绘进度条控件。