從最小化返回後directshow播放畫面刷新地疑難

 

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個回答
我暈,還沒解決???

如果可以,請將代碼發我郵箱:[email protected]


第24個回答
不是吧,我也做這播放器,就是這樣搞定的,要是方便將代碼傳給我看看   [email protected]
要是不放便你給個郵件地址也行,我給你傳個例子


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章