//根据线程句柄获取当前任务在列表视图控件中的位置
void
CMultiThreadDlg::FindItemPos(
HANDLE
hHandle,
int
&nPos, POSITION &pos,
bool
&bTerminate)
{
pos = m_hHandleList.GetHeadPosition();
//获取头节点位置
while
(pos != NULL)
{
//获取节点元素数据
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(pParam->hHandle == hHandle)
{
nPos = pParam->nPos;
bTerminate = pParam->bStop;
return
;
}
}
m_hHandleList.GetNext(pos);
}
nPos = -1;
}
//在删除项目后更新HandleList列表
void
CMultiThreadDlg::UpdateHandleList(
int
nPos)
{
POSITION pos = m_hHandleList.GetHeadPosition();
while
(pos != NULL)
{
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(pParam->nPos > nPos)
{
pParam->nPos--;
}
}
m_hHandleList.GetNext(pos);
}
}
//线程函数
DWORD
__stdcall TaskProc(
LPVOID
lpParameter)
{
CThreadParam param;
//定义线程参数
memcpy
(¶m, (CThreadParam *)lpParameter,
sizeof
(CThreadParam));
char
szCounter[10] = {0};
int
nPos = 0;
POSITION pos;
bool
bTerminate =
false
;
for
(
int
i=0; i<500; i++)
{
memset
(szCounter, 0, 10);
_itoa_s(i, szCounter, 10);
//获取当前位置对应列表视图中的项目位置
param.pDlg->FindItemPos(param.hHandle, nPos, pos, bTerminate);
if
(nPos != -1)
{
//在列表视图中设置计数
param.pDlg->m_listTask.SetItemText(nPos, 1, (CString)szCounter);
}
if
(bTerminate)
//如果线程被提前终止
{
goto
label;
}
Sleep(100);
//延时,演示任务进行中
}
label:
//线程结束后删除列表中的任务
//线程同步,不允许多个线程同时执行该操作
WaitForSingleObject(param.pDlg->m_hEvent, INFINITE);
//根据线程句柄查找项目
param.pDlg->FindItemPos(param.hHandle, nPos, pos, bTerminate);
if
(nPos != -1)
{
param.pDlg->m_listTask.DeleteItem(nPos);
//获取m_listTask链表中对应的节点数据
CThreadParam *pItem = (CThreadParam *)param.pDlg->m_hHandleList.GetAt(pos);
param.pDlg->m_hHandleList.RemoveAt(pos);
if
(pItem != NULL)
{
delete
pItem;
}
param.pDlg->UpdateHandleList(nPos);
}
SetEvent(param.pDlg->m_hEvent);
//将事件设置为有信号状态
if
(param.pDlg->m_listTask.GetItemCount() < 1)
{
if
(param.pDlg->m_bExitProcess)
{
exit
(0);
}
}
return
0;
}
//新任务
void
CMultiThreadDlg::OnBnClickedNewTask()
{
CThreadParam *pParam =
new
CThreadParam;
//定义一个线程参数
pParam->pDlg =
this
;
//关联对话框
int
nCount = m_listTask.GetItemCount();
int
nPos = m_listTask.InsertItem(nCount, _T(
"任务"
), 0);
CString strText;
strText.Format(_T(
"任务%d"
), nPos);
m_listTask.SetItemText(nPos, 0, strText);
m_listTask.SetItemText(nPos, 2, _T(
"进行中..."
));
pParam->nPos = nPos;
pParam->hHandle = CreateThread(NULL, 0, TaskProc, pParam, 0, NULL);
//创建线程
m_hHandleList.AddHead(pParam);
//将线程参数添加到列表中
}
//暂停
void
CMultiThreadDlg::OnBnClickedPause()
{
int
nSel = m_listTask.GetSelectionMark();
//获取用户选中的选项
if
(nSel != -1)
{
CString strState = m_listTask.GetItemText(nSel, 2);
if
(strState == _T(
"暂停"
))
{
return
;
}
POSITION pos = m_hHandleList.GetHeadPosition();
while
(pos != NULL)
{
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(pParam->nPos == nSel)
{
SuspendThread(pParam->hHandle);
//挂起线程
m_listTask.SetItemText(nSel, 2, _T(
"暂停"
));
return
;
}
}
m_hHandleList.GetNext(pos);
}
}
}
//继续
void
CMultiThreadDlg::OnBnClickedContinue()
{
int
nSel = m_listTask.GetSelectionMark();
if
(nSel != -1)
{
CString strState = m_listTask.GetItemText(nSel, 2);
if
(strState == _T(
"暂停"
))
{
POSITION pos = m_hHandleList.GetHeadPosition();
while
(pos != NULL)
{
//获取节点数据
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(pParam->nPos == nSel)
{
ResumeThread(pParam->hHandle);
//唤醒线程
m_listTask.SetItemText(nSel, 2, _T(
"进行中..."
));
return
;
}
}
m_hHandleList.GetNext(pos);
}
}
}
}
//终止
void
CMultiThreadDlg::OnBnClickedStop()
{
int
nSel = m_listTask.GetSelectionMark();
if
(nSel != -1)
{
POSITION pos = m_hHandleList.GetHeadPosition();
while
(pos != NULL)
{
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(pParam->nPos == nSel)
{
if
(!pParam->bStop)
{
pParam->bStop =
true
;
}
return
;
}
}
m_hHandleList.GetNext(pos);
}
}
}
//继续所有暂停的任务
void
CMultiThreadDlg::ContinueAllTask()
{
POSITION pos = m_hHandleList.GetHeadPosition();
while
(pos != NULL)
{
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(!pParam->bStop)
{
ResumeThread(pParam->hHandle);
//唤醒线程
}
}
m_hHandleList.GetNext(pos);
}
}
void
CMultiThreadDlg::OnCancel()
{
POSITION pos = m_hHandleList.GetHeadPosition();
if
(pos != NULL)
{
CDialogEx::OnCancel();
return
;
}
ContinueAllTask();
//恢复所有任务
m_bExitProcess = TRUE;
while
(pos != NULL)
{
CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
if
(pParam != NULL)
{
if
(!pParam->bStop)
{
pParam->bStop =
true
;
}
}
m_hHandleList.GetNext(pos);
}
CDialogEx::OnCancel();
}