用一个对话框显示后台线程进度的实现

时间:2021-12-25 18:21:35

功能描述:在后台有一个线程处理数据,现在需要在主线程弹出对话框显示线程的进度,线程处理完后会关闭对话框,在对话框上可以通过单击“取消”按钮结束线程。

功能实现:

1.主线程中的步骤:

(1)在主线程新建一个对话框。

CDlgWait dlgWait;// 新建对话框

(2)创建一个线程,将对话框作为参数传递进去(此处传递一个全局的结构体,结构体中保存dlgWait的地址)。

m_exportPara.pdlgWait = &dlgWait;// 保存对话框地址

HANDLE handle = ::CreateThread(NULL, 0, OnExportMapSpotExcel, &m_exportPara, 0, NULL);// 新建线程

(3)弹出对话框。

dlgWait.DoModal();// 弹出对话框

2.CDlgWait对话框中的实现:

(1)CDlgWait中可以添加一个进度条,提供进度条接口,在线程中通过dlgWait的地址显示进度。

(2)CDlgWait中设置一个BOOL变量,来控制是否关闭线程。

BOOL m_bCloseHandle;// 是否关闭线程

(3)”取消“按钮的实现,在取消按钮中设置m_bCloseHandle为True就行,不退出对话框。因为如果在此时退出对话框,无法判断线程是否已经退出(可能对话框关闭了,但是线程还在后台运行)。而如果使用WaitForSingleObject,则会阻塞主线程。

m_bCloseHandle = TRUE;

(4)CDlgWait中添加EBM_END_WAIT消息,在该消息中退出对话框。

ON_MESSAGE(EBM_END_WAIT, EndWait)

LRESULT CDlgWait::EndWait( WPARAM wParam, LPARAM lParam )
{
OnCancel();
return 0;
}

3.输出线程的实现:

(1)输出线程中通过判断dlgWait的标志,如果为True则关闭对话框,并且退出线程。每次在线程关闭之前,关闭对话框。

if (para->pdlgWait->GetBCloseHandle())// 如果用户点击“取消”关闭线程
{
// 关闭对话框,直接退出
para->pdlgWait->PostMessage(EBM_END_WAIT);// 关闭等待界面
return 0;
}

这种方法可以保证用户取消线程时,线程是正常退出(通过Return退出),用户可以在线程退出前释放资源。对话框弹出时开始线程,对话框关闭时关闭线程,对话框和线程是同时出现和消失的。