windows之MFC进度条
创建UI线程
-
创建线程类
在vsstudio2019中按快捷键
ctrl+shift+x
弹出类向导, 在类向导中添加MFC类, 选择父类为CWinThread
。定义类名称点击确定即可。 -
关联该UI线程对应的对话框
BOOL CProgressThread::InitInstance() { CProgressDlg dlgprogress; m_pMainWnd = &dlgprogress; dlgprogress.DoModal(); return TRUE; }
-
定义线程处理消息及函数
在头文件中定义线程处理消息宏, 需要基于
WM_USER
加上自定义值。如:#define WM_THREAD_MESSAGES WM_USER + 8
添加对应的消息处理函数:
// 头文件中声明 void OnThreadMessages(WPARAM wParam, LPARAM lParam); // cpp文件中建立消息关联 BEGIN_MESSAGE_MAP(CProgressThread, CWinThread) ON_THREAD_MESSAGE(WM_THREAD_MESSAGES, &CProgressThread::OnThreadMessages) END_MESSAGE_MAP() void CProgressThread::OnThreadMessages(WPARAM wParam, LPARAM lParam) { CProgressDlg* dlgprogress = ((CProgressDlg*)GetMainWnd()); const int flag = (int)wParam; switch (flag) { case 0: dlgprogress->EndDialog(IDCANCEL); break; case 1: { const CString tips = *(CString*)lParam; dlgprogress->SetTips(tips); } break; case 2: break; default: break; } }
线程消息处理函数中处理进度条进度位置及信息提示, 可自定义
wParam
及lParam
来实现进度、提示传递。
创建关联的对话框
创建一个普通对话框, 添加信息提示控件CStatic
及进度条控件CProgressCtrl
, 设置进度条控件为来回滚动形式而非进度递增新式。这样就不用传递进度信息了。
m_progress_ctrl.SetMarquee(TRUE, 30);
要实现来回滚动的效果需要添加启用通用控件声明, 否则滚动条将不会呈现预期效果
:
#if defined _M_IX86
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
封装对外接口
封装对外接口调用UI线程, 隐藏内部进度条实现。
class Progress
{
public:
Progress();
~Progress();
void Start();
void End();
void UpdateTips(const CString& tips);
private:
struct Impl;
Impl* impl_;
};
在以上声明的Start()
接口中创建UI线程:
void Progress::Start()
{
impl_->thread = AfxBeginThread(RUNTIME_CLASS(CProgressThread));
}
其他接口实现如下:
void Progress::End()
{
impl_->thread->PostThreadMessage(WM_THREAD_MESSAGES, (WPARAM)0, (LPARAM)0);
}
void Progress::UpdateTips(const CString& tips)
{
impl_->tips = tips;
impl_->thread->PostThreadMessage(WM_THREAD_MESSAGES, (WPARAM)1, (LPARAM)&impl_->tips);
}