返回
顶部

前言

前几天写了一个MFC程序,但是在写进度条的时候遇到了问题

因为我都放在了主线程中,所以就导致在绘制进度条的时候,程序是卡死的,为了解决这个问题,我百度了一波,最终使用了多线程的方式解决了主线程阻塞的问题

基础用法

首先在原有的项目中添加一个头文件:Thread.h,内容如下:

#pragma once
#include <process.h>
#include <Windows.h>
#define WM_USER_MSG WM_USER + 1001
#define WM_USER_FIN WM_USER + 1002

class CThread
{
public:
    static void Run(void *);
public:
    CThread(void);
    ~CThread(void);
};

编写Thread.cpp内容如下:

#include "StdAfx.h"
#include "Thread.h"

void CThread::Run( void* lpVoid )
{
    HWND hWnd = (HWND)lpVoid;

    for (int i=0;i<100;i++)
    {
        ::PostMessage(hWnd,WM_USER_MSG,WPARAM(i),LPARAM(0));
        Sleep(100);
    }

    ::PostMessage(hWnd,WM_USER_FIN,WPARAM(0),LPARAM(0));
    _endthread();
}

CThread::CThread(void)
{
}

CThread::~CThread(void)
{
}

在主窗口的cpp文件中添加如下消息映射:

ON_MESSAGE(WM_USER_MSG, &CMFCApplication1Dlg::OnMsg)
ON_MESSAGE(WM_USER_FIN, &CMFCApplication1Dlg::OnFin)

第一个消息映射是通知主窗口进行进度条的绘制,第二个消息映射时通知主窗口进度条绘制完毕,触发相应的回调函数

在按钮点击事件中编写如下代码:

CProgressCtrl *prog = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS1);
prog->SetRange(0, 100);
_beginthread(&CThread::Run, 0, this->GetSafeHwnd());

最终运行效果:

完整项目解决方案:

传参

上面的示例程序中我们只传了一个参数this->GetSafeHwnd()_beginthread函数的最后一个参数是一个指针,用于指向传递给第一个参数所指向的函数的参数列表,我去网上搜了一下,都是说使用结构体,但是我在实际操作的时候又总是会遇到这样那样的问题,最后干脆使用了类来传递多个参数

首先新建一个头文件:Share.h,内容如下:

#pragma once
#include <process.h>
#include <Windows.h>

class CShare
{
public:
    HWND hWnd;
    CString para1;
    CString para2;
    CShare(void);
    ~CShare(void);
};

然后再创建用于实现的cpp文件:Share.cpp,内容如下:

#include "StdAfx.h"
#include "Share.h"


CShare::CShare(void)
{
}

CShare::~CShare(void)
{
}

然后在主窗口类的头文件中新增一个CShare类的成员变量,使用如下方式传参即可:

void CMFCApplication1Dlg::OnBnClickedOk()
{
    CProgressCtrl *prog = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS1);
    prog->SetRange(0, 100);
    HWND hwnd = this->GetSafeHwnd();
    CString para1 = _T("我是参数一");
    CString para2 = _T("我是参数二");
    cshare.para1 = para1;
    cshare.para2 = para2;
    cshare.hWnd = hwnd;
    _beginthread(&CThread::Run, 0, &cshare);
}

Thread.cpp中接受参数的代码如下:

void CThread::Run( void* lpVoid )
{

    //强制类型转换
    HWND hWnd = ((CShare*)lpVoid)->hWnd;
    CString para1 = ((CShare*)lpVoid)->para1;
    CString para2 = ((CShare*)lpVoid)->para2;

    AfxMessageBox(para1);
    AfxMessageBox(para2);

    for (int i=0;i<100;i++)
    {
        ::PostMessage(hWnd,WM_USER_MSG,WPARAM(i),LPARAM(0));
        Sleep(100);
    }

    ::PostMessage(hWnd,WM_USER_FIN,WPARAM(0),LPARAM(0));
    _endthread();
}

最终运行效果:

asdsa

完整项目解决方案:

后记

不足之处还望指出