从最小化返回后directshow播放画面刷新地疑难

来源:互联网 发布:陈奕迅 圣诞结 知乎 编辑:程序博客网 时间:2024/04/28 08:08

 

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和其他同志的热情相助!


原创粉丝点击