MFC中在子线程中如何更新控件的值

以下以vs2013+opencv2.4.9的开发环境做出演示:

文章通过MFC+opencv使用多线程的方法实现视频的播放暂停和结束这个demo来说
http://blog.csdn.net/davebobo/article/details/51123853

线程函数DWORD WINAPI PlayVideo(LPVOID lpParam)

DWORD WINAPI PlayVideo(LPVOID lpParam)
{
    CMFCdetectDlg* pThis = (CMFCdetectDlg*)lpParam;
    CvCapture* pCapture;
    IplImage* frame;
    pCapture = cvCreateFileCapture("example.mov");
    // 获取视频的帧率
    int fps = (int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FPS);
    //pThis->UpdateData(TRUE);
    SendMessage(pThis->m_hWnd, WM_MY_MESSAGE2, 0, (WPARAM)(&fps));
    //pThis->edit_fps = (int)fps;
    //pThis->UpdateData(FALSE);
    if (pCapture == NULL)
    {
        return -1;
    }

    frame = cvQueryFrame(pCapture);
    while (frame)
    {

            start_event.SetEvent();
            if (terminate_flag == -1)
            {
                terminate_flag = 0;
                _endthreadex(0);
            };
            pThis->Display(frame, IDC_STATIC);
            Sleep(33);
            frame = cvQueryFrame(pCapture);
        }
    }

    cvReleaseCapture(&pCapture);

}

如果使用UpdateData(TRUE)的方法来更新控件的值,则会报错Debug Assertion Failed! ,在工作线程中不能使用UpdateData来更新主线程中的数据,只能在主线程中使用。界面的东西,最好就是用主线程(界面线程)去执行相应的操作。要想在子线程(工作线程)里执行界面线程的操作,最好是向主线程发送消息。

解决方法:工作线程给主线程发消息,然后由主线程受到消息后,Updatedata
(1)在CMCdetectDlg.h中定义一个消息宏

#define WM_MY_MESSAGE (WM_USER+100)  

(2)在头文件中增加一个回调函数声明:

这里写图片描述

(3)定义消息映射

BEGIN_MESSAGE_MAP(CMFCdetectDlg, CDialogEx)

    ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
    ON_MESSAGE(WM_MY_MESSAGE2, OnMyMessage2)
    ON_MESSAGE(WM_MY_MESSAGE3, OnMyMessage3)

END_MESSAGE_MAP()

(4) 在窗口或对话框的cpp文件中增加回调函数的实现

LRESULT CMFCdetectDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
    // TODO: 处理用户自定义消息 
    UpdateData(TRUE);//更新控件的值
    edit_frameNum = *((int*)lParam);

    UpdateData(FALSE);
     return 0;
}

(5)在线程中触发该消息

SendMessage(pThis->m_hWnd,WM_MY_MESSAGE, 0, (LPARAM)(&FrameCount));

函数SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) 或 PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) 可实现发送发送自定义的消息。
说明:
(1)PostMessage()与SendMessage()函数的区别是:SendMessage()的消息直接发给窗口并调用相应的消息响应函数,消息不进消息队列,但直到消息响应函数处理完后SendMessage()才返回。而PostMessage()将消息放入消息队列后立即返回。

(2)传递参数时,如果是局部变量要用SendMessage()函数,如果是全局变量则两个都可以使用。

(3)使用SendMessage传递CSting

CString w1(_T("abcdefg"));
SendMessage(pThis->m_hWnd, WM_MY_MESSAGE3,  (WPARAM)(&w1),0);
LRESULT CMFCdetectDlg::OnMyMessage3(WPARAM wParam, LPARAM lParam)
{
    // TODO: 处理用户自定义消息 
    //UpdateData(TRUE);

    CString str2;
    str2 = *((CString*)wParam);
    //UpdateData(FALSE);
    return 0;
}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值