http://www.qqgb.com/Program/VC/VCJQ/Program_176331.html
大家好,我的程序是这样的:一个dialog里面有个picture control, 用来做directshow的视频播放。
开始播放后画面会出来,一切正常。现在的问题是,当此dialog最小化,再恢复时,视频画面一闪而过变成了picture control的底色灰色。只有拖动一下dialog画面才会出来。或者在没有最小化的情况下,直接切换到一个别的最大化的窗口,再切换回来时也会有相同的状况(估计dialog在后台被自动最小化了)。请问如何解决!!
另:
1. 参考了别人播放画面刷新的问题,我重载了OnPaint和OnEraseBkgnd,都分别加了ExcludeClipRec,却没有起任何作用!
2. 当别的未最大化的窗口半遮或全遮住视频窗口,画面都能正常刷新。
谢谢大家!!!! 100
第1个回答
LZ是用的VMR并且工作在Windowless模式下吗?
如果是, 在你的Picture control绘制时WM_PAINT, 通过VMR的IVMRWindowlessControl::RepaintVideo()方法就可以重新绘制了, 具体应用可以参考SDK的Using Windowless Mode章节
你可能需要subclass你的picturel control来处理WM_PAINT, 可以先用一个对话框实验, 在它的OnPaint()中调用RepaintVideo()方法, 有效后再移到Picture control中
第2个回答
我想应该跟OnPaint和OnEraseBkgnd,还有ExcludeClipR都没有关系的.也就是说跟刷新没有关系,应该跟恢复播放控制有关.
曾经做过,不过不大记得了,现在我机器上又没有源码,可能是在OnSize里要做一下恢复正常播放的.
第3个回答
to crumpy: 好像不是你说的这回事。。。
to my_girlf: 你说的好像有道理,但要在OnSize里做什么呢?
第4个回答
这个刷新问题是由于其没有消息循环影起的,可以这样:
1。直接put_owner在窗体上,由窗体的WM_PAINT来刷新
2。修改控件的属性,添加处理消息
3。不使用默认的render filter,手动添加使用VMR9,其自动处理刷新问题
第5个回答
my_girlf说的不对,呵呵,其实你移动下窗体图象可能就出来了
第6个回答
to rageliu:
可能我說的是不對,現在的情況就是要移動下窗體,圖像才能出來。
要移動下窗體,圖像才能出來,這就是LZ本來問的和要解決的問題。
第7个回答
to my_girlf:
我知道他遇到的问题,这个问题做ds的很多人问过,就是刷新的问题,一般由于对IVideoWindow Interface的put_Owner操作后出现的,上面说的几种方法都可以解决
第8个回答
是否可以把播放的函数放在OnPaint()中,这样最小化后在还原就不会没有了.
第9个回答
看了看VC2005, 还是放在OnDraw里比较好, (OnPaint()会调用OnDraw())
第10个回答
to rageliu:
我的代码里已经有了:
pVidWin-> put_Owner((OAHWND)m_hWnd);
pVidWin-> put_WindowStyle(WS_CHILD ¦ WS_CLIPSIBLINGS ¦ WS_CLIPCHILDREN);
然后OnPaint里也有ExcludeClipRec。
是这样吗?但还是不行啊!
第11个回答
就是由于你上面的操作,才会出现问题。
要解决这个问题,你现在可以:
1。直接put_owner在窗体上,由窗体的WM_PAINT来刷新
2。修改控件的属性,添加处理消息
3。不使用默认的render filter,手动添加使用VMR9,其自动处理刷新问题
第12个回答
上面3种方法中的任一种都可以解决,并不是要全部做
第13个回答
不好意思啊我很菜鸟,
第一种方法里你是说dialog窗体吗?pVidWin-> put_Owner((OAHWND)m_hWnd)不就是把dialog窗体作为父窗体了?
第14个回答
对, 你使用IVideoWindow()就按rageliu星星的方法做, 把对话框作为你的IVideoWindow的owner, picture box是子窗口, 没法做其它子窗口的owner
第15个回答
是呀,m_hWnd是dialog的句柄呀,我已经pVidWin-> put_Owner((OAHWND)m_hWnd)了,还是不行!!
希望能再解释一下!!
第16个回答
put_Owner( m_hWnd ); 其中m_hWnd是你的对话框或窗体的HANDLE, 不是子窗体的;
put_WindowStyle( WS_CHILD ¦ WS_CLIPSIBLINGS );
OnPaint()里先不要做任何绘图操作
对话框中的OnEraseBkgnd()改为下面的样子, 再试试:
-
C/C++ code
-
BOOL CYourDlg::OnEraseBkgnd(CDC* pDC) { return TRUE; }
第17个回答
to crumpy:
嗯谢谢啊!我按照你说的做了,现在视频是弄好了,但是对话框的绘图变得一塌糊涂。(现在OnPaint是空的,OnEraseBkgnd里只有return true)
然后我发现OnEraseBkgnd里面如果直接return CDialog::OnEraseBkgnd(pDC); (相当于不重载),视频也是正常的,而且对话框的绘图会稍好一点。看来问题出在OnPaint()里。
然后我又试着在OnPaint里只写CDialog::OnPaint();(也相当于不重载),结果对话框绘图好了,视频又是出现老问题!!
这下该咋办呢??
第18个回答
你可以把视频所占的区域从绘图区中扣出去, 可以在OnEraseBkgnd()中做, 比如用ExcludeClipRect(), 然后在OnPaint()中进行正常的绘图.
推荐使用VMR的Windowless方式 它比传统IVideoWindow要好用.
第19个回答
1、put_Owner((OAHWND)m_hWnd) 还是设置为字窗口的句柄
2、显示控件(就叫m_view吧)得修改属性 m_view.ModifyStyle(0, WS_CLIPCHILDREN);
3、OnPaint 不用动
4、OnEraseBkgnd 加如下代码
RECT rect;
m_view.GetWindowRect(&rect);
ScreenToClient(&rect);
pDC-> ExcludeClipRect(&rect);
return CDialog::OnEraseBkgnd(pDC);
第20个回答
消息循环没处理好。看看务实和开发指南的例子
第21个回答
to crumpy:
我在最早就说了,我在OnEraseBkgnd()或者OnPaint里面加ExcludeClipRect都没用。刚才再试了一下还是不行啊。
to lemon_wei:
你说的我都照样做了,还是不行。特别是加了m_view.ModifyStyle(0, WS_CLIPCHILDREN)之后,刚开始播也没有画面,也要拖一下才有,越来越糟了。(原本是ModifyStyle(0, WS_CLIPCHILDREN),即对对话框modify style)。
---------------
看来也没能解决我的问题,再等等就结贴算了。
第22个回答
有没有试过用LPDIRECTDRAWSURFACE2,
LPDIRECTDRAWSURFACE2-> UpdateOverlay(...);
这个可以保证画面始终在你需要的图层上刷新!
第23个回答
我晕,还没解决???
如果可以,请将代码发我邮箱:rageliu@sina.com
第24个回答
不是吧,我也做这播放器,就是这样搞定的,要是方便将代码传给我看看 wei56958@163.com
要是不放便你给个邮件地址也行,我给你传个例子
第25个回答
to rageliu, lemon_wei:
我已经将代码发给两位了,多谢帮助!!!
第26个回答
邮件已收到,已回复,请查收。
第27个回答
LZ,如何解决的,正好我也有这样的问题
第28个回答
在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);
---------------
结贴。再次感谢lemon_wei和其他同志的热情相助!