相关函数

AfxBeginThread

CWinThread* AfxBeginThread(
   AFX_THREADPROC pfnThreadProc,
   LPVOID pParam,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
CWinThread* AfxBeginThread(
   CRuntimeClass* pThreadClass,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
  • pfnThreadProc
    指向工作线程的控制函数,不能为NULL。函数声明如下

    UINT __cdecl MyControllingFunction( LPVOID pParam );

  • pThreadClass
    从CWinThread派生的对象的RUNTIME_CLASS

  • pParam
    要传递给控制函数的参数,桶pfnThreadProc中函数的形参。

  • nPriority
    优先级,见 SetThreadPriority

  • nStackSize
    指定新线程堆栈的大小(以字节为单位)。如果为0,则堆栈大小默认为与创建线程相同大小的堆栈。

  • dwCreateFlags
    指定控制线程创建的附加标志。此标志可以包含以下两个值之一:

    • CREATE_SUSPENDED   以1的挂起计数启动线程。如果要在线程开始运行之前初始化CWinThread对象的任何成员数据,如m_bAutoDelete或派生类的任何成员,请使用CREATE_SSUSPENDED。初始化完成后,使用CWinThread::ResumeThread启动线程运行。在调用CWinThread::ResumeThread之前,该线程不会执行。

    • 0   创建后立即启动线程。

  • lpSecurityAttrs
    指向指定线程安全属性的SECURITY_ATTRIBUTES结构。如果为NULL,则将使用与创建线程相同的安全属性。 SECURITY_ATTRIBUTES

Return Value

指向新创建的线程对象的指针,如果发生故障,则为NULL。

CWinThread 类

名称描述
CWinThread::CreateThread开始执行 CWinThread 对象。
CWinThread::ExitInstance替代以在线程终止时清理。
CWinThread::GetMainWnd检索指向线程的主窗口的指针。
CWinThread::GetThreadPriority获取当前线程的优先级。
CWinThread::InitInstance替代以执行线程实例初始化。
CWinThread::IsIdleMessage检查是否有特殊消息。
CWinThread::OnIdle替代以执行特定于线程的空闲时间处理。
CWinThread::PostThreadMessage将消息发布到另一个 CWinThread 对象。
CWinThread::PreTranslateMessage在消息调度到 Windows 函数 TranslateMessage 和 DispatchMessage 之前筛选消息。
CWinThread::ProcessMessageFilter在某些消息到达应用程序之前截获这些消息。
CWinThread::ProcessWndProcException截获由线程的消息和命令处理程序引发的所有未经处理的异常。
CWinThread::PumpMessage包含线程的消息循环。
CWinThread::ResumeThread递减线程的挂起计数。
CWinThread::Run具有消息泵的线程的控制函数。 替代以自定义默认消息循环。
CWinThread::SetThreadPriority设置当前线程的优先级。
CWinThread::SuspendThread递增线程的挂起计数。

AfxEndThread

void AFXAPI AfxEndThread(
   UINT nExitCode,
   BOOL bDelete = TRUE
);

nExitCode:指定线程的退出代码。

bDelete:shif从内存中删除线程对象。

必须从要终止的线程内调用。


范例

1新建给予对话框的MFC项目

2添加菜单

3添加变量并初始化

	m_pThread1 = nullptr;//线程指针1
	m_pThread2 = nullptr;;//线程指针2
	m_bSuspend1 = false;//线程1挂起标志
	m_bSuspend2 = false;//线程2挂起标志
	m_bEnable1 = true;//线程1有效性
	m_bEnable2 = true;//线程2有效性

	CWinThread* m_pThread1;//线程指针1
	CWinThread* m_pThread2;//线程指针2
	bool m_bSuspend1;//线程1挂起标志
	bool m_bSuspend2;//线程2挂起标志
	bool m_bEnable1;//线程1有效性
	bool m_bEnable2;//线程2有效性

volatile bool bExit1 = false;
volatile bool bExit2 = false;

4添加线程

UINT MyThread1(LPVOID param)
{
	CMFCApplDlg* pMainWnd = (CMFCApplDlg*)AfxGetMainWnd();//获取应用程序对象的m_pMainWnd
	if (param != 0)
	{
		AfxEndThread(2);//结束线程
	}
	bExit1 = false;//
	CSliderCtrl* pSilder = (CSliderCtrl*)pMainWnd->GetDlgItem(IDC_SLIDER_THREAD1);//通过ID获取CSliderCtrl
	pSilder->SetRange(0, 500);//设置范围
	pSilder->SetPos(0);//设置滑块位置
	int pos = pSilder->GetPos();//获取滑块位置
	while (pos < 500 && !bExit1)
	{
		pSilder->SetPos(pos);//设置滑块位置
		pos++;
		Sleep(200);
	}
	return 0;
}
UINT MyThread2(LPVOID param)
{
	CMFCApplDlg* pMainWnd = (CMFCApplDlg*)AfxGetMainWnd();//获取应用程序对象的m_pMainWnd
	if (param != 0)
	{
		AfxEndThread(3);//结束线程
	}
	bExit1 = false;
	CProgressCtrl* pProgress = (CProgressCtrl*)pMainWnd->GetDlgItem(IDC_PROGRESS_THREAD2);//通过ID获取CProgressCtrl
	pProgress->SetRange(0, 500);//设置范围
	pProgress->SetPos(0);//设置位置
	int pos = pProgress->GetPos();//获取位置
	while (pos < 500 && !bExit2)
	{
		pProgress->OffsetPos(2);//设置偏移
		pos = pProgress->GetPos();//获取位置
		Sleep(200);
	}
	return 0;
}

5添加菜单消息处理

如对启动线程1和启动线程2添加UPDATE_COMMAND_UI消息处理函数

void CMFCApplDlg::OnUpdateThread1(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_bEnable1);//启用或禁用此命令的用户界面项。
}
void CMFCApplDlg::OnUpdateThread2(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_bEnable2);//启用或禁用此命令的用户界面项。
}

对所有菜单添加命令消息处理函数

void CMFCApplDlg::OnThread1()
{
	m_pThread1 = AfxBeginThread(MyThread1, 0);//启动MyThread1,传递参数0
	m_bEnable1 = false;
}
void CMFCApplDlg::OnThread2()
{
	m_pThread2 = AfxBeginThread(MyThread2, 0);//启动MyThread2,传递参数0
	m_bEnable2 = false;
}
void CMFCApplDlg::OnSuspendThread1()
{
	//线程存在,且线程未挂起
	if (m_pThread1 && !m_bSuspend1)
	{
		m_pThread1->SuspendThread();//挂起线程
		m_bSuspend1 = true;
	}
}
void CMFCApplDlg::OnSuspendThread2()
{
	//线程存在,且线程未挂起
	if (m_pThread2 && !m_bSuspend2)
	{
		m_pThread2->SuspendThread();//挂起线程
		m_bSuspend2 = true;
	}
}
void CMFCApplDlg::OnResumeThread1()
{
	//线程存在,且线程挂起
	if (m_pThread1 && m_bSuspend1)
	{
		m_pThread1->ResumeThread();//唤醒线程
		m_bSuspend1 = false;
	}
}
void CMFCApplDlg::OnResumeThread2()
{
	//线程存在,且线程挂起
	if (m_pThread2 && m_bSuspend2)
	{
		m_pThread2->ResumeThread();//唤醒线程
		m_bSuspend2 = false;
	}
}
void CMFCApplDlg::OnPriorityThread1()
{
	int prior;
	//线程存在
	if (m_pThread1 && !bExit1)
	{
		prior = m_pThread1->GetThreadPriority();
		if (prior == THREAD_PRIORITY_NORMAL )
		{
			m_pThread1->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
			AfxMessageBox(L"线程1的优先级提升1级", MB_OK);
		}
		else
		{
			m_pThread1->SetThreadPriority(THREAD_PRIORITY_NORMAL);
			AfxMessageBox(L"线程1的优先级降低1级", MB_OK);
		}
	}
}
void CMFCApplDlg::OnPriorityThread2()
{
	int prior;
	//线程存在
	if (m_pThread2 && !bExit2)
	{
		prior = m_pThread2->GetThreadPriority();
		if (prior == THREAD_PRIORITY_NORMAL)
		{
			m_pThread2->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
			AfxMessageBox(L"线程2的优先级提升1级", MB_OK);
		}
		else
		{
			m_pThread2->SetThreadPriority(THREAD_PRIORITY_NORMAL);
			AfxMessageBox(L"线程2的优先级降低1级", MB_OK);
		}
	}
}
void CMFCApplDlg::OnStopThread1()
{
	bExit1 = true;
	m_bEnable1 = true;
}
void CMFCApplDlg::OnStopThread2()
{
	bExit2 = true;
	m_bEnable2 = true;
}

6添加关于

添加消息处理

void CMFCApplDlg::On32788()
{
	CAboutDlg dlg{};
	dlg.DoModal();
}

7运行