前言:这一篇,分为三个部分,第一部分是添加对简易播放器的补充,第二部分是解码器的安装、配置。

简易播放器的补充

主要内容:添加对双击全屏的代码


注意:有些朋友可能会想,这个有这么麻烦吗,直接添加对IDC_VIDEOWND的STN_CLICKED响应不就行了,你可以添加一下对该消息的响应,就会明白了,根本执行不进去!这是为什么呢,主要是因为视频信号已经覆盖在图片控件上面了,所以点击的时候根本接收不到点击消息,当然也就没有办法执行我们写在双击响应里面的代码了。由此可知我们可以拦截双击动作,然后对拦截的消息添加处理代码,要实现拦截就先添加CplayerDlg中的PreTranslateMessage()虚函数,此函数主要是为了方便用户对消息的处理

实现代码如下:

BOOL CPlayerDlg::PreTranslateMessage(MSG* pMsg)
{// TODO: 在此添加专用代码和/或调用基类if (pMsg->message == WM_KEYDOWN){if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE){RestoreFromFullScreen();return 1;}}if(pMsg->message==WM_LBUTTONDBLCLK)  //响应双击鼠标信息{CPoint pt;pt.x=LOWORD(pMsg->lParam); //X坐标pt.y=HIWORD(pMsg->lParam);  //Y坐标CRect rect;GetDlgItem(IDC_VIDEOWND)->GetWindowRect(&rect);this->ScreenToClient(&rect);CRgn rgn;rgn.CreateEllipticRgnIndirect(&rect);//创建一个rgn对象,主要用于判断当前点击的点是否在视频显示区域内//注意,如果已经全屏,就直接缩小,不应该这样判断,此方法主要用于将视频全屏if(this->GetFullScreen())//如果全屏则直接缩小{this->m_VideoWindow->put_FullScreenMode(OAFALSE);return true;}if(rgn.PtInRegion(pt))  //判断是否是在指定区域内{RestoreFromFullScreen();return true;}}return CDialog::PreTranslateMessage(pMsg);
}

上面我们先添加了对按键的响应,主要是为了方便用户在全屏状态时,通过按“ESC”键来返回原来的状态,代码如下:

if (pMsg->message == WM_KEYDOWN){if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE){RestoreFromFullScreen();return 1;}}

然后是添加对左键双击信息的响应,消息为WM_LBUTTONDBLCLK

首先是获取双击点的坐标,用pt.x=LOWORD(pMsg->lParam);获取X坐标, pt.y=HIWORD(pMsg->lParam);来获取Y坐标,然后根据显示窗口的大小(IDC_VIDEOWND)创建一个Rgn对象,然后判断当前的点是否在这个RGN区域内,如果在,就根据当前的状态来放大和缩小

其中有个函数RestoreFromFullScreen()主要是根据当前的显示状态来放大和缩小窗口的,代码如下:

bool CPlayerDlg::RestoreFromFullScreen()
{if (this->m_Graph){if (this->GetFullScreen()){this->SetFullScreen(FALSE);return true;}else{this->SetFullScreen(TRUE);return true;}}return false;
}

以上就实现了双击全屏和双击退出全屏,但你可能会发现这里还是存在了点问题,主要是,全屏后,鼠标不见了,下面我们采用另一种方法来实现全屏。

1、先申请几个CPlayerDlg的成员变量

public:WINDOWPLACEMENT m_OldWndPlacement;//保存原始位置CRect m_OldPlayWndRect; //保存原始的播放窗口的位置CRect m_OldProgressRect;//保存进度条原始位置CRect m_OldOpenBtnRect;//保存打开按钮原始位置CRect m_OldPlayBtnRect;//保存播放按钮原始位置CRect m_OldPauseBtnRect;//保存暂停按钮原始位置CRect m_OldStopBtnRect;//保存停止按钮原始位置BOOL m_bFullScreen;//屏显示标志

初始化时,将m_bFullScreen=false;其它变量无需初始化。

2、先贴实现代码,等下讲解

先将RestoreFromFullScreen()函数更改为以下代码:

bool CPlayerDlg::RestoreFromFullScreen()
{if (this->m_Graph){this->SetFullScreen2();return true;}return false;
}

SetFullScreen2()是新实现的函数,实现代码如下:

bool CPlayerDlg::SetFullScreen2()
{if(m_bFullScreen){ModifyStyle(WS_POPUP,WS_CAPTION);//首先还原框架的大小及位置SetWindowPlacement(&m_OldWndPlacement);//将播放窗口还原到原来的位置this->m_VideoWindowPlay.SetWindowPos(&wndTop,m_OldPlayWndRect.left,m_OldPlayWndRect.top,m_OldPlayWndRect.Width(),m_OldPlayWndRect.Height(),SWP_NOACTIVATE);//还原视频显示大小this->SetDisplayWindow(m_VideoWindowPlay.GetSafeHwnd());//还原其它控件的位置this->GetDlgItem(IDC_PROGRESS)->MoveWindow(m_OldProgressRect.left,m_OldProgressRect.top,m_OldProgressRect.Width(),m_OldProgressRect.Height(),true);this->GetDlgItem(IDC_BTN_OPEN)->MoveWindow(m_OldOpenBtnRect.left,m_OldOpenBtnRect.top,m_OldOpenBtnRect.Width(),m_OldOpenBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_PLAY)->MoveWindow(m_OldPlayBtnRect.left,m_OldPlayBtnRect.top,m_OldPlayBtnRect.Width(),m_OldPlayBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_PAUSE)->MoveWindow(m_OldPauseBtnRect.left,m_OldPauseBtnRect.top,m_OldPauseBtnRect.Width(),m_OldPauseBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_STOP)->MoveWindow(m_OldStopBtnRect.left,m_OldStopBtnRect.top,m_OldStopBtnRect.Width(),m_OldStopBtnRect.Height(),true);m_bFullScreen=false;return true;}else{//先放大总框架GetWindowPlacement(&m_OldWndPlacement);CRect m_RectOfCurrentWindow,m_RectOfClient;GetWindowRect(&m_RectOfCurrentWindow);RepositionBars(0,0xffff,AFX_IDW_PANE_FIRST,reposQuery,&m_RectOfClient);ClientToScreen(&m_RectOfClient);int nFullWidth = GetSystemMetrics(SM_CXSCREEN);int nFullHeight = GetSystemMetrics(SM_CYSCREEN);CRect m_FSRect;m_FSRect.left = m_RectOfCurrentWindow.left-m_RectOfClient.left;m_FSRect.top = m_RectOfCurrentWindow.top - m_RectOfClient.top;m_FSRect.right = m_RectOfCurrentWindow.right - m_RectOfClient.right+nFullWidth;m_FSRect.bottom = m_RectOfCurrentWindow.bottom - m_RectOfClient.bottom + nFullHeight;MoveWindow(&m_FSRect,TRUE);CRect rect;::GetWindowRect(::GetDesktopWindow(),rect);//先保存播放窗口及各控件原来的位置,以便还原this->m_VideoWindowPlay.GetWindowRect(this->m_OldPlayWndRect);this->GetDlgItem(IDC_PROGRESS)->GetWindowRect(m_OldProgressRect);this->GetDlgItem(IDC_BTN_OPEN)->GetWindowRect(m_OldOpenBtnRect);this->GetDlgItem(IDC_BTN_PLAY)->GetWindowRect(m_OldPlayBtnRect);this->GetDlgItem(IDC_BTN_PAUSE)->GetWindowRect(m_OldPauseBtnRect);this->GetDlgItem(IDC_BTN_STOP)->GetWindowRect(m_OldStopBtnRect);//设置作为播放窗口的图片控件的位置this->m_VideoWindowPlay.SetWindowPos(&wndTop,rect.left,rect.top,rect.Width(),rect.Height()-100,SWP_NOACTIVATE);//设置视频图像显示输出的大小this->m_VideoWindow->put_Left(rect.left);this->m_VideoWindow->put_Top(rect.top);this->m_VideoWindow->put_Width(rect.right   -   rect.left);this->m_VideoWindow->put_Height( rect.bottom   -   rect.top);//播放窗口最大化//设置其它控件新的位置this->GetDlgItem(IDC_PROGRESS)->MoveWindow(rect.left,rect.bottom-90,rect.Width(),20,true);CRect rectTemp;this->GetDlgItem(IDC_BTN_OPEN)->GetWindowRect(rectTemp);this->GetDlgItem(IDC_BTN_OPEN)->MoveWindow(rect.left+rect.Width()/2-300,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_PLAY)->MoveWindow(rect.left+rect.Width()/2-100,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_PAUSE)->MoveWindow(rect.left+rect.Width()/2+100,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_STOP)->MoveWindow(rect.left+rect.Width()/2+300,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);ShowCaret();//显示鼠标 m_bFullScreen=true;return true;        }return false;
}

代码讲解:

这里只讲解SetFullScreen2()的实现过程:

首先根据m_bFullScreen的值来判断当前窗口是全屏(值为TRUE)还是缩小状态(值为FALSE),如果全屏则缩小,如果缩小状态则全屏

先讲ELSE的全屏部分

先用GetWindowPlacement(&m_OldWndPlacement);函数保存当前框架的位置信息;

通过下面代码实现全屏

     CRect m_RectOfCurrentWindow,m_RectOfClient;GetWindowRect(&m_RectOfCurrentWindow);RepositionBars(0,0xffff,AFX_IDW_PANE_FIRST,reposQuery,&m_RectOfClient);ClientToScreen(&m_RectOfClient);int nFullWidth = GetSystemMetrics(SM_CXSCREEN);int nFullHeight = GetSystemMetrics(SM_CYSCREEN);CRect m_FSRect;m_FSRect.left = m_RectOfCurrentWindow.left-m_RectOfClient.left;m_FSRect.top = m_RectOfCurrentWindow.top - m_RectOfClient.top;m_FSRect.right = m_RectOfCurrentWindow.right - m_RectOfClient.right+nFullWidth;m_FSRect.bottom = m_RectOfCurrentWindow.bottom - m_RectOfClient.bottom + nFullHeight;MoveWindow(&m_FSRect,TRUE);

然后是保存原来各个控件的位置,以便缩小时还原,代码如下:

//先保存播放窗口及各控件原来的位置,以便还原this->m_VideoWindowPlay.GetWindowRect(this->m_OldPlayWndRect);this->GetDlgItem(IDC_PROGRESS)->GetWindowRect(m_OldProgressRect);this->GetDlgItem(IDC_BTN_OPEN)->GetWindowRect(m_OldOpenBtnRect);this->GetDlgItem(IDC_BTN_PLAY)->GetWindowRect(m_OldPlayBtnRect);this->GetDlgItem(IDC_BTN_PAUSE)->GetWindowRect(m_OldPauseBtnRect);this->GetDlgItem(IDC_BTN_STOP)->GetWindowRect(m_OldStopBtnRect);

再下面是设置播放窗口的位置及视频显示窗口的大小

CRect rect;::GetWindowRect(::GetDesktopWindow(),rect);//设置作为播放窗口的图片控件的位置this->m_VideoWindowPlay.SetWindowPos(&wndTop,rect.left,rect.top,rect.Width(),rect.Height()-100,SWP_NOACTIVATE);//设置视频图像显示输出的大小this->m_VideoWindow->put_Left(rect.left);this->m_VideoWindow->put_Top(rect.top);this->m_VideoWindow->put_Width(rect.right   -   rect.left);this->m_VideoWindow->put_Height( rect.bottom   -   rect.top);//播放窗口最大化

然后是设置各个控件在放大后的新位置

//设置其它控件新的位置this->GetDlgItem(IDC_PROGRESS)->MoveWindow(rect.left,rect.bottom-90,rect.Width(),20,true);CRect rectTemp;this->GetDlgItem(IDC_BTN_OPEN)->GetWindowRect(rectTemp);this->GetDlgItem(IDC_BTN_OPEN)->MoveWindow(rect.left+rect.Width()/2-300,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_PLAY)->MoveWindow(rect.left+rect.Width()/2-100,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_PAUSE)->MoveWindow(rect.left+rect.Width()/2+100,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);this->GetDlgItem(IDC_BTN_STOP)->MoveWindow(rect.left+rect.Width()/2+300,rect.bottom-50,rectTemp.Width(),rectTemp.Height(),true);

最后是显示鼠标语句,及设置m_bFullScreen,代码如下:

     ShowCaret();//显示鼠标  m_bFullScreen=true;

下面是IF语句部分的讲解:

缩小时正好是放大的反过程,相比之下,比前面的步骤要简单很多

首先用SetWindowPlacement(&m_OldWndPlacement);还原框架的大小及位置

然后是还原视频显示窗口的位置及大小,因为我们已经保存了以前位置,所以直接用SetWindowPos就完全可以实现了。

this->m_VideoWindowPlay.SetWindowPos(&wndTop,m_OldPlayWndRect.left,m_OldPlayWndRect.top,m_OldPlayWndRect.Width(),m_OldPlayWndRect.Height(),SWP_NOACTIVATE);

设置视频显示大小

this->SetDisplayWindow(m_VideoWindowPlay.GetSafeHwnd());

还原其它控件位置

     this->GetDlgItem(IDC_PROGRESS)->MoveWindow(m_OldProgressRect.left,m_OldProgressRect.top,m_OldProgressRect.Width(),m_OldProgressRect.Height(),true);this->GetDlgItem(IDC_BTN_OPEN)->MoveWindow(m_OldOpenBtnRect.left,m_OldOpenBtnRect.top,m_OldOpenBtnRect.Width(),m_OldOpenBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_PLAY)->MoveWindow(m_OldPlayBtnRect.left,m_OldPlayBtnRect.top,m_OldPlayBtnRect.Width(),m_OldPlayBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_PAUSE)->MoveWindow(m_OldPauseBtnRect.left,m_OldPauseBtnRect.top,m_OldPauseBtnRect.Width(),m_OldPauseBtnRect.Height(),true);this->GetDlgItem(IDC_BTN_STOP)->MoveWindow(m_OldStopBtnRect.left,m_OldStopBtnRect.top,m_OldStopBtnRect.Width(),m_OldStopBtnRect.Height(),true);m_bFullScreen=false;

放大时的效果图:

缩小图:

解码器的安装及配置

解码器我使用的是K-Lite解码器,它能够实现全格式的解码

一、安装

到下面的位置去下载K-Lite解码器,我上传上去的,不要分,就是我现在使用的版本,下载,根据默认选项安装即可。

http://download.csdn.net/detail/harvic880925/4575369

二、配置

在“开始”-》“所有程序”-》“K-Lite codec pack”-》“configuration”-》“ffdshow video decoder”

选中左边栏中的“codecs”,将左边的“decoder”列,全部选择上其中一个解码器,部分截图如下,其它类似:

配置好之后,即可播放任意格式的视频了。

至此,我们就基本实现了全格式的播放器了

本文的源码下载地址:

http://download.csdn.net/detail/harvic880925/4575507 不收分,有需要的朋友可以去下载

声明:本文仅供交流,如需转载,请标明出处哦!

第二篇就先写到这吧,下篇将讲解GraphEdit.exe的使用方法,最后一篇讲解如何用代码连接指定FILTER。

基于directShow,打造全能播放器系列之二相关推荐

  1. 基于directShow,打造全能播放器系列之一

    总前言:我打算写一个能实现全能播放的播放器,功能比较简单,也算是抛砖引玉吧,因为内容较多,所以打算写三篇,这是开篇,欢迎大家吐槽 简易播放器的实现 本文的编写环境:visual studio 2008 ...

  2. 基于DirectShow的简单播放器

    一 个简单的基于DirectShow的打开本地视频文件的例子. 参考了各种资材,网上很多,也比较简单,但有个问题就是在调用" RenderFile "函数时只有在x86下都会返回S ...

  3. 打造全能播放器 totem-xine

    Fedora 默认安装的totem采用的gstreamer底端只能播放有版权信息的影音文件,然而国内的情况大家都知道,所以我们发现他什么都播放不了,留之无用,所以,第一步,理所当然是删除之: yum ...

  4. 基于单片机的音乐播放器设计

     word完整版可点击如下下载>>>>>>>> 基于单片机的音乐播放器设计-硬件开发文档类资源-CSDN下载内容包括详细设计文档word版,附带开题报告 ...

  5. 仿迅雷播放器教程 -- 基于VLC的MFC播放器 (6)

    代码下载: http://download.csdn.net/detail/qq316293804/6409417 昨天的教程里写着预计MFC播放器会隔得久一点,但是今晚仔细看了下VLC的常用代码,发 ...

  6. html5开发一个音乐播放器,HTML5开发学习(1):使用aduio标签打造音乐播放器

    关于html5的炒作已经有一段时间了,小弟亦是个跟风之人,对该新鲜事物也充满好奇和期待.本文为该系列(html5尝鲜)第一节,先以一个简单的demo开胃,希望能勾起各位同学对html5的兴趣和关注. ...

  7. linux 音频播放器源码,基于Linux的音频播放器的设计 源代码.doc

    嵌入式操作系统 课程设计 源代码 设计题目: 基于Linux的音频播放器的设计 院 系: ********* 班 级: ******** 组 别: 第1组 学 号: ****** 姓 名: 起止日期: ...

  8. 基于python的音频播放器_基于python实现音乐播放器代码实例

    基于python实现音乐播放器代码实例,一首,函数,按钮,布局,音乐 基于python实现音乐播放器代码实例 易采站长站,站长之家为您整理了基于python实现音乐播放器代码实例的相关内容. 核心播放 ...

  9. iOS播放器之基于VLCKit的自定义播放器

    VLC是一款了不起的播放器,很喜欢,功能很强大,目前据我所知能播放RMVB.MKV.mp4.FLV等等格式的视频,分享一个基于VLCKit的自定义播放器 源码地址:https://github.com ...

最新文章

  1. 【深度学习】449页pdf,FaceBook称其迈出“重塑AI科学的第一步”
  2. 调用IOS邮件系统发送邮件
  3. python判断密码强度_python – 检查密码的强度(如何检查条件)
  4. 分享清华大学鲁志教授实验室生物信息学教程
  5. mysql select不走索引_避免写出不走索引的SQL, MySQL
  6. http 标准超时时间_Go 中 http 超时问题的排查
  7. Java 杨辉三角形
  8. 开发者拒绝写技术博客的常见理由
  9. 【贪玩巴斯】无线传感器网络(二)「无线传感器网络中物理层的五点详解」 2021-09-24
  10. Epicor10自定义更新
  11. vob文件怎么转换成mp4?
  12. 数据结构:什么是红黑树?为什么要用红黑树?
  13. 一键复制粘贴工具使用教程
  14. 【无人驾驶 | 国内篇】主要玩家介绍
  15. 计算机应用基础上册周测7,计算机应用基础(第3版)周南岳(win7+office10)期末复习及答案-20210614221003.docx-原创力文档...
  16. uAvionix 获得 FAA 批准进行 C 波段测试,并继续在几个新地点推出 SkyLine C2
  17. 用Java整合Clamav病毒库检测病毒
  18. 做自媒体,有哪些免费下载视频剪辑素材的网站?
  19. css文本与字体样式(基础知识整理)
  20. 项目一.认识Linux操作系统

热门文章

  1. Tyvj P3572 BZOJ 1122 账本BBB
  2. 中国十大“勾魂”美景-戈壁滩、风蚀地貌
  3. 算法经典“可怜的奶牛”问题 使用堆高效组织数据 C语言描述
  4. 简单快速处理网络请求超时的方法
  5. 四种积分双谱算法matlab,MATLAB实现双谱线修正算法
  6. GaussDB200与postgresql相关性
  7. 中国机械式停车设备深度调研与投资战略报告(2021版)
  8. 积分总是遭闲置?看看积分被用户沉淀不用的两个原因
  9. 使用ViewFlipper实现屏幕切换动画效果
  10. dtsi与dts_设备树DTS规范