Bootstrap

MFC线程-通过CWinThread派生类实现

基本步骤

1.创建 CWinThread 派生类
 从 CWinThread 继承,并重写以下虚函数:
      InitInstance():线程初始化方法,执行线程启动时的资源分配和初始化操作。
      ExitInstance():线程结束时的清理方法,负责释放线程创建时分配的资源。
      Run()(可选):线程执行的核心逻辑,在这里处理线程的实际任务(例如循环计算、后台任务等)。
2.创建线程对象
        使用 AfxBeginThread 或直接调用 CreateThread 方法启动线程。
3.管理线程生命周期
        根据需要设置 m_bAutoDelete,选择自动或手动销毁线程对象。在线程结束时确保资源正确清理。

创建 CWinThread 派生类

首先,从 CWinThread 派生出自定义线程类,并重写 InitInstanceRunExitInstance 函数。

头文件:

#pragma once
#include <afxwin.h>

class ThreadDoManger : public CWinThread
{
public:
	ThreadDoManger(HWND hWnd);
	virtual BOOL InitInstance() override;
	virtual int ExitInstance() override;
	virtual int Run() override;

private:
	HWND m_hWnd; // 用于通知主线程的窗口句柄
};

CPP文件:

#include "stdafx.h"
#include "ThreadDoManger.h"


// 构造函数
ThreadDoManger::ThreadDoManger(HWND hWnd) : m_hWnd(hWnd) {}

// 初始化线程
BOOL ThreadDoManger::InitInstance()
{
	AfxMessageBox(_T("线程初始化成功!"));
	return TRUE;
}

// 清理线程
int ThreadDoManger::ExitInstance()
{
	AfxMessageBox(_T("线程清理完成!"));
	return CWinThread::ExitInstance();
}

// 线程主体执行代码
int ThreadDoManger::Run()
{
	int sum = 0;
	for (int i = 1; i <= 10; ++i)
	{
		sum += i;
		CString strMsg;
		strMsg.Format(_T("线程正在运行,计数: %d  \n"), i);
		TRACE(strMsg);
		Sleep(500); // 模拟耗时操作,每次累加休眠 50ms
	}

	// 任务完成后,通知主线程
	::PostMessage(m_hWnd, WM_USER + 1, sum, 0);
	return 0;
}

主线程调用及与主线程通信

线程完成任务后,主线程需要接收并处理消息。我们可以通过 PostMessage 来向主线程发送计算结果。下面是主线程中如何接收并处理这个消息。

头文件:

#define WM_USER_TASK_COMPLETED (WM_USER + 1) // 定义消息

class CMFCtestThreadDlg : public CDialogEx
{
private:
    ThreadDoManger* m_pThread; // 线程对象指针
public:
    afx_msg LRESULT OnTaskCompleted(WPARAM wParam, LPARAM lParam); // 消息处理方法
    DECLARE_MESSAGE_MAP()
};

在主线程的消息映射中,注册并处理 WM_USER_TASK_COMPLETED 消息。

OnBnClickedButton5:通过点击按钮启动线程,并将主窗口句柄传递给线程对象,以便线程能通过消息通知主线程。

OnTaskCompleted:线程完成任务后,接收到的消息中包含计算结果。主线程显示这个结果,并手动清理线程对象。

CPP文件:

BEGIN_MESSAGE_MAP(CMFCtestThreadDlg, CDialogEx)
    ON_MESSAGE(WM_USER_TASK_COMPLETED, &CMFCtestThreadDlg::OnTaskCompleted) // 注册消息
END_MESSAGE_MAP()

void CMFCtestThreadDlg::OnBnClickedButton5()
{
    m_pThread = new ThreadDoManger(m_hWnd); // 创建线程并传递主窗口句柄

    if (!m_pThread->CreateThread())
    {
        AfxMessageBox(_T("线程创建失败!"));
        delete m_pThread;
        m_pThread = nullptr;
    }
    else
    {
        m_pThread->m_bAutoDelete = FALSE; // 手动销毁线程对象
        AfxMessageBox(_T("线程已启动!"));
    }
}

LRESULT CMFCtestThreadDlg::OnTaskCompleted(WPARAM wParam, LPARAM lParam)
{
    int sum = static_cast<int>(wParam); // 获取结果
    CString strMessage;
    strMessage.Format(_T("线程任务完成,结果为:%d"), sum);
    AfxMessageBox(strMessage); // 显示结果

    // 清理线程
    if (m_pThread)
    {
        m_pThread->Delete(); 
        m_pThread = nullptr;
    }

    return 0;
}
;