网络编程(43)—— windows平台下创建线程的四种方法(二)之用户界面线程

四、AfxBeginThread

        在介绍使用AfxBeginThread进行多线程编程之前,我们先介绍下MFC中两种线程的概念,这也是在MFC编程中无法绕过的两种类型的线程 —— 用户界面线程和工作者线程。

4.1 用户界面线程

        用户界面线程,顾名思义,它是一种可以管理UI界面的线程。它含有自己的消息循环,可以处理UI界面的各种消息。最常见的用户界面线程,就是MFC中主界面所在的主线程。用户界面线程可以用AfxBeginThread创建,函数原型如下:
CWinThread* AfxBeginThread(
   CRuntimeClass* pThreadClass,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 
);

pThreadClass —— 是CWinThread类的派生类的运行时。我们要创建用户界面线程,必须定义自己的CWinThread的派生类,并重载CWinThread::InitInstance()和

WinThread::ExitInstance()函数,在CWinThread::InitInstance()我们做一些界面资源的创建和显示操作,在WinThread::ExitInstance()中我们对资源进行回收。

nPriority —— 设置线程的优先级,如果是0,设置的所有线程的优先级都一样,常见的优先级设置项参考下表:

线程优先级等级 标志 优先级值


线程优先级等级

标志

优先级值

 

1

idle (最低)

THREAD_PRIORITY_IDLE

如果进程优先级为realtime则调整为16,其它情况为1

2

LOWEST 低

THREAD_PRIORITY_LOWEST

-2(在原有基础上-2)

3

BELOW 低于标准

THREAD_PRIORITY_BELOW_NORMAL

-1(在原有基础上-1)

4

NORMAL(标准)

THREAD_PRIORITY_NORMAL

不变(取进程优先级值)

5

ABOVE 高于标准

THREAD_PRIORITY_ABOVE_NORMAL

+1(在原有基础上+1)

6

HIGHEST (高)

THREAD_PRIORITY_HIGHEST

+2(在原有基础上+2)

7

CRITICAL(最高)

THREAD_PRIORITY_TIME_CRITICAL

如果进程优先级为realtime则调整为31,其它情况为15


nStackSize —— 为线程分配的调用堆栈大小,0为默认值。

dwCreateFlags —— 设置线程创建后的初始状态。0,创建后立即执行;CREATE_SUSPENDED宏,创建后被挂起。

lpSecurityAttrs —— 线程的安全属性,默认为NULL。

返回值 —— AfxBeginThread()返回的是一个CWinThread类型的指针,这是MFC中封装的一个线程类型。在MFC多线程编程中,关于线程的任何操作都是通过该类完成。

        介绍完创建用户界面线程的AfxBeginThread原型之后,我们通过一个例子按照步骤介绍该函数的用法。

步骤一 派生自己的CWinThread类。

        通过类向导,我们从CWinThread派生一个CUIThread类,用来作为用户界面线程。类中定义一个m_udlg成员变量,为我们自定义的对话框。
class CUIThread : public CWinThread
{
...
}

步骤二 创建自定义对话框

        我们创建一个对话框UIDlg,并在对话框上放置一个EditControl。


        然后设置一个定时器,并重载对话框的WM_TIME定时器消息处理函数,主要实现的效果是每隔1秒钟编辑框的数字会从0逐渐增大。

BOOL CMfctestDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	…
    SetTimer(1,1000,NULL);
}
void UIDlg::OnTimer(UINT_PTR nIDEvent)
{
	CString str;
	str.Format("%d",m_index++);
	this->GetDlgItem(IDC_EDIT1)->SetWindowText(str);

	CDialogEx::OnTimer(nIDEvent);
}

步骤三 为CWinThread的派生了添加对话框资源以及重载相关函数

        我们为CUIThread成员添加一个UIDlg类型的成员m_udlg,并重载InitInstance和ExitInstance函数:
BOOL CUIThread::InitInstance()
{
	m_udlg.Create(IDD_DIALOG1);//创建此ID号的对话框窗口
	m_udlg.ShowWindow(SW_SHOW);
	m_pMainWnd=&m_udlg;
	
	return TRUE;
}

int CUIThread::ExitInstance()
{
	m_udlg.DestroyWindow();
	return CWinThread::ExitInstance();
}

步骤四 在主程序中开启用户界面线程。

        我们在主程序界面添加一个按钮:



        然后在按钮的点击事件处理函数中进行用户界面线程的创建:
void CMfctestDlg::OnBnClickedOpen()
{
	AfxBeginThread(RUNTIME_CLASS(CUIThread));
}

        如果运行程序,并点击按钮就实现了我们预期的效果:


Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clonegit@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL45




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值