MFC用户界面线程初学小结

来自:https://blog.csdn.net/fengsizhao/article/details/86431127

 

MFC用户界面线程初学小结

一、MFC的线程分类
不同于Win32 API不区分线程的类型,MFC中将线程分为两种类型:用户界面线程(users-interface threads)和辅助线程(即工作线程,worker threads)两种。用户界面线程用来处理需要用户输入、用户产生的事件和消息的响应,辅助线程用来处理完成不需要用户输入的任务。

参考网址:
https://msdn.microsoft.com/zh-cn/library/975t8ks0(v=vs.120).aspx

二、创建用户界面线程
1、创建一个继承于CWinThread的类
要使用宏定义DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE来实现这个新创建的类,并且至少需要重写以下两个函数:InitInstance()和ExitInstance()。
InitInstance()函数用于初始化这个用户界面线程,在这个函数中,可以创建对一个你所需要的对话框。执行成功时返回非零值,否则返回0。
示例如下(本文所有示例使用VS2013):

BOOL CMyDlgThread::InitInstance()
{
	// TODO:    在此执行任意逐线程初始化
	CSonDlg* pSonDlg = new CSonDlg;//创建一个非模态窗口
	if (NULL != pSonDlg)
	{
		m_pSonDlg = pSonDlg;
		m_pSonDlg->Create(IDD_DIALOG1, NULL);
		m_pSonDlg->SetWindowTextW(_T("Dialog in MyDlgThread."));
		m_pSonDlg->ShowWindow(SW_SHOW);
		m_pSonDlg->UpdateWindow();//马上刷新窗口
	}
	else
	{
		return FALSE;//结束线程
	}
	m_pMainWnd = NULL;//为主窗口赋值

	return TRUE;
}

 

ExitInstance()函数会在退出线程或者InitInstance()函数执行失败时被调用,在这个函数中可以对自行创建的对象等进行清理,清理完后,需要调用基类中的该函数。线程终止时,如果CWinThread::m_bAutoDelete的值为TRUE,会自动删除创建的CWinThread对象,m_bAutoDelete默认值即为TRUE。

 

int CMyDlgThread::ExitInstance()
{
	// TODO:    在此执行任意逐线程清理
	if (NULL != m_pSonDlg)//删除创建的对象
	{
		m_pSonDlg->DestroyWindow();
		m_pSonDlg = NULL;
	}

	return CWinThread::ExitInstance();//调用基类中的该函数
}

 

 

2、使用AfxBeginThread()函数创建用户界面线程
AfxBeginThread()函数有两种重载类型,一种只能创建辅助线程,另一种可以创建用户界面线程和辅助线程。使用的类型如下:

CWinThread* AfxBeginThread( 
   CRuntimeClass* pThreadClass, 
   int nPriority = THREAD_PRIORITY_NORMAL, 
   UINT nStackSize = 0, 
   DWORD dwCreateFlags = 0, 
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL  
);

 

入参含义如下所示:

  1. pThreadClass:从CWinThread类中派生的对象的RUNTIME_CLASS
  2. nPriority:线程优先级
  3. nStackSize:新线程堆栈的大小,为0时默认与创建线程的堆栈大小相同
  4. dwCreateFlags:控制线程创建的标志,创建用户界面线程需要设置为CREATE_SUSPENDED
  5. lpSecurityAttrs:安全性设置,为NULL时将与创建线程安全性相同

创建成功返回新线程对象的指针,失败返回NULL。

3、使用ResumeThread()函数调用用户界面线程
由于创建用户界面线程时使用了CREATE_SUSPENDED标志,因此需要使用ResumeThread()函数来调用创建的用户界面线程。
示例如下:

CWinThread* pThread = AfxBeginThread(RUNTIME_CLASS(CMyDlgThread), NULL, NULL, CREATE_SUSPENDED);
if (NULL != pThread)
{
	pThread->ResumeThread();//调用线程
}

 

 

参考网址:
https://msdn.microsoft.com/zh-cn/library/b807sta6(v=vs.120).aspx
https://msdn.microsoft.com/zh-cn/library/s3w9x78e(v=vs.120).aspx

三、退出创建的用户界面线程
在用户界面线程中调用PostQuitMessage()函数即可,入参是线程的退出代码,0表示成功完成任务。
示例如下:

void CSonDlg::OnCancel()
{
	// TODO:  在此添加专用代码和/或调用基类
	PostQuitMessage(0);
}

 

参考网址:
https://msdn.microsoft.com/zh-cn/library/2s21xzfe(v=vs.120).aspx

四、创建用户界面线程时,传入指定参数
为创建的界面线程类添加成员变量,用来存储参数,如下所示:

class CMyDlgThread : public CWinThread
{
	DECLARE_DYNCREATE(CMyDlgThread)

protected:
	CMyDlgThread();           // 动态创建所使用的受保护的构造函数
	virtual ~CMyDlgThread();

public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

private:
	CSonDlg* m_pSonDlg;

public:
	CString m_strTemp; //添加成员变量,存储传入参数

protected:
	DECLARE_MESSAGE_MAP()
};

 

 

用户界面线程创建后,先为添加的成员变量赋值再调用该线程,如下所示:

CWinThread* pThread = AfxBeginThread(RUNTIME_CLASS(CMyDlgThread), NULL, NULL, CREATE_SUSPENDED);
if (NULL != pThread)
{
	((CMyDlgThread*)pThread)->m_strTemp = _T("TestParam");//为传入参数赋值
	pThread->ResumeThread();//调用线程
}

 

参考网址:
https://blog.csdn.net/sniper_bing/article/details/5002191

posted @ 2020-10-09 16:21  宇宙之外  阅读(356)  评论(0编辑  收藏  举报