热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我想在mfc对话框播放视频的功能,加一个单独的线程

testDlg.hUINTshowvideo(LPVOIDlpParameter);classCtestDlg:publicCDialogEx{构造public:
testDlg.h

UINT showvideo( LPVOID lpParameter  );
class CtestDlg : public CDialogEx
{
// 构造
public:
CtestDlg(CWnd* pParent = NULL); // 标准构造函数

// 对话框数据
enum { IDD = IDD_TEST_DIALOG };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持


// 实现
protected:
HICON m_hIcon;
/*HANDLE hThread1;
HANDLE hThread2;*/
// 生成的消息映射函数


virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
//IplImage* TheImage;

//CString m_vdpath; 
//CString   mPath; 



void ShowImage( IplImage* img, UINT ID );
void ResizeImage(IplImage* img);
void OnTimer(UINT nIDEvent) ;

afx_msg void OnBnClickedvideo();
afx_msg void OnBnClickedabout();
afx_msg void OnBnClickedtool();
afx_msg void OnBnClickedopenimage();
afx_msg void OnBnClickedrun();

};
test.cpp

#include "stdafx.h"
#include "test.h"
#include "testDlg.h"
#include "afxdialogex.h"
#include "CvvImage.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

 
CString  m_vdpath;
CString   mPath; 
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();

// 对话框数据
enum { IDD = IDD_ABOUTBOX };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnBnClickedhelp();
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_help, &CAboutDlg::OnBnClickedhelp)
END_MESSAGE_MAP()


// CtestDlg 对话框




CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/): CDialogEx(CtestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CtestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CtestDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CtestDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_video, &CtestDlg::OnBnClickedvideo)
ON_BN_CLICKED(IDC_about, &CtestDlg::OnBnClickedabout)
ON_BN_CLICKED(IDC_tool, &CtestDlg::OnBnClickedtool)
ON_BN_CLICKED(IDC_openimage, &CtestDlg::OnBnClickedopenimage)
ON_BN_CLICKED(IDC_run, &CtestDlg::OnBnClickedrun)
END_MESSAGE_MAP()


// CtestDlg 消息处理程序

BOOL CtestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码
CvSize ImgSize;
    ImgSize.height = IMAGE_HEIGHT;
    ImgSize.width = IMAGE_WIDTH;
    TheImage = cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
//UpdateData(FALSE);     将成员变量的值赋值给控件,将数据从窗口显示。

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CtestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//CDialogEx::OnPaint();
//CDialog::OnPaint();              // 重绘对话框
        CDialog::UpdateWindow();                // 更新windows窗口,如果无这步调用,图片显示还会出现问题
        ShowImage( TheImage, IDC_STATIC );    // 重绘图片函数

//add background picture
 CPaintDC   dc(this);   
           CRect   rect;   
           GetClientRect(&rect);   
           CDC   dcMem;   
           dcMem.CreateCompatibleDC(&dc);   
           CBitmap   bmpBackground;   
           bmpBackground.LoadBitmap(IDB_BITMAP1);        
           BITMAP   bitmap;   
           bmpBackground.GetBitmap(&bitmap);   
           CBitmap   *pbmpOld=dcMem.SelectObject(&bmpBackground);   
           dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,   
         bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);   


}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CtestDlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}

//以下为showimage函数
void CtestDlg::ShowImage(IplImage* img, UINT ID)// ID 是Picture Control控件的ID号
{
         CDC* pDC=GetDlgItem(ID)->GetDC();// 获得显示控件的 DC
         HDC hDC=pDC->GetSafeHdc();// 获取 HDC(设备句柄) 来进行绘图操作

         CRect rect;
         GetDlgItem(ID)->GetClientRect(&rect);
         int rw=rect.right-rect.left;    // 求出picture control的宽和高
         int rh=rect.bottom-rect.top;
         int iw=img->width;             // 读取图片的宽和高
         int ih=img->height;
         int tx = (int)(rw - iw)/2;                                      // 使图片的显示位置正好在控件的正中
         int ty = (int)(rh - ih)/2;
         SetRect( rect, tx, ty, tx+iw, ty+ih );

         CvvImage cimg;
         cimg.CopyOf(img);    // 复制图片
         cimg.DrawToHDC(hDC,&rect);

         ReleaseDC(pDC);
}
//以下为改变图片大小以适应控件
void CtestDlg::ResizeImage(IplImage* img)
{
         // 读取图片的宽和高
         int w = img->width;
         int h = img->height;

         // 找出宽和高中的较大值者
         int max = (w > h)? w: h;

         // 计算将图片缩放到TheImage区域所需的比例因子
         float scale = (float) ( (float) max / 512.0f );

         // 缩放后图片的宽和高
         int nw = (int)( w/scale );
         int nh = (int)( h/scale );

         // 为了将缩放后的图片存入 TheImage 的正中部位,需计算图片在 TheImage 左上角的期望坐标值
         int tlx = (nw > nh)? 0: (int)(256-nw)/2;
         int tly = (nw > nh)? (int)(256-nh)/2: 0;

         // 设置 TheImage 的 ROI 区域,用来存入图片 img
         cvSetImageROI( TheImage, cvRect( tlx, tly, nw, nh) );

         // 对图片 img 进行缩放,并存入到 TheImage 中
cvResize( img, TheImage );
         // 重置 TheImage 的 ROI 准备读入下一幅图片
         cvResetImageROI( TheImage );
}

