热门标签 | 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


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

推荐阅读
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • MicrosoftDeploymentToolkit2010部署培训实验手册V1.0目录实验环境说明3实验环境虚拟机使用信息3注意:4实验手册正文说 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 命令模式是一种行为设计模式,它将请求封装成一个独立的对象,从而允许你参数化不同的请求、队列请求或者记录请求日志。本文将详细介绍命令模式的基本概念、组件及其在实际场景中的应用。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 本文介绍了如何使用Python的Paramiko库批量更新多台服务器的登录密码。通过示例代码展示了具体实现方法,确保了操作的高效性和安全性。Paramiko库提供了强大的SSH2协议支持,使得远程服务器管理变得更加便捷。此外,文章还详细说明了代码的各个部分,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 如何在PHP中准确获取服务器IP地址?
    如何在PHP中准确获取服务器IP地址? ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
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社区 版权所有