关于mfc多线程进度条的问题

日光倾城亦微凉 2014-09-10 03:23:08
这是我暑假的大作业,具体实现的是把视频中的每一帧提取成图片保存下来
做完之后,我想为它加上一个进度条,如图所示

可是运行之后,程序窗口都会显示“未响应”,查了资料才知道要用到多线程
关键部分代码如下:
在VideoToPictureDlg.h中:

protected:
CWinThread* pThread;
UINT ThreadSpeed(LPVOID lpParameter);//线程函数的声明 此行在类外

在VideoToPictureDlg.cpp中:

//下面是BOOL CVideoToPictureDlg::OnInitDialog()函数中关于初始化的代码:
m_ctrlProgress.SetRange(0,100);

//设置进度条的每一步的增量

m_ctrlProgress.SetStep(1);

//设置进度条的当前位置

m_ctrlProgress.SetPos(1);

m_ctrlProgress.SendMessage(PBM_SETBKCOLOR, 0, RGB(255, 255, 255));//背景色

m_ctrlProgress.SendMessage(PBM_SETBARCOLOR, 0, RGB(0, 255, 0));//前景色
waitKey();

return TRUE;

//下面是点击开始键的响应函数:
void CVideoToPictureDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
if(infilename.IsEmpty())
{
MessageBox("请选择视频文件", "提示",MB_OK);
return;
}
else if(outfilename.IsEmpty())
{
MessageBox("请选择输出文件夹", "提示",MB_OK);
return;
}
CvCapture* capture = cvCreateFileCapture((LPSTR)(LPCTSTR)infilename);
IplImage* frame;
int i = 0;
char image_name[20];
CString Out;
//pThread = AfxBeginThread(ThreadSpeed, &m_ctrlProgress);
int numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
while(1)
{
frame = cvQueryFrame(capture);
if(!frame) break ;
sprintf_s(image_name, "%s%d%s", "image", ++i, ".jpg");//保存的图片名
CString str3;
str3.Format("%s",image_name);
CString str2 = _T("\\");
Out = outfilename + str2 + str3;
cvSaveImage((LPSTR)(LPCTSTR)Out, frame); //保存一帧图片
int jindu = (i * 100)/numFrames;
percent = jindu;
pThread = AfxBeginThread(ThreadSpeed, &m_ctrlProgress);//此处创建新线程

}

MessageBox("已完成提取", "提示",MB_OK);
cvReleaseCapture(&capture);

}

//下面是线程函数
UINT ThreadSpeed(LPVOID lpParameter)
{
CProgressCtrl *Speed = (CProgressCtrl*)lpParameter;
Speed->SetPos((percent));
Sleep(10);
return 0;
}

但是代码改成以上内容以后窗口仍然会未响应(其实后台在提取图片),调试时也进不到线程函数内部。
可能是自己还不太理解多线程。
希望大神们能帮帮我,谢谢!
...全文
416 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
u011016062 2015-02-07
  • 打赏
  • 举报
回复
楼主,我也在弄线程控制进度条,有点不理解,怎么发消息给主线程,可否给我讲讲
肆水東澤 2014-09-12
  • 打赏
  • 举报
回复
AfxBeginThread不要再循环里面做,这个只是开启一个线程,线程函数里面做循环,做耗时费力的事 sleep是要线程停歇片刻,把时间片给cpu,可以让主线程得到响应,就不会假死了,现在多核cpu功能强大,基本不会出现的
  • 打赏
  • 举报
回复
引用 2 楼 m617105 的回复:
你的流程有点问题。 1、void CVideoToPictureDlg::OnBnClickedOk()你这个函数里面正确的处理应该只是一些参数的初始化,例如视频文件的路径赋值,视频的总帧数赋值等,这些参数初始化完成后紧接着开启一个线程A。 2、线程A来执行你保存单个帧的任务,同时向主窗体发送自定义消息,自定义消息的内容就是当前保存帧的进度值,在自定义消息处理函数中来设置进度条。 3、在void CVideoToPictureDlg::OnBnClickedOk()中初始化的参数,你要保证他们的生命周期,因为在线程A中要使用到。
谢谢!
  • 打赏
  • 举报
回复
引用 1 楼 fqzlala 的回复:
你在线程里做了什么!!!!!去操作进度条了!!!不是不可以,你假死的原因,是没把工作量大的提取图片的工作放到线程里,你应该摆while里的东西,放到线程里去做!! 你的后台就是线程函数,在按钮中启动线程。 线程函数里,先计算视频总帧数,也就是提取图片的总数,设置初始化进度条。 然后进入循环处理提取图片的工作。每次提取图片完,都要修改下进度条。 你在线程提取图片循环里,最好都sleep下,防假死,线程中,不要操作进度条,方法是发消息,让主线程(界面线程)处理,或者调用一个接口函数,处理进度条。
谢谢你,我根据你说的,已经改好了,但是还有几个小问题想搞明白 先是“AfxBeginThread(ThreadSpeed, &m_ctrlProgress);//此处创建新线程”这一句放在while循环里,会不会导致创建多个线程? 还是因为线程函数名是一样的,编译器自动识别出来了,只创建一个? 其次是“你在线程提取图片循环里,最好都sleep下,防假死,”sleep会不会导致每次循环都变慢啊? 而且sleep为什么能防假死我也不太明白 十分感谢~
浩南_哥 2014-09-10
  • 打赏
  • 举报
回复
你的流程有点问题。 1、void CVideoToPictureDlg::OnBnClickedOk()你这个函数里面正确的处理应该只是一些参数的初始化,例如视频文件的路径赋值,视频的总帧数赋值等,这些参数初始化完成后紧接着开启一个线程A。 2、线程A来执行你保存单个帧的任务,同时向主窗体发送自定义消息,自定义消息的内容就是当前保存帧的进度值,在自定义消息处理函数中来设置进度条。 3、在void CVideoToPictureDlg::OnBnClickedOk()中初始化的参数,你要保证他们的生命周期,因为在线程A中要使用到。
肆水東澤 2014-09-10
  • 打赏
  • 举报
回复
你在线程里做了什么!!!!!去操作进度条了!!!不是不可以,你假死的原因,是没把工作量大的提取图片的工作放到线程里,你应该摆while里的东西,放到线程里去做!! 你的后台就是线程函数,在按钮中启动线程。 线程函数里,先计算视频总帧数,也就是提取图片的总数,设置初始化进度条。 然后进入循环处理提取图片的工作。每次提取图片完,都要修改下进度条。 你在线程提取图片循环里,最好都sleep下,防假死,线程中,不要操作进度条,方法是发消息,让主线程(界面线程)处理,或者调用一个接口函数,处理进度条。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