本文仅供学习交流,严禁用于商业用途,如本文涉及侵权请及时联系本人将于及时删除
目录
1.实例说明
2.技术要点
3.实现过程
4.实例结果
5.示例拓展
2.10 进度条控件典型实例进度条控件(Progress)用于显示程序的进度,在进行程序安装、文件传输时经常用到。
1.实例说明
在设计应用程序时,通常使用进度条来描述当前的操作进度。但是MFC提供的进度条控件不能够利用精确的数字或百分比来描述进度。本实例将实现进度条的百分比显示的功能,运行结果如图所示。
2.技术要点
在进度条控件中显示文字比较简单,只需要在进度条控件的OnPaint方法中根据当前的位置值输出字符串文本就可以了。为了提供进度条窗口的绘制效率,这里使用了BeginPaint方法来获得进度条窗口的设备上下文,在进度条窗口的设备上下文使用后,调用EndPaint方法来结束进度条窗口的绘制。
下面介绍这两个方法的使用。
(1)BeginPaint方法。
BeginPaint方法用于为窗口准备绘制操作,将绘制的信息填充到参数中。语法如下:
HDC BeginPaint(LPPAINTSTRUCT lpPaint);
参数说明:
● lpPaint:是一个PAINTSTRUCT结构指针,表示接收的绘制信息。
返回值:表示关联窗口的设备上下文指针。
(2)EndPaint方法。
EndPaint方法用于表示窗口的绘制操作结束。语法如下:
void EndPaint(LPPAINTSTRUCT lpPaint);
参数说明:
● lpPaint:是一个PAINTSTRUCT结构指针,包含了由BeginPaint方法获取的绘制信息。
3.实现过程
(1)新建一个基于对话框的应用程序。
(2)从CProgressCtrl类派生一个子类CTextProgress。
(3)向对话框中添加一个进度条控件,设置控件的Border和Smooth属性,关联变量m_Progress,其类型为CTextProgress。
(4)向CTextProgress类中添加成员变量。代码如下:
#pragma once
#include "afxcmn.h"
class CTextProgress :
public CProgressCtrl
{
public:
CTextProgress();
~CTextProgress();
COLORREF m_crText; //文本颜色
COLORREF m_crProgress; //进度颜色
COLORREF m_crBlank; //空白区域颜色
};
并初始化对象
https://blog.csdn.net/self_mind/article/details/50859718
CTextProgress::CTextProgress()
{
m_crText=RGB(255, 0, 0);
m_crProgress=RGB(0,0,255);
m_crBlank = RGB(255, 255, 255);
}
(5)处理进度条的WM_PAINT消息,在其消息处理函数中绘制进度条的文本和当前进度。代码如下:
void CTextProgress::OnPaint()
{
//CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CProgressCtrl::OnPaint()
PAINTSTRUCT ps;
CDC*pDC = BeginPaint(&ps); //开始绘制
int nPos = GetPos(); //获取当前进度条的位置
CString csPos;
csPos.Format(_T("%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;
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;
/********************************二选一*******************************/
//pDC->FillRect(leftRC, &CBrush(m_crProgress)); //使用蓝色标识当前的进度
/**********************************二选一*****************************/
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(m_crBlank)); //使用白色标识剩余的部分
pDC->SetTextColor(m_crText); //设置文本颜色
pDC->TextOut(nX, nY, csPos); //输出当前的进度
ReleaseDC(pDC); //释放设备上下文
EndPaint(&ps); //结束窗口绘制
}
(6)处理主窗口的WM_TIMER消息,在消息处理函数中设置进度条的显示进度。代码如下:
void C进度条百分比Dlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == 1)
{
int nCurPos = m_Progress.GetPos(); //获取进度条的当前位置
m_Progress.SetPos(nCurPos + 1); //设置进度条的位置
if (m_Progress.GetPos() >= 100)
{
KillTimer(1);
MessageBox(_T("进程完毕"));
}
}
CDialogEx::OnTimer(nIDEvent);
}
(7)在进度条百分比Dlg::OnInitDialog()中添加相应的初始化代码,代码如下:
BOOL C进度条百分比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); //设置进度条初始位置
SetTimer(1, 1000, NULL); //启动Timer
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
4.实例结果
5.示例拓展
根据本实例,读者可以:在滑块显示的进度条中显示进度文本。