VC进度条控件编程CProgressCtrl
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC进度条(Progress)控件
一属性
二CProgressCtrl常用函数
三一般的开发方法
四编程示例
进度条控件对应的MFC类为CProgressCtrl。
从上图的继承关系可以看出,进度条对应的类继承与窗口类,所以进度条控件实质上就是一个窗口。
一属性
ID设置控件的ID。
visible是否可见
group将控件分组。
help id确定控件是否具有帮助ID
disabled是否可用
tab stop按tab键是否能够获得焦点
border控件周围有边框
vertical控件竖直(PBS_VERTICAL)放置,默认是水平放置的。
smooth设置进度条为平滑(PBS_SMOOTH)显示方式。
client edge使控件边框下凹
static edge控件边缘为实边框
modal frame控件呈现3D效果
transparent控件透明。
控件下方的窗口不会被控件掩盖。
accept files是否接受文件拖动。
用户在对话框中拖动一个文件,控件将收到WM_DROPFILES消息。
Right aligned text文本右对齐
二CProgressCtrl常用函数
SetRange
void SetRange(short nLower,short nUpper);
void SetRange32(int nLower,int nUpper);
功能:设置进度条的范围。
如果不设置,默认的范围是0~100。
参数:nLower为范围下界,nUpper为范围上界。
说明:设置范围一个好处是方便计算进度。
例如要复制1000个文件,就设置范围为0~1000。
这样就不用去转换进度,直接用复制了的文件数来设置当前进度条的位置。
对应的函数void GetRange(int&nLower,int&nUpper);
SetPos
int SetPos(int nPos);
功能:用于设置当前进度条的位置。
例如设置进度条的范围是0~100。
调用SetPos(50),那么进度条就显示走过了50%。
返回值:返回先前的进度条位置。
对应的函数int GetPos();获得当前进度条的位置。
Create
BOOL Create(DWORD dwStyle,const RECT&rect,CWnd*pParentWnd,UINT nID);
功能:用于动态创建一个进度条。
参数:
DWORD dwStyle进度条的样式。
由于进度条是窗口,所以具有窗口的样式。
同时进度条也有自己特有的样式。
PBS_VERTICAL进度条竖直放置,PBS_SMOOTH进度平滑显示。
const RECT&rect进度条的父窗口的放置位置。
CWnd*pParentWnd父窗口
UINT nID进度条的ID。
返回值:创建成功返回TRUE,失败FALSE。
三一般的开发方法
进度条创建的方式有两种:动态创建和静态创建。
动态创建的大概步骤:首先创建一个CProgressCtrl类对象,然后调用Create()函数创建一个进度条,最后调用ShowWindow()将进度条显示在父窗口上。
这样进度条就创建好了,如要设置进度,就调用SetPos()函数来设置。
动态创建要注意,一个CProgressCtrl
类对象仅能够和一个进度条相关联,否则程序会报错。
判断对象是否关联进度条的一个方法是判断m_hwnd是否为NULL,如果是则表示没有关联,否则就关联了。
m_hwnd是CWnd 类的成员变量,保存窗口句柄。
CProgressCtrl类继承于CWnd,所以也有这个成员变量。
静态创建:就是先在对话框上拖动进度条控件来创建一个控件,然后将该控件ID和一个CProgressCtrl类对象关联。
方法如下:选择“view”菜单→“classwizard”弹出“MFC classwizard”对话框,如下图。
单击Member Variables选项卡,选择进度条控件的ID,然后单击右边的“add variable”按钮,弹出如下对话框:
定义一个变量名,单击“OK”就将这个CProgressCtrl对象和进度条控件关联了。
然后用该对象,调用SetPos()函数就能够设置进度条的进度了。
四编程示例
在新浪博客/s/blog_1321350730102v0mo.html中可以获得代码的下载地址。
示例最终的效果如上图所示,第一个进度条用MFC的CProgressCtrl类创建,后面两个进度条用自定义的一个CProgressCtrl类的子类CAdvancedProgress创建。
第二个进度条仅是将已完成的进度用红色表示,未完成的用绿色表示。
最后一个滚动条增加一个功能,就是在已完成部分,有一条白色的线条不停地来回滚动。
为了实现已完成部分用红色填充,未完成部分用绿色填充,需要重载OnPaint()函数,代码如下。
基本思想是:先调用GetPos()和GetRange()函数来获得进度条的当前进度和范围;然后调用GetClientRect()函数来获得进度条的用户区域;根据前两步得到的数据,计算得到已完成的区域和未完成的区域;最后用FillRect()函数分别用红色和绿色来填充两个区域。
//绘制滚动条
void CAdvancedProgress::OnPaint()
{
CPaintDC dc(this);//device context for painting
//TODO:Add your message handler code here
//获取进度条的范围和当前进度
int iLower,iUpper;
int iCurrentPos=GetPos();
GetRange(iLower,iUpper);
//获取进度条的客户区信息
RECT rectProgress;
GetClientRect(&rectProgress);
int iClientWidth=rectProgress.right-rectProgress.left;
//计算进度的区域
double dCurrentRate=(double)(iCurrentPos-iLower)/(iUpper-iLower);
RECT rectLeft=rectProgress,rectRight=rectProgress;
rectLeft.right=rectLeft.left+iClientWidth*dCurrentRate;
rectRight.left=rectLeft.right;
//绘制左边区域和右边区域
dc.FillRect(&rectLeft,&CBrush(RGB(255,0,0)));
dc.FillRect(&rectRight,&CBrush(RGB(0,255,0)));
//Do not call CProgressCtrl::OnPaint()for painting messages
}
为了实现白色线条在已完成区域来回滚动的效果,需要在CAdvancedProgress类中设置一个定时器,来实现绘制白色线条的功能。
具体代码见下面,基本原理和上面的填充进度条的原理一致。
//滚动条的定时器
void CAdvancedProgress::OnTimer(UINT nIDEvent)
{
//TODO:Add your message handler code here and/or call default
//获取进度条的范围和当前进度
int iLower,iUpper;
int iCurrentPos=GetPos();
GetRange(iLower,iUpper);
if(iCurrentPos==iUpper){//如果进度为100%就结束这个定时器KillTimer(1);
}
//获取进度条的客户区信息
RECT rectProgress;
GetClientRect(&rectProgress);
int iClientWidth=rectProgress.right-rectProgress.left;
if(m_iChilePos>=iLower&&m_iChilePos<iCurrentPos){
//计算进度的区域
double dCurrentRate=(double)(m_iChilePos-iLower)/(iUpper-iLower);
int x=rectProgress.left+iClientWidth*dCurrentRate;
CClientDC dc(this);
CPen newPen(PS_SOLID,1,RGB(255,255,255));
CPen*pOld=dc.SelectObject(&newPen);
dc.MoveTo(x,rectProgress.top);
dc.LineTo(x,rectProgress.bottom);
m_iChilePos++;
dc.SelectObject(pOld);
}else{
m_iChilePos=0;
}
CProgressCtrl::OnTimer(nIDEvent); }。