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