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;
}
相关推荐
cookies_s_s1 小时前
Linux--进程(进程虚拟地址空间、页表、进程控制、实现简易shell)
linux·运维·服务器·数据结构·c++·算法·哈希算法
不想编程小谭1 小时前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
曼巴UE52 小时前
UE5.3 C++ TArray系列(一)
开发语言·c++·ue5
阿巴~阿巴~3 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
CoderCodingNo4 小时前
【GESP】C++二级真题 luogu-b3924, [GESP202312 二级] 小杨的H字矩阵
java·c++·矩阵
刃神太酷啦5 小时前
堆和priority_queue
数据结构·c++·蓝桥杯c++组
Heris995 小时前
2.22 c++练习【operator运算符重载、封装消息队列、封装信号灯集】
开发语言·c++
----云烟----5 小时前
C/C++ 中 volatile 关键字详解
c语言·开发语言·c++
ChoSeitaku6 小时前
12.重复内容去重|添加日志|部署服务到Linux上(C++)
linux·c++·windows
挣扎与觉醒中的技术人6 小时前
网络安全入门持续学习与进阶路径(一)
网络·c++·学习·程序人生·安全·web安全