//以下为打开视频函数
void CtestDlg::OnBnClickedvideo() 
{
CFileDialog dlg(TRUE, NULL, NULL,OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
_T("video files (*.avi) |*.avi| All Files (*.*) |*.*||"), NULL
        );                                        // 选项图片的约定
    dlg.m_ofn.lpstrTitle = _T("Open video");    // 打开文件对话框的标题名
   // CString mPath = dlg.GetPathName();
//capture=cvCaptureFromAVI(mPath);
//SetTimer(1,25,NULL); 
    if(dlg.DoModal()==IDOK) 
 { 
       m_vdpath=dlg.GetPathName(); 
 }   

CWinThread *hThread2=AfxBeginThread(showvideo,NULL,0,0,0,NULL);
}

UINT  showvideo( LPVOID lpParameters )
{

CtestDlg *pDlg  = (CtestDlg*)lpParameters; 
CvCapture* pCapture=NULL;
pCapture = cvCaptureFromAVI(m_vdpath); 
   if(pCapture == NULL)
      AfxMessageBox("AVI视频打开失败或格式不对");
 IplImage* frame=NULL;
while(true)
    {
if(frame = cvQueryFrame(pCapture) )
{
    //  cvQueryFrame( pCapture ) 用来提取指定视频中的每一帧
                   //视频的尾部 则退出
          
/* cvWaitKey(50000);*/
//Sleep(1);
pDlg->ResizeImage( frame );    // 对读入的图片进行缩放,使其宽或高最大值者刚好等于         再复制到 TheImage 中
pDlg->ShowImage( TheImage, IDC_STATIC );            // 调用显示图片函数    
    
}
 else
        {
            break;
        }
}

cvReleaseImage( &frame ); 
cvReleaseCapture( &pCapture );// 释放 ipl 占用的内存
return 0;

}

以前不另外加线程视频可以再空控件里运行,就是其它对话框其它按键都禁用了,所以想单独给视频加个线程,我自己试了下,不能播放了,对线程不是很了解,还请大家帮帮忙看看什么原因...

8 个解决方案

#1


那个函数ResizeImage就不需要了,opencv显示图像cimg.DrawToHDC(hDC,&rect);这个就可以自动改变图片大小以适应你给的控件的rect了。

线程我也在学习

#2


OpenCV

#3


毕业设计吧?CreateThread

#4


看了一下,你用的是工作线程,想要与界面交互就使用界面线程。现学现用的,你可以参考下。

#5


引用 1 楼  的回复:
那个函数ResizeImage就不需要了,opencv显示图像cimg.DrawToHDC(hDC,&rect);这个就可以自动改变图片大小以适应你给的控件的rect了。

线程我也在学习

用你的那个确实是很好的选择,就会避免我的那种问题出现。
另外我想问一下,我新建了一个对话框,想把图片显示在那个对话框里,我在主对话框里的一个按键相应函数里用
show dg; //show是我新建的对话框类
dg.DoModal();
再在新建的对话框的OnInitDialog() 下用
IplImage* ipl = cvLoadImage(mPath, 1 );
ShowImage( ipl,IDC_STATIC2);
cvReleaseImage( &ipl ); 
我断定追踪到这里,发现mpath也是有值的,不知为什么在运行的时候新建对话框的控件下还是什么都没有,,,不知道还有添加什么?还请多多指教...

#6


慢慢研究rect方法,,用rect实现控件的控制与你需要的视频图像显示

#7


多线程可以参考下《秒杀多线程面试题系列》
http://blog.csdn.net/column/details/killthreadseries.html
这里有十五篇文章,绝对让你在有收获。


-------------------
MoreWindows 
计科小硕 迅雷/微软/豌豆荚实习生 CSDN资深博客专家 2012年度CSDN博客之星
我的微博: http://weibo.com/MoreWindows
我的博客: http://blog.csdn.net/MoreWindows

#8


我现在貌似也是要多线程才能操作这个。。。囧。。

推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
author-avatar
mobiledu2502873617
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有