功能描述:在后台有一个线程处理数据,现在需要在主线程弹出对话框显示线程的进度,线程处理完后会关闭对话框,在对话框上可以通过单击“取消”按钮结束线程。
功能实现:
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退出),用户可以在线程退出前释放资源。对话框弹出时开始线程,对话框关闭时关闭线程,对话框和线程是同时出现和消失的。