VC_控件之进度条
- 格式:pdf
- 大小:252.58 KB
- 文档页数:34
virtual ~CProgStatusBar(); CProgressCtrl& GetProgressCtrl() { return m_wndProgBar; } void OnProgress(UINT pct); protected: CProgressCtrl m_wndProgBar; // the progress bar afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() DECLARE_DYNAMIC(CProgStatusBar) }; ///////////////////////////////////////////////////////////////////// //////// CprogStatusBar 类的实现文件; #include "StdAfx.h" #include "ProgBar.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(CProgStatusBar, CStatusBar) BEGIN_MESSAGE_MAP(CProgStatusBar, CStatusBar) ON_WM_CREATE() ON_WM_SIZE() END_MESSAGE_MAP() //////////////////////////////////////////////////////////////// CProgStatusBar::CProgStatusBar() {} CProgStatusBar::~CProgStatusBar() {} ////////////////////////////////////////创建状态条时也创建进程条 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; } ////////////////////////////////////////////////////使进程度条的尺寸 与状态条的尺寸同步变化; void CProgStatusBar::OnSize(UINT nType, int cx, int cy) {
类的二个重要成员函数: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,因为我们要实现的目标是仅仅当装载文件时进 度条才显现,其余时间内应用程序都隐藏它。 熟悉 Windows 编程 的人都清楚,无论何时,只要在某个窗口里添加子窗口,那 么一定要负责管理它的大小尺寸,也就是说,当父窗口大小改变后,子窗口的大 小也要跟着作相应的改 变。一般来说,这个工作由父窗口的 WM_SIZE 消息处理 函数 OnSize()来作,所以我们也要处理该类的 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 隐藏进度控制。 虽然子窗口控件通常都是放在父窗口能绘制的区域的最上面, 但这样做在绘制方 面是有一定风险的。 在 隐藏/显示进度控制时尤其如此, 这时候会出现两个问题: 第一, 因为进度指示器显示在状态栏的第一个窗格位置,所以如果进度条指示器 显示时已经显示有状态信 息,那么进度指示器和状态信息文本就会有冲突,相 互干扰。之所以会这样,是因为进度控制假设其绘制背景是干净的,并且只绘制 进度控制的着色部分。解决这个 问题最简单的方法是调用 CStatusB指示器之前打扫一下环境卫
vc 进度条控件(一)
2011-05-27 17:49:12| 分类: MFC | 标签: |字号大中小 订阅
方法 1: 单线程方式。 将你的任务分成多个部分,每运行一部分,就更新一下进度条。 这种方法就是很烦人。 方法 2: 双线程方式。 主线程负责完成你想要的工作。副线程负责更新进度条。 更新进度条可以按照计时方法,或者根据主线程完成任务的状态来更新。 因此,你的主线程在完成任务时,还得用一个临界区随时报告任务的完成状态。 方法 3: 双线程方式 主线程负责更新进度条,并且创建副线程完成任务的某部分工作。但这和单线程 很像。
生,清除以前的文本。 对 于状态栏来说,SetWindowText 函数的作用是设置状态栏第一个窗格的文本。 反之,当调用 OnProgress(0)清除进度控制时也存在类 似的问题, CProgStatusBar::OnProgress 隐藏进度控制后,状态栏第一个窗格该显示什么 信息呢?一般显示"就绪"或其它的提示信息。当应用程序不做任何事情时,MFC 程序总是在这个位置显示资源串 AFX_IDS_IDLEMESSAGE 表示的文本,其缺省值 为"就绪",当然读者朋友们可以在当前项目的 RC 文件中任意修改这个值,不管 怎样,在 MFC 程序的状态栏中显示"就绪"信息很容易,需要作的就是在 CProgStatusBar::OnProgress()函数中调用语句 GetParent()->PostMessage(WM_SETMESSAGESTRING,AFX_IDS_IDLEMESSAGE)向父 窗口 发送一个 WM_SETMESSAGESTRING 消息就可以了,需要注意的是,使用消息 WM_SETMESSAGESTRING 时必须包含它的定义文 件"afxpriv.h",否则程序会报告 编译错误。 上述 CprogStatusBar 类实现了状态栏中包含进度条控件, 该类的使用 方法很简 单,首先在应用程序的 CmainFrame 类中用 CProgStatusBar 代替 CStatusBar 声 明实例,然后在任何想要显示进度控制指 示的地方调用 CProgStatusBar::OnProgress。本例中定义了一个消息 MYWM_PROGRESS,它将进 度条当前的进度作为 WPARAM 参数传递到 CProgStatusBar::OnProgress () 函数。 经过上述处理,想要使用进度指示的任何对象 都可以通过发送一个消息到主框 架来调用状态栏进行进度条的显示。例如,在例子程序中,文档的 Serialize() 函数在加载文本文件时,利用 Sleep()函数仿真耗时加载,每隔 150 毫秒报告 一次进度状态。 如果你不想从文档发送 Windows 消息,可以用 MFC 的视图更新机 制来做。你可以发 明一个"暗示"代码以及一个小结构来保存进度百分比数据, 并通过向框架发送 MYWM_PROGRESS 消息调用暗示信息。这是从文档到视图/框架 传递进度 控制信息的最省事的方式。 二、编程步骤 1、 启动 Visual C++6.0,生成一个单文档应用程序 prgsbar,项目的视图类的 基类选择 CEdit 类; 2、 在程序的 Resource.h 文件中添加自定义消息的定义: #define MYWM_PROGRESS (WM_USER+1) 3、 在程序的主框架窗口 CMainFrame 类的头文件中声明 MYWM_PROGRESS 的消息 响应函数 afx_msg LRESULT OnProgress(WPARAM wp, LPARAM lp),在该类的实 现中添加消息映射 ON_MESSAGE(MYWM_PROGRESS,OnProgress); 4、 将 CMainFrame 类中的工具条对象改为 CProgStatusBar m_wndStatusBar; 5、 重载 CPrgsbarDoc::Serialize(CArchive& ar)函数,用来处理读取文件时 的进度条仿真; 6、 添加代码,编译运行程序。 三、程序代码 ////////////////////////////////////////////CprogStatusBar 类的头文 件; // Status bar with progress control. class CProgStatusBar : public CStatusBar { public: CProgStatusBar();