AfxBeginthread() 工作线程和UI线程

本文详细介绍了MFC框架下UI线程和工作线程的区别,指出UI线程拥有消息队列并能响应各种消息,而工作线程通常不包含消息队列。UI线程通过消息循环处理消息,包括GetMessage、TranslateMessage和DispatchMessage等关键函数的作用。同时,文章还阐述了如何自定义消息处理和窗体过程。
摘要由CSDN通过智能技术生成

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
);
只有在使用MFC框架时才有UI线程和工作线程之分。
UI线程与工作线程的区别是操作系统为UI线程创建并维护了一个消息队列。
UI线程,能够响应操作系统的特定消息(包括界面消息,鼠标键盘消息,自定义消息等),是在普通的工作线程的基础上加上消息循环来实现的。
工作线程原本没有消息队列,可强制加一个,一般线程中出现GDI的调用就会出现一个消息队列;
UI线程处理消息
UI线程启动一个消息循环(Message Loop),每次从本线程所对应的消息队列中取出一条消息,然后根据消息所包容的信息,将其转发给特定的窗体对象,此窗体对象所对应的“窗体过程”函数被调用以处理这些消息。
MSG msg; // 代表一条消息
BOOL bRet;
// 从UI线程消息队列中取出一条消息
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// 错误处理代码,通常是直接退出程序
}
else
{
TranslateMessage(&msg); // 转换消息格式
DispatchMessage(&msg); // 分发消息给相应的窗体
}
}

GetMessage()等到消息才返回,peekmessage()则马上返回消息或者空值;
GetMessage()获得消息后从队列中删除(WM_PAINT除外);
peekMessage()根据参数PM_NOREMOVE或者PM_REMOVE来决定要不要删除;
TranslateMessage()函数主要用于将WM_KEYDOWN和WM_KEYUP消息转换WM_CHAR消息。如果想要截获WM_KEYDOWN和WM_KEYUP消息,需要重载窗体类的PreTranslateMessage()函数进行分析。
DispatchMessage()函数根据取出的消息中所包含的窗体句柄,将这一消息转发给引此句柄所对应的窗体对象。负责响应消息的函数称为窗体过程(Window Procedure)。如果需要自定义处理,则重载窗体类的DefWindowProc()函数。窗体过程是一个函数,每个窗体一个,形式如下:
LRESULT CALLBACK MainWndProc(……)
{
//……
switch (uMsg) // 依据消息标识符进行分类处理
{
case WM_CREATE:
// 初始化窗体.
return 0;
case WM_PAINT:
// 绘制窗体
return 0;
//
// 处理其他消息
//
default:
// 转去调用系统默认的消息处理函数
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//……
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值