进度条Dialog线程

1.创建相应进度条Dialog

#include "stdafx.h"
#include "ReadTiff.h"
#include "ProgressDlg.h"


// CProgressDlg 对话框

UINT ThreadFunc(LPVOID lpParam)//线程函数
{
CProgressCtrl* pInfo=(CProgressCtrl*)lpParam;//线程函数参数
for(int pos=0;pos<30;pos++)
{
pInfo->SetPos(pos);//设置进度条进度
Sleep(50);//停止0.5秒
if(pos>=29)
{
pos=0;
}
}
return 0;
}
IMPLEMENT_DYNAMIC(CProgressDlg, CDialog)

。。。。。。。。。。。。。。。。


// CProgressDlg 消息处理程序

BOOL CProgressDlg::On<wbr>InitDialog()<br> {<br> CDialog::On<wbr>InitDialog();</wbr></wbr>

// TODO: 在此添加额外的初始化
m_progress.SetRange(0,30);//设置进度条范围

return TRUE; // return TRUE unless you set the focus to a control
}

void CProgressDlg::On<wbr>Paint()<br> {<br> CPaintDC dc(this); // device context for painting<br> //调用线程的处理函数<br> CWinThread* pThread=AfxBeginThread(ThreadFunc,&amp;m_progress);<br> }</wbr>

2.创建线程类

IMPLEMENT_DYNCREATE(CProgress, CWinThread)

。。。。。。。。

BOOL CProgress::InitInstance()
{
CProgressDlg *pDlg=new CProgressDlg

pDlg->Create(IDD_DIALOG_PROGRESS);//创建非模态对话框
pDlg->ShowWindow(SW_SHOW);//显示对话
//m_pMainWnd = pDlg;//将对话框设为主窗口
return TRUE;
}

int CProgress::ExitInstance()
{
return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CProgress, CWinThread)
END_MESSAGE_MAP()
}

3.在主程序中调用执行

CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CProgress),THREAD_PRIORITY_HIGHEST,0,NULL);

4.注:线程产生的dialog默认是主视图作为其父窗口

2.在已经开始执行某个线程时难于启动现在的线程

http://anwj336.blog.163.com/blog/static/894152092009624112340846/

http://apps.hi.baidu.com/share/detail/34609735

 

 

 

昨天一个同学问到为何界面上进度条被碰一下后就不动了。最直接的原因就是由于她采用的是单线程。所以手工写了个小例子来解决问题。

 

我直接采用C++类模板来实现这个过程。

1)首先我新建一个.h文件,不需要source文件,定义为命名为runsss.h,将该类改为模板类,然后只要在其中只写一个函数命名为insar(),这便是主函数,我们的大程序都可写在里面

.h文件的全部代码如下,很简单。

// runsss.h: interface for the runsss class.

template<class T1> class runsss;

template<class T1>

class runsss

{

public:

runsss();

virtual ~runsss();

BOOL Insar(){

for(int i=0;i<100000000.0;i++)

{

if(i%1000000==0)

g = (i/1000000);////这里的g就是进度,setpos里的参数值。

}

return true;

};

};

template<class T1>

runsss<T1>::runsss()

{}

 

template<class T1>

runsss< T1>::~runsss()

{}

#endif // !defined(AFX_RUNSSS_H__1B2FC4B5_B84E_419E_844C_1942B78A8DC0__INCLUDED_

(2)界面类

 

 

命名为:m_dia类。

建立’’执行的响应函数

建立timer事件,建立intital dialog事件。

进度条控件命名为:CProgressCtrlm_progress;

(1)m_dia.cpp外部声明模板类

runsss<UINT>run ;之后便可以在m_dia.cpp的任何地方调用runsss中的函数。

然后建调用线程的接口函数。

UINTInsars(LPVOID pParam)

{

return run.Insar();//这里就运行了类模板的函数了。

}

 

然后在执行的响应函数里建一个线程。来调用接口函数。

void m_dia::On<wbr>Button1()</wbr>

{

// TODO: Add your control notification handler co<wbr>de here</wbr>

AfxBeginThread(Insars, GetSafeHwnd(), THREAD_PRIORITY_NORMAL);//开辟新线程,//这样可以和界面线程分开。。。

}

 

最后在timer里设置进度条更新

void m_dia::On<wbr>Timer(UINT nIDEvent)</wbr>

{

// TODO: Add your message handler co<wbr>de here and/or call default</wbr>

m_progress.SetPos(g);

m_progress.UpdateWindow();

CDialog::On<wbr>Timer(nIDEvent);</wbr>

}

 

至于进度条的初始距离,以及步长等的设置,在initial对话框里进行。然后就OK了。

BOOL m_dia::On<wbr>InitDialog()</wbr>

{

CDialog::On<wbr>InitDialog();</wbr>

// TODO: Add extra initialization here

if(timer<0)

timer = SetTimer(1,100,NULL);

m_progress.SetRange(1,100);

m_progress.SetStep(5);

return TRUE;// return TRUE unless you set the focus to a control

}

 

void m_dia::On<wbr>Cancel()</wbr>

{

// TODO: Add extra cleanup here

if(timer>0)

KillTimer(1);

CDialog::On<wbr>Cancel();</wbr>

}

 

运行结果:

 

 

运行过程中,随意拖动对话框时,进度条不会停止。。

 

进度条Dialog线程 - 旺齐齐 - 宇宙的奇点

 

进度条Dialog线程 - 旺齐齐 - 宇宙的奇点
VC中进度条实时显示的解决方法
 

当我们在处理大程序时,常常需要耗很长时间,为了不让用户错误的认为系统已经死机,我们要给程序添加进度条,但是大家知道如果就直接添加进度条,并在程序里面控制它的进度,往往得到的结果是程序仍然像死机状态,直到处理完毕才显示进度条进度为100%,中间的过程看不到了,那么怎么办呢,是为什么呢?

原因是我们处理大程序和进度条显示是在同一个线程中进行的,这样往往因为处理大程序导致界面无法实时更新。

解决办法就是把处理大程序的这段逻辑让一个单独的线程在处理,并利用postmessage或sendmessage给主界面发送消息,让主界面去更新。

具体代码实现如下:

首先,定义一个关联事件:

#define WM_UPDATEDATA WM_USER + 1999 //定义事件

BEGIN_MESSAGE_MAP(CBinLogAnalyse, CDialog)
ON_MESSAGE(WM_UPDATEDATA, &CBinLogAnalyse::OnUpdateData) //让事件关联程序
END_MESSAGE_MAP()

第二,实现关联程序(返回类型一定要是LRESULT):

LRESULT CBinLogAnalyse::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
int iTmp = (int)wParam;
m_process.SetPos(iTmp);//设置进度条的值
UpdateData(false);//实时更新主界面
return 0;
}

第三,创建一个独立的线程处理大程序


m_pMyThread = AfxBeginThread(MyThread, this);//MyThread为该大程序处理的入口函数,this为入口函数的参数
m_pMyThread = NULL;

第四,实现大程序逻辑

UINT CBinLogAnalyse::MyThread(LPVOID pParam)//注意返回类型为UINT
{
CBinLogAnalyse *pDlg = (CBinLogAnalyse *)pParam;

//这里添加计算过程
char sRtnMsgBuf[MAXPATH];
memset(sRtnMsgBuf, 0, MAXPATH);
int iRec = pDlg->ProcessLogFile(pDlg->m_sSaveFile, sRtnMsgBuf, MAXPATH);//调用具体处理大程序的逻辑函数
return 0;
}

第五,向主线程发送消息让进度条实时更新

int CBinLogAnalyse::ProcessLogFile(const char *pSaveFile, char *pRtnMsgBuf, int ibufLen)
{
if (NULL == pSaveFile)
{
return -1;
}

。。。。

while(。。。)

{

。。。。

//调用进度条实时更新函数实时更新进度条

setProcess(value);

}

}

//进度条实时更新函数

void CBinLogAnalyse::setProcess(int value)
{
SendMessage(WM_UPDATEDATA, value);//向主线程发送消息更新进度条
}

 

转载自:http://zhou24388.blog.163.com/blog/static/59746327201172891943156/?suggestedreading&wumii

你可能感兴趣的:(dialog)