windows之MFC进度条

发布时间 2023-10-12 15:20:36作者: 汗牛充栋

windows之MFC进度条

创建UI线程

  1. 创建线程类

    在vsstudio2019中按快捷键ctrl+shift+x弹出类向导, 在类向导中添加MFC类, 选择父类为CWinThread。定义类名称点击确定即可。

  2. 关联该UI线程对应的对话框

    BOOL CProgressThread::InitInstance()
     {
         CProgressDlg dlgprogress;
         m_pMainWnd = &dlgprogress;
         dlgprogress.DoModal();
         return TRUE;
     }
    
  3. 定义线程处理消息及函数

    在头文件中定义线程处理消息宏, 需要基于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;
         }
     }
    

    线程消息处理函数中处理进度条进度位置及信息提示, 可自定义wParamlParam来实现进度、提示传递。

创建关联的对话框

创建一个普通对话框, 添加信息提示控件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);
}

最终效果

最终效果