概述
以下以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;
}
最后
以上就是天真寒风为你收集整理的MFC中在子线程中如何更新控件的值的全部内容,希望文章能够帮你解决MFC中在子线程中如何更新控件的值所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复