MFC 工作者线程(二)

工作者线程一般适合后台处理,没有消息队列,看不见、感觉不到它。

现在做一个让人能看得见、感觉得到的工作者线程。





基于对话框,工程名:241 

启动按钮:IDC_START_WORKER

暂停按钮:IDC_PAUSE

继续按钮:IDC_CONTINUE

进度条:    IDC_PROGRESS         关联变量:m_ctrlProgress


自定义 消息: WM_MSG_WORKER       及其响应函数:   OnWorkerMessage()

点击“启动按钮”,程序创建一个线程,线程执行函数为 WorkerThread(),它每隔0.1秒,发送自定义的 WM_MSG_WORKER 消息到主窗口。

响应函数则会根据消息的附加值,让进度条进度不断增加,当进度条满格后,关闭线程。

这样,工作者线程在后台看不见的处理,通过进度条的滚动,变得看得见。

添加代码,如下:

1、在 CMy241Dlg.h中   自定义消息   :#define WM_MSG_WORKER WM_USER+1

2、在 CMy241Dlg.h中       

       class CMy241Dlg : public CDialog
       {
       public:
           CWinThread *m_pWorkThread;                 //  定义线程指针
           LRESULT OnWorkerMessage(WPARAM wParam,LPARAM lParam);      //  声明消息响应函数 

3、在 CMy241Dlg.cpp 中,消息映射  BEGIN_MESSAGE_MAP(CMy241Dlg, CDialog)
                                                                  ......        
                                                                    //}}AFX_MSG_MAP
                                                                    ON_MESSAGE(WM_MSG_WORKER,OnWorkerMessage)
                                                                     END_MESSAGE_MAP()

        消息响应函数的具体实现:

         LRESULT  CMy241Dlg::OnWorkerMessage(WPARAM wParam,LPARAM lParam)
        {
          m_ctrlProgress.SetPos(wParam);
           if (wParam==100)                                                                                       //  如果进度条已满  
          {
          DWORD code;
        GetExitCodeThread(m_pWorkThread->m_hThread,&code);
        if (code==STILL_ACTIVE)
         {
         TerminateThread(m_pWorkThread->m_hThread,-1);           //   终止线程
          }
         delete m_pWorkThread;
          m_pWorkThread=NULL;
         GetDlgItem(IDC_START_WORKER)->SetWindowText("启动WORKER线程");
          }
          return 0;
        }

       

4、初始化进度条:

       BOOL CMy241Dlg::OnInitDialog()
       {
       CDialog::OnInitDialog();

                ..........
       m_ctrlProgress.SetRange(0,100);
       m_ctrlProgress.SetPos(1);

               return TRUE;  // return TRUE  unless you set the focus to a control
       }

5、为启动按钮添加 BN_CLICKED 事件处理函数: 

 void CMy241Dlg::OnStartWorker() 

{
// TODO: Add your control notification handler code here
if (m_pWorkThread==NULL)        //   如果线程不存在
{

 //   创建工作者线程:WorkerThrea,

 //    传递的参数是当前窗口的句柄:GetSafeHwnd()

 //    线程的初始状态:挂起  CREATE_SUSPENDED

m_pWorkThread= AfxBeginThread(WorkerThread,GetSafeHwnd(),0,0,CREATE_SUSPENDED,0);   

m_pWorkThread->m_bAutoDelete=FALSE;

m_pWorkThread->ResumeThread();             //  执行线程        
GetDlgItem(IDC_START_WORKER)->SetWindowText("停止WORKER线程");
}
else                                                                                                                 //  如果线程已存在
{
DWORD code;
GetExitCodeThread(m_pWorkThread->m_hThread,&code);
if (code==STILL_ACTIVE)                                                                  //   仍在运行中             
{
TerminateThread(m_pWorkThread->m_hThread,-1);          //   停止线程
}
delete m_pWorkThread;
m_pWorkThread=NULL;
GetDlgItem(IDC_START_WORKER)->SetWindowText("启动WORKER线程");
}
}

6、  线程执行函数:

UINT WorkerThread(LPVOID lParam)
{
HWND hWnd=(HWND)lParam;               //   创建线程时,传递的参数是窗口句柄,所以用(HWND)强制转换为句柄
for (int i=0;i<=100;i++)
{
   Sleep(100);                                              //   间隔100 毫秒
   SendMessage(hWnd,WM_MSG_WORKER , i ,0);            //   把自定义消息WM_MSG_WORKER   发送给主窗口,附加消息  i      
}
return 0;
}

7、暂停按钮:IDC_PAUSE 的 BN_CLICKED 事件处理函数: 

void CMy241Dlg::OnPause() 

{
// TODO: Add your control notification handler code here
SuspendThread(m_pWorkThread->m_hThread);
}

8、继续按钮:IDC_CONTINUE 的 BN_CLICKED 事件处理函数: 

void CMy241Dlg::OnContinue() 
{
// TODO: Add your control notification handler code here
ResumeThread(m_pWorkThread->m_hThread);
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值