CWinThread

表示应用程序中的执行线程。

语法

class CWinThread : public CCmdTarget

成员

公共构造函数

名称 描述
CWinThread::CWinThread 构造 CWinThread 对象。

公共方法

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

公共运算符

“属性” 描述
CWinThread::operator HANDLE 检索 CWinThread 对象的句柄。

公共数据成员

“属性” 描述
CWinThread::m_bAutoDelete 指定是否在线程终止时销毁对象。
CWinThread::m_hThread 当前线程的句柄。
CWinThread::m_nThreadID 当前线程的 ID。
CWinThread::m_pActiveWnd 当 OLE 服务器处于就地活动状态时,指向容器应用程序的主窗口的指针。
CWinThread::m_pMainWnd 保留指向应用程序主窗口的指针。

备注

执行的主线程通常由派生自 CWinApp 的对象提供;CWinApp 派生自 CWinThread。 其他 CWinThread 对象允许一个给定应用程序中存在多个线程。

CWinThread 支持两种常规类型的线程:工作线程和用户界面线程。 工作线程没有消息泵:例如在电子表格应用程序中执行后台计算的线程。 用户界面线程具有消息泵,并处理从系统接收的消息。 CWinApp 和派生自它的类是用户界面线程的示例。 其他用户界面线程也可以直接派生自 CWinThread

CWinThread 的对象通常存在于线程的持续时间内。 如果要修改此行为,请将 m_bAutoDelete 设置为 FALSE

CWinThread 类是使代码和 MFC 完全线程安全所必需的。 框架用来维护特定于线程的信息的线程本地数据由 CWinThread 对象管理。 由于通过这种对 CWinThread 的依赖来处理线程本地数据,因此,使用 MFC 的任何线程必须由 MFC 创建。 例如,运行时函数 _beginthread_beginthreadex 创建的线程不能使用任何 MFC API。

若要创建线程,请调用 AfxBeginThread。 有两种形式,具体取决于你是需要工作线程还是用户界面线程。 如果需要用户界面线程,请传递给 AfxBeginThread 指向 CWinThread 派生类的 CRuntimeClass 的指针。 如果要创建工作线程,请传递给 AfxBeginThread 指向控制函数的指针和控制函数的参数。 对于工作线程和用户界面线程,可以指定用于修改优先级、堆栈大小、创建标志和安全特性的可选参数。 AfxBeginThread 将返回指向新 CWinThread 对象的指针。

通过改为调用 AfxBeginThread,可以构造 CWinThread 派生的对象,然后调用 CreateThread。 如果要在连续创建和终止线程执行之间重复使用 CWinThread 对象,则此双阶段构造方法非常有用。

有关 CWinThread 的详细信息,请参阅文章使用 C++ 和 MFC 进行多线程处理多线程处理:创建用户界面线程多线程处理:创建工作线程多线程处理:如何使用同步类

继承层次结构

CObject

CCmdTarget

CWinThread

要求

标头afxwin.h

CWinThread::CreateThread

创建要在调用进程的地址空间内执行的线程。

BOOL CreateThread(
    DWORD dwCreateFlags = 0,
    UINT nStackSize = 0,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

参数

dwCreateFlags
指定一个用于控制线程创建的额外标志。 此标志可以包含两个值之一:

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

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

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

lpSecurityAttrs
指向用于指定线程安全属性的 SECURITY_ATTRIBUTES 结构。

返回值

如果线程创建成功,则为非零值;否则为 0。

备注

使用 AfxBeginThread 创建线程对象并在一个步骤中执行它。 如果要在连续创建和终止线程执行之间重复使用线程对象,请使用 CreateThread

CWinThread::CWinThread

构造 CWinThread 对象。

CWinThread();

备注

若要开始线程的执行,请调用 CreateThread 成员函数。 通常通过调用 AfxBeginThread 来创建线程,这将调用此构造函数和 CreateThread

CWinThread::ExitInstance

由框架从很少替代的 Run 成员函数中调用以退出线程的此实例,或者在调用 InitInstance 失败时由框架调用。

virtual int ExitInstance();

返回值

线程的退出代码;0 表示无错误,大于 0 的值表示错误。 可以通过调用 GetExitCodeThread 来检索此值。

注解

不要从除了 Run 成员函数内以外的任何位置调用此成员函数。 此成员函数仅在用户界面线程中使用。

如果 m_bAutoDeleteTRUE,此函数的默认实现将删除 CWinThread 对象。 如果要在线程终止时执行其他清理,请替代此函数。 ExitInstance 的实现应在代码执行后调用基类的版本。

CWinThread::GetMainWnd

如果应用程序是 OLE 服务器,请调用此函数来检索指向应用程序的活动主窗口的指针,而不是直接引用应用程序对象的 m_pMainWnd 成员。

virtual CWnd* GetMainWnd();

返回值

此函数返回指向两种类型的窗口之一的指针。 如果线程是 OLE 服务器的一部分,并且具有在活动容器中处于就地活动状态的对象,则此函数将返回 CWinThread 对象的 CWinApp::m_pActiveWnd 数据成员。

如果没有在容器中处于就地活动状态的对象,或者你的应用程序不是一个 OLE 服务器,则此函数返回你的线程对象的 m_pMainWnd 数据成员。

备注

对于用户界面线程,这等效于直接引用应用程序对象的 m_pActiveWnd 成员。

如果您的应用程序不是 OLE 服务器,调用此函数相当于直接引用应用程序对象的 m_pMainWnd 成员。

替代此函数以修改默认行为。

CWinThread::GetThreadPriority

获取此线程的当前线程优先级别。

int GetThreadPriority();

返回值

其优先级类中的当前线程优先级别。 返回的值将是以下值之一,从最高优先级到最低优先级列出:

  • THREAD_PRIORITY_TIME_CRITICAL

  • THREAD_PRIORITY_HIGHEST

  • THREAD_PRIORITY_ABOVE_NORMAL

  • THREAD_PRIORITY_NORMAL

  • THREAD_PRIORITY_BELOW_NORMAL

  • THREAD_PRIORITY_LOWEST

  • THREAD_PRIORITY_IDLE

有关这些优先级的详细信息,请参阅 Windows SDK 中的 SetThreadPriority

CWinThread::InitInstance

必须替代 InitInstance 才能初始化用户界面线程的每个新实例。

virtual BOOL InitInstance();

返回值

如果初始化成功,则为非零值;否则为 0。

注解

通常,你会替代 InitInstance 以执行在首次创建线程时必须完成的任务。

此成员函数仅在用户界面线程中使用。 在传递给 AfxBeginThread 的控制函数中执行工作线程初始化。

CWinThread::IsIdleMessage

替代此函数,使 OnIdle 在特定消息生成后不被调用。

virtual BOOL IsIdleMessage(MSG* pMsg);

参数

pMsg
指向正在处理的当前消息。

返回值

如果在处理消息后应调用 OnIdle,则为非零值;否则为 0。

注解

默认实现不会在冗余鼠标消息和由闪烁的插入符生成的消息后调用 OnIdle

如果应用程序创建了短计时器,则将经常调用 OnIdle,从而导致性能问题。 若要提高此类应用程序的性能,请在应用程序的 CWinApp 派生类中替代 IsIdleMessage 以检查 WM_TIMER 消息,如下所示:

BOOL CMyWinApp::IsIdleMessage(MSG* pMsg)
{
   if (!CWinApp::IsIdleMessage(pMsg) || pMsg->message == WM_TIMER)
      return FALSE;
   else
      return TRUE;
}

以这种方式处理 WM_TIMER 将提高使用短计时器的应用程序的性能。

CWinThread::m_bAutoDelete

指定 CWinThread 对象是否应在线程终止时自动删除。

BOOL m_bAutoDelete;

注解

m_bAutoDelete 数据成员是 BOOL 类型的公共变量。

m_bAutoDelete 的值不会影响基础线程句柄的关闭方式,但它会影响关闭句柄的计时。 在销毁 CWinThread 对象时,始终关闭线程句柄。

CWinThread::m_hThread

附加到此 CWinThread 的线程的句柄。

HANDLE m_hThread;

注解

m_hThread 数据成员是 HANDLE 类型的公共变量。 仅当基础内核线程对象当前存在且句柄尚未关闭时,它才有效。

CWinThread 析构函数对 m_hThread 调用 CloseHandle。 如果当线程终止时 m_bAutoDeleteTRUECWinThread 对象会被销毁,这将使指向 CWinThread 对象及其成员变量的任何指针失效。 可能需要 m_hThread 成员来检查线程退出值,或等待信号。 若要在线程执行期间以及线程终止后保留 CWinThread 对象及其 m_hThread 成员,请在允许线程执行继续之前将 m_bAutoDelete 设置为 FALSE。 否则,在你尝试使用它之前,线程可能会终止、销毁 CWinThread 对象,并关闭句柄。 如果使用此方法,则需要负责删除 CWinThread 对象。

CWinThread::m_nThreadID

附加到此 CWinThread 的线程的 ID。

DWORD m_nThreadID;

注解

m_nThreadID 数据成员是 DWORD 类型的公共变量。 仅当基础内核线程对象当前存在时,它才有效。 另请参阅有关 m_hThread 生存期的注解。

示例

请参阅 AfxGetThread 的示例。

CWinThread::m_pActiveWnd

使用此数据成员来存储指向线程的活动窗口对象的指针。

CWnd* m_pActiveWnd;

备注

m_pActiveWnd 引用的窗口关闭时,Microsoft 基础类库将自动终止你的线程。 如果此线程是应用程序的主线程,则应用程序也将终止。 如果此数据成员是 NULL,则将继承应用程序的 CWinApp 对象的活动窗口。 m_pActiveWndCWnd* 类型的公共变量。

通常,在替代 InitInstance 时将设置此成员变量。 在工作线程中,此数据成员的值继承自其父线程。

CWinThread::m_pMainWnd

使用此数据成员来存储指向线程的主窗口对象的指针。

CWnd* m_pMainWnd;

备注

m_pMainWnd 引用的窗口关闭时,Microsoft 基础类库将自动终止你的线程。 如果此线程是应用程序的主线程,则应用程序也将终止。 如果此数据成员是 NULL,则应用程序的 CWinApp 对象的主窗口将用于确定何时终止线程。 m_pMainWndCWnd* 类型的公共变量。

通常,在替代 InitInstance 时将设置此成员变量。 在工作线程中,此数据成员的值继承自其父线程。

CWinThread::OnIdle

替代此成员函数以执行空闲时间处理。

virtual BOOL OnIdle(LONG lCount);

参数

lCount
每当线程的消息队列为空而调用 OnIdle 时将递增的计数器。 每次处理新消息时,此计数将重置为 0。 可以使用 lCount 参数来确定在未处理消息的情况下线程空闲时间的相对长度。

返回值

如果接收更多空闲处理时间,则为非零值;如果不再需要更多空闲处理时间,则为 0。

备注

当线程的消息队列为空时会在默认消息循环中调用 OnIdle。 使用替代以调用自己的后台空闲处理程序任务。

OnIdle 应返回 0 以指示不需要额外的空闲处理时间。 每当消息队列为空而调用 OnIdle 时,lCount 参数将递增,并且在每次处理新消息时将重置为 0。 可以基于此计数调用不同的空闲例程。

此成员函数的默认实现将从内存中释放临时对象和未使用的动态链接库。

此成员函数仅在用户界面线程中使用。

由于应用程序在 OnIdle 返回之前无法处理消息,因此不要在此函数中执行冗长的任务。

CWinThread::operator HANDLE

检索 CWinThread 对象的句柄。

operator HANDLE() const;

返回值

如果成功,则为线程对象的句柄;否则为 NULL.

注解

使用句柄直接调用 Windows API。

CWinThread::PostThreadMessage

调用以将用户定义的消息发布到另一个 CWinThread 对象。

BOOL PostThreadMessage(
    UINT message,
    WPARAM wParam,
    LPARAM lParam);

参数

message
用户定义的消息的 ID。

wParam
第一个消息参数。

lParam
第二个消息参数。

返回值

如果成功,则不为 0;否则为 0。

备注

已发布的消息由消息映射宏 ON_THREAD_MESSAGE 映射到正确的消息处理程序。

注意

调用 PostThreadMessage 时,消息将放置在线程的消息队列中。 但是,由于以这种方式发布的消息与窗口不关联,因此 MFC 不会将它们调度到消息或命令处理程序。 为了处理这些消息,请替代 CWinApp 派生类的 PreTranslateMessage() 函数,并手动处理消息。

CWinThread::PreTranslateMessage

替代此函数,以在窗口消息调度到 Windows 函数 TranslateMessageDispatchMessage 之前筛选这些消息。

virtual BOOL PreTranslateMessage(MSG* pMsg);

参数

pMsg
指向包含要处理的消息的 MSG 结构

返回值

如果消息已在 PreTranslateMessage 中完全处理且不应进一步处理,则为非零值。 如果消息应以正常方式处理,则为零。

备注

此成员函数仅在用户界面线程中使用。

CWinThread::ProcessMessageFilter

框架的挂钩函数调用此成员函数来筛选和响应某些 Windows 消息。

virtual BOOL ProcessMessageFilter(
    int code,
    LPMSG lpMsg);

参数

code
指定挂钩代码。 此成员函数使用此代码来确定如何处理 lpMsg

lpMsg
指向 Windows MSG 结构的指针。

返回值

如果消息已处理,则为非零值;否则为 0。

备注

挂钩函数将在事件发送到应用程序的正常消息处理之前处理事件。

如果替代此高级功能,请确保调用基类版本以维护框架的挂钩处理。

CWinThread::ProcessWndProcException

每当处理程序不捕获线程的消息或命令处理程序之一中引发的异常时,框架都会调用此成员函数。

virtual LRESULT ProcessWndProcException(
    CException* e,
    const MSG* pMsg);

参数

e
指向未处理的异常。

pMsg
指向 MSG 结构,其中包含有关导致框架引发异常的 Windows 消息的信息。

返回值

如果生成 WM_CREATE 异常,则为 -1;否则为 0。

备注

请勿直接调用此成员函数。

此成员函数的默认实现仅处理从以下消息生成的异常:

命令 操作
WM_CREATE Fail.
WM_PAINT 验证受影响的窗口,从而防止生成另一条 WM_PAINT 消息。

替代此成员函数以提供异常的全局处理。 仅当希望显示默认行为时,才调用基本功能。

此成员函数仅在具有消息泵的线程中使用。

CWinThread::PumpMessage

包含线程的消息循环。

virtual BOOL PumpMessage();

注解

PumpMessage 包含线程的消息循环。 PumpMessageCWinThread 调用以泵出线程的消息。 可以直接调用 PumpMessage 以强制处理消息,也可以替代 PumpMessage 以更改其默认行为。

仅建议高级用户直接调用 PumpMessage 并替代其默认行为。

CWinThread::ResumeThread

调用以恢复执行由 SuspendThread 成员函数挂起的线程或使用 CREATE_SUSPENDED 标志创建的线程。

DWORD ResumeThread();

返回值

如果成功,则为线程的上一个挂起计数;否则为 0xFFFFFFFF。 如果返回值为零,则当前线程未挂起。 如果返回值为 1,则线程已挂起,但现在将重新启动。 任何大于 1 的返回值都表示线程保持挂起状态。

备注

当前线程的挂起计数减 1。 如果挂起计数减到 0,线程将恢复执行;否则线程将保持挂起状态。

CWinThread::Run

为用户界面线程提供默认消息循环。

virtual int Run();

返回值

由线程返回的 int 值。 可以通过调用 GetExitCodeThread 来检索此值。

备注

Run 会获取并调度 Windows 消息,直到应用程序接收 WM_QUIT 消息为止。 如果线程的消息队列当前不包含任何消息,Run 会调用 OnIdle 以执行空闲时间处理。 传入消息将转到 PreTranslateMessage 成员函数进行特殊处理,然后转到 Windows 函数 TranslateMessage 进行标准键盘转换。 最后,将调用 DispatchMessage Windows 函数。

尽管 Run 很少被替代,但可以替代它来实现特殊行为。

此成员函数仅在用户界面线程中使用。

CWinThread::SetThreadPriority

此函数在其优先级类中设置当前线程的优先级别。

BOOL SetThreadPriority(int nPriority);

参数

nPriority
在其优先级类中指定新的线程优先级别。 此参数必须是以下值之一,从最高优先级到最低优先级列出:

  • THREAD_PRIORITY_TIME_CRITICAL

  • THREAD_PRIORITY_HIGHEST

  • THREAD_PRIORITY_ABOVE_NORMAL

  • THREAD_PRIORITY_NORMAL

  • THREAD_PRIORITY_BELOW_NORMAL

  • THREAD_PRIORITY_LOWEST

  • THREAD_PRIORITY_IDLE

有关这些优先级的详细信息,请参阅 Windows SDK 中的 SetThreadPriority

返回值

如果函数成功,则为非零值;否则为 0。

注解

它只能在 CreateThread 成功返回后调用。

CWinThread::SuspendThread

递增当前线程的挂起计数。

DWORD SuspendThread();

返回值

如果成功,则为线程的上一个挂起计数;否则为 0xFFFFFFFF

注解

如果任何线程的挂起计数高于零,该线程将不会执行。 可以通过调用 ResumeThread 成员函数来恢复线程。

另请参阅

CCmdTarget
层次结构图
CWinApp
CCmdTarget