用directshow编写了一个简单的媒体播放器,遇到了网上很多网都遇到的问题,程序运行后有声音,但无图像,把窗口移动一下以后图像又显示出来了,困扰了好几天,在网上查资料,下面是查到的相关结果:
http://www.qqgb.com/Program/VC/VCJQ/Program_177692_2.html
http://topic.csdn.net/u/20080221/21/5ee17fc6-d14c-41d5-861d-5c09ec862681.html
大家好,我的程序是这样的:一个dialog里面有个picture control, 用来做directshow的视频播放。
开始播放后画面会出来,一切正常。现在的问题是,当此dialog最小化,再恢复时,视频画面一闪而过变成了picture control的底色灰色。只有拖动一下dialog画面才会出来。或者在没有最小化的情况下,直接切换到一个别的最大化的窗口,再切换回来时也会有相同的状况(估计dialog在后台被自动最小化了)。请问如何解决!!
另:
1. 参考了别人播放画面刷新的问题,我重载了OnPaint和OnEraseBkgnd,都分别加了ExcludeClipRec,却没有起任何作用!
2. 当别的未最大化的窗口半遮或全遮住视频窗口,画面都能正常刷新。
LZ是用的VMR并且工作在Windowless模式下吗?
如果是, 在你的Picture control绘制时WM_PAINT, 通过VMR的IVMRWindowlessControl::RepaintVideo()方法就可以重新绘制了, 具体应用可以参考SDK的Using Windowless Mode章节
你可能需要subclass你的picturel control来处理WM_PAINT, 可以先用一个对话框实验, 在它的OnPaint()中调用RepaintVideo()方法, 有效后再移到Picture control中
我想应该跟OnPaint和OnEraseBkgnd,还有ExcludeClipR都没有关系的.也就是说跟刷新没有关系,应该跟恢复播放控制有关.
曾经做过,不过不大记得了,现在我机器上又没有源码,可能是在OnSize里要做一下恢复正常播放的.
这个刷新问题是由于其没有消息循环影起的,可以这样:
1。直接put_owner在窗体上,由窗体的WM_PAINT来刷新
2。修改控件的属性,添加处理消息
3。不使用默认的render filter,手动添加使用VMR9,其自动处理刷新问题
在lemon_wei的热情帮助下,问题终于圆满解决了!
lemon_wei之前的回复是正确的,我稍作修改减少歧义,现总结如下,希望也能够帮助到以后遇到此问题的人:
假定视频窗口的picture控件id为IDC_VW_FRAME, pVidWin为IVideoWindow* 接口,做以下4步:
1、pVidWin->put_Owner((OAHWND)GetDlgItem(IDC_VW_FRAME)->GetSafeHwnd());
2、GetDlgItem(IDC_VW_FRAME)->ModifyStyle(0, WS_CLIPCHILDREN);
3、OnPaint 不用动
4、OnEraseBkgnd 加如下代码
RECT rect;
GetDlgItem(IDC_VW_FRAME)->GetWindowRect(&rect);
ScreenToClient(&rect);
pDC-> ExcludeClipRect(&rect);
return CDialog::OnEraseBkgnd(pDC);
---------------
其实最关键的还是上面紫颜色的那一句,
GetDlgItem(IDC_VW_FRAME)->ModifyStyle(0, WS_CLIPCHILDREN);
在陆其明书里其实已经讲清楚了:
为了让视频窗口正常刷新,我们还必须修改视频窗口的风格,即在主对话框的初始化函数OinitDialog中增加如下函数调用:
mVideoWindow.Modifystyle(0,WS_CLIPCHILDREN);
就可以了
转自: http://hi.baidu.com/hainei_/blog/item/3eded17240046e118601b070.html