设为首页 加入收藏

TOP

滚动条控件(模式对话框+后台线程处理) (一)
2014-11-23 20:17:47 】 浏览:643
Tags:滚动 控件 模式 对话 后台 线程 处理

有时候,在用户处理大量数据,或是在网络通信过程中,希望自己的主线程阻塞,等待该过程完成后,再继续执行,但同时由于该处理过程耗时较长,会让用户体验下降。这时候我们会想到使用一个滚动条来通知用户当前程序的执行进度,防止用户以为程序长时间不动,造成的误认为程序已死,强制关闭。

这时候最简单的一个做法就是,制作一个模式对话框,然后在该对话框中执行一个线程,将用户需要执行的操作放在该线程中来执行。在程序中,创建自己的一个对话框资源,添加滚动条,以及相应的Text模块说明进度在执行的操作。这时,最大的问题在于,怎么让滚动条模态阻塞后,执行数据处理部分的线程代码。

这时候,我的解决办法是采用观察者模式,创建一个观察者类,提供一个CallBack的方法。在进度条对话框中提供SetCallBack(CObserver*)的方法设置观察者对象。这样在需要处理数据的类中,就可以继承CallBack的方法,然后所有的耗时处理过程,都放在那里面执行。然后在进度条对话框中创建的线程中,调用观察者的CallBack方法。好吧,还是直接上源码吧。


[cpp] // DlgProcessBar.cpp : implementation file
//

#include "stdafx.h"
#include "DlgProcessBar.h"
#include "process.h"
#include "../Observer.h"
// CDlgProcessBar dialog
IMPLEMENT_DYNAMIC(CDlgProcessBar, CDialog)

CDlgProcessBar::CDlgProcessBar(CWnd* pParent /*=NULL*/)
: CDialog(CDlgProcessBar::IDD, pParent)
{
ob = NULL;
m_hThread = NULL;
}

CDlgProcessBar::~CDlgProcessBar()
{
ob = NULL;
if (NULL != m_hThread)
{
WaitForSingleObject(m_hThread,INFINITE);
m_hThread = NULL;
}
}

void CDlgProcessBar::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS, m_ProcessCtl);
DDX_Control(pDX, IDC_STATIC_NOTE, m_StaticCtl);
}


BEGIN_MESSAGE_MAP(CDlgProcessBar, CDialog)
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()


// CDlgProcessBar message handlers

unsigned __stdcall CDlgProcessBar::ThreadProc(void *pArgParam)
{
TRACE("执行回调函数\r\n");
if (NULL == pArgParam)
{
TRACE("请设置线程参数\r\n");
_endthreadex(0);
}
CDlgProcessBar *dlg = (CDlgProcessBar *)pArgParam;
if (NULL == dlg->ob)
{
TRACE("请设置观察者\r\n");
_endthreadex(0);
}
TRACE(L"Call CallBack Function\r\n");
dlg->ob->CallbackFunc();
TRACE(L"End CallBack Function\r\n");
if (NULL != dlg->GetSafeHwnd())
{
TRACE(L"Post Message\r\n");
dlg->PostMessage(WM_COMMAND,
MAKEWPARAM(IDOK,BN_CLICKED),(LPARAM)dlg->GetSafeHwnd());
}
return 0;
}
BOOL CDlgProcessBar::SetCallBack(CObserver *ob)
{
if (NULL == ob)
{
TRACE("设置观察者失败");
return FALSE;
}
this->ob = ob;
return TRUE;
}
BOOL CDlgProcessBar::SetNotice(const CString ice /* = L"正在处理..." */,
const COLORREF &color /* = RGB */)
{
m_TextColor = color;
m_StaticCtl.SetWindowText(notice);
RedrawWindow(); //
return TRUE;
}
BOOL CDlgProcessBar::InitProcessBar(const int &range)
{

m_ProcessCtl.SetRange(0,range);
return TRUE;
}
BOOL CDlgProcessBar::SetProcessBar(const int &inc)
{
int iCurPos = m_ProcessCtl.GetPos();
m_ProcessCtl.SetPos(iCurPos + inc);
return TRUE;
}
HBRUSH CDlgProcessBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
switch (nCtlColor)
{
case CTLCOLOR_STATIC:
pDC->SetTextColor(m_TextColor);
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
default:
return CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
}
}
BOOL CDlgProcessBar::OnInitDialog()
{
CDialog::OnInitDialog();
m_TextColor = RGB(255,0,0);
m_hThread = NULL;
m_threadID = 0;
if (NULL == ob)
{
TRACE("观察者设置失败");
return FALSE;

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇在VC中动态加载ODBC的方法 下一篇VC各种链接错的解决办法

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目