如何在状态栏中实现进度指示器控制

男鹿半岛

男鹿半岛

2016-01-29 12:01

如何在状态栏中实现进度指示器控制,如何在状态栏中实现进度指示器控制

如何在状态栏中实现进度指示器控制


编译/NorthTibet

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/cyuyanjiaocheng/)

下载例子源代码


    我最近作了一个C++/MFC程序,这个程序有时要加载大容量文件,为了让文件加载过程不至于太单调,我想在UI中用进度指示器显示文件的加载过程,而且我想在程序的状态栏中使用这个指示器控制。经过一番研究和尝试,我实现了自己的想法。本文将详细介绍整个实现过程。希望大家在解决类似的问题时少走一些弯路......
    尽管MFC提供了标准的进度指示器控件(progress control),但是不能在状态栏里直接使用这个控件,因此我创建了自己的可重用C++类来实现进度指示。这个类从CStatusBar派生。整个实现过程不是很难,思路是在状态栏创建一个进度指示器控制,把它作为子窗口来对待,然后根据不同的状态来显示或者隐藏进度指示器。本文提供了一个范例程序pgrsbar,这个程序的框架使用了MFC的文档/视图结构,在编辑视图里显示文本文件。打开文件的时候,pgrsbar仿真长时间的加载过程并在状态栏里显示进度指示,如图一所示。我将这个含有进度指示器的状态栏封装在了一个CStatusBar派生的类中——CProgStatusBar。


图一 在状态栏里显示进度指示

下面是这个类的详细说明和使用方法:
CProgStatusBar是从标准的MFC类CStatusBar派生而来。我在CProgStatusBar派生类中加了一个CProgressCtrl类型的数据成员——m_wndProgBar,并且实现了三个重要的成员函数或方法:OnCreate、OnSize和OnProgress。下面是这三个函数的详细说明:

OnCreate负责在状态栏第一次被创建时接收控制,继而创建进度指示器并将它初始化为一个子窗口,

int CProgStatusBar::OnCreate(LPCREATESTRUCT lpcs){   lpcs-style |= WS_CLIPCHILDREN;   VERIFY(CStatusBar::OnCreate(lpcs)==0);   VERIFY(m_wndProgBar.Create(WS_CHILD, CRect(), this, 1));   m_wndProgBar.SetRange(0,100);   return 0;}      
    OnCreate在状态栏的式样中加了一个WS_CLIPCHILDREN,它告诉Windows不要绘制子窗口以下的状态栏区域,这样可以减少屏幕闪烁。接着OnCreate创建进度指示器控制并将它的范围设置成[0,100]。注意在这里创建进度指示器控制时没有用WS_VISIBLE,因为我想在程序开始的时候隐藏它。
    无论何时,只要你在某个窗口里添加子窗口,那么一定要负责管理它的大小尺寸,也就是说,当父窗口大小改变后,子窗口的大小也要跟着作相应的改变。一般来说,这个工作在父窗口的WM_SIZE/OnSize处理例程中完成: 
// 状态栏大小改变以后,子窗口的尺寸跟着变void CProgStatusBar::OnSize(...){  CStatusBar::OnSize(...);  CRect rc;  GetItemRect(0, &rc);  m_wndProgBar.MoveWindow(&rc,FALSE);}      
    CProgStatusBar::OnSize 负责移动进度指示器到你期望的位置:例子程序是把它放在了状态栏的第一个窗格,这个窗格通常用来显示程序的“就绪”信息和命令提示信息。注意这里不论进度指示器时处于可见状态还是隐藏状态,MoveWindow都照样起作用——所以即便是进度指示器处于隐藏状态,其窗口大小同样是可调的。
    说完窗口大小的调整,下面我们来看看进度指示器的显示,进度指示器状态的显示在CProgStatusBar::OnProgress中完成。它有一个类型为UINT的入口参数:参数值的范围从0到100,表示进度百分比,0表示进度没开始,100表示全部完成。如果这个参数的值大于0,则OnProgress显示进度控制并设置指示器的位置;如果参数值等于0,则 OnProgress隐藏进度控制。
    虽然我们常常都把子窗口控制放在父窗口能绘制的区域的最上面,但这样做在绘制方面是有一定风险的。在你隐藏/显示进度控制时尤其如此,你会发现有两个问题:第一,因为进度指示器显示在状态栏的第一个窗格位置,所以如果指示器显示时已经显示有状态信息,那么进度指示器和状态信息文本就会有冲突,相互干扰。如图二所示。之所以会这样,是因为进度控制假设其绘制背景是干净的,并且只绘制进度控制的着色部分。解决这个问题最简单的方法是调用CStatusBar::SetWindowText(NULL)函数在显示进度指示器之前打扫一下环境卫生,清除以前的文本。对于状态栏来说,SetWindowText函数的作用是设置状态栏第一个窗格的文本。


展开更多 50%)
分享

猜你喜欢

如何在状态栏中实现进度指示器控制

C语言教程 C语言函数
如何在状态栏中实现进度指示器控制

VC技巧:在程序的状态栏中实现进度条

编程语言 网络编程
VC技巧:在程序的状态栏中实现进度条

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

安卓平式栏指示器怎么用?

Android
安卓平式栏指示器怎么用?

利用Delphi实现系统状态栏图标

编程语言 网络编程
利用Delphi实现系统状态栏图标

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Access 2007 状态栏

编程语言 网络编程
Access 2007 状态栏

Access 2007状态栏

编程语言 网络编程
Access 2007状态栏

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

设计高手进阶技巧:用记事本编辑网页

设计高手进阶技巧:用记事本编辑网页

深入浅出 CPropertySheet

深入浅出 CPropertySheet
下拉加载更多内容 ↓