前言
前几天写了一个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();
}
最终运行效果:
完整项目解决方案:
后记
不足之处还望指出