1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/moviectrl.cpp
3 // Purpose: wxMovieCtrl MSW
4 // Author: Ryan Norton <wxprojects@comcast.net>
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 //#pragma implementation "moviectrl.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #define wxUSE_MOVIECTRL 1
27 #include "wx/moviectrl.h"
28 #include "wx/msw/ole/oleutils.h" //for wxBasicString
32 IMPLEMENT_CLASS(wxMovieCtrl
, wxControl
);
34 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
36 #define WM_GRAPHNOTIFY WM_USER+13
39 #define wxDSVERIFY(x) wxASSERT( SUCCEEDED ((x)) )
41 #define wxDSVERIFY(x) (x)
44 BEGIN_EVENT_TABLE(wxMovieCtrl
, wxControl
)
45 EVT_SIZE(wxMovieCtrl::OnSize
)
46 // EVT_ACTIVATE(wxMovieCtrl::OnActivate)
49 //it's there someplace :)
50 extern "C" WXDLLIMPEXP_BASE HWND
51 wxCreateHiddenWindow(LPCTSTR
*pclassname
, LPCTSTR classname
, WNDPROC wndproc
);
53 bool wxMovieCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxString
& fileName
,
54 const wxString
& label
, const wxPoint
& pos
, const wxSize
& size
,
55 long style
, const wxString
& name
)
58 IGraphBuilder
*& pGB
= (IGraphBuilder
*&) m_pGB
;
59 IMediaControl
*& pMC
= (IMediaControl
*&) m_pMC
;
60 IMediaEventEx
*& pME
= (IMediaEventEx
*&) m_pME
;
61 IVideoWindow
*& pVW
= (IVideoWindow
*&) m_pVW
;
62 IBasicAudio
*& pBA
= (IBasicAudio
*&) m_pBA
;
63 IBasicVideo
*& pBV
= (IBasicVideo
*&) m_pBV
;
64 IMediaSeeking
*& pMS
= (IMediaSeeking
*&) m_pMS
;
66 //create our filter graph
67 CoCreateInstance(CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
68 IID_IGraphBuilder
, (void**)&pGB
);
70 //load the graph & render
71 if (FAILED(pGB
->RenderFile(fileName
.wc_str(wxConvLocal
), NULL
)))
73 wxFAIL_MSG("Could not load movie!");
77 //get the interfaces, all of them
78 wxDSVERIFY( pGB
->QueryInterface(IID_IMediaControl
, (void**)&pMC
) );
79 wxDSVERIFY( pGB
->QueryInterface(IID_IMediaEventEx
, (void**)&pME
) );
80 wxDSVERIFY( pGB
->QueryInterface(IID_IMediaSeeking
, (void**)&pMS
) );
81 wxDSVERIFY( pGB
->QueryInterface(IID_IVideoWindow
, (void**)&pVW
) );
82 wxDSVERIFY( pGB
->QueryInterface(IID_IBasicAudio
, (void**)&pBA
) );
83 wxDSVERIFY( pGB
->QueryInterface(IID_IBasicVideo
, (void**)&pBV
) );
85 //get the _actual_ size of the movie & remember it
86 long nX
, nY
, nSX
, nSY
;
87 pVW
->GetWindowPosition(&nX
,&nY
,&nSX
,&nSY
);
92 //do some window stuff - ORDER IS IMPORTANT
94 if ( !wxControl::Create(parent
, id
, pos
, size
, wxNO_BORDER
| wxCLIP_CHILDREN
, wxDefaultValidator
, name
) )
97 //Set our background color to black by default
98 SetBackgroundColour(*wxBLACK
);
100 wxDSVERIFY( pVW
->put_Owner((OAHWND
)this->GetHandle()) );
101 wxDSVERIFY( pVW
->put_WindowStyle(WS_CHILD
| WS_CLIPSIBLINGS
) );
102 // wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) );
103 wxDSVERIFY( pVW
->put_Visible(OATRUE
) ); //OATRUE actually == -1 :)
105 //set the time format
106 wxDSVERIFY( pMS
->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME
) );
114 void wxMovieCtrl::SetLabel(const wxString
& label
)
116 wxControl::SetLabel(label
);
118 IVideoWindow
*& pVW
= (IVideoWindow
*&) m_pVW
;
120 //wxBasicString will have a null string on an
121 //empty wxString - gotta love those workarounds!!
124 wxBasicString
theBasicString(label
.mb_str());
125 wxDSVERIFY( pVW
->put_Caption(theBasicString
.Get()) );
129 bool wxMovieCtrl::Play()
131 return SUCCEEDED( ((IMediaControl
*&)m_pMC
)->Run() );
134 bool wxMovieCtrl::Pause()
136 return SUCCEEDED( ((IMediaControl
*&)m_pMC
)->Pause() );
139 bool wxMovieCtrl::Stop()
141 return SUCCEEDED( ((IMediaControl
*&)m_pMC
)->Stop() );
146 bool wxMovieCtrl::Seek(const wxTimeSpan
& where
)
148 //DS uses 100 nanos - so we need a 10 mult
149 LONGLONG pos
= ((size_t)where
.GetMilliseconds().ToLong()) * 10;
151 return SUCCEEDED( ((IMediaSeeking
*&)m_pMS
)->SetPositions(
153 AM_SEEKING_AbsolutePositioning
,
155 AM_SEEKING_NoPositioning
159 #endif // wxUSE_DATETIME
161 wxMovieCtrlState
wxMovieCtrl::GetState()
164 OAFilterState theState
;
165 hr
= ((IMediaControl
*&)m_pMC
)->GetState(INFINITE
, &theState
);
167 wxASSERT( SUCCEEDED(hr
) );
169 //MSW state is the same as ours
171 //State_Paused = State_Stopped + 1,
172 //State_Running = State_Paused + 1
174 return (wxMovieCtrlState
) theState
;
177 //WXLRESULT wxMovieCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
181 IMediaControl*& pMC = (IMediaControl*&) m_pMC;
182 IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
183 IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
185 if (nMsg == WM_GRAPHNOTIFY)
187 LONG evCode, evParam1, evParam2;
194 // Process all queued events
195 while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
196 (LONG_PTR *) &evParam2, 0)
200 // Free memory associated with callback, since we're not using it
201 hr = pME->FreeEventParams(evCode, evParam1, evParam2);
203 // If this is the end of the clip, reset to beginning
204 if(EC_COMPLETE == evCode)
208 // Reset to first frame of movie
209 hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
210 NULL, AM_SEEKING_NoPositioning);
214 // for filters that don't support seeking do a rewind
218 wxString::Format(TEXT("Failed(0x%08lx) to stop media clip!\r\n"), hr)
223 hr = hr = pMC->Run();
228 wxString::Format(TEXT("Failed(0x%08lx) to reset media clip!\r\n"), hr)
235 return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
238 //pass the event to our parent
239 // return wxControl::MSWWindowProc(nMsg, wParam, lParam);
242 wxMovieCtrl::~wxMovieCtrl()
245 IGraphBuilder
*& pGB
= (IGraphBuilder
*&) m_pGB
;
246 IMediaControl
*& pMC
= (IMediaControl
*&) m_pMC
;
247 IMediaEventEx
*& pME
= (IMediaEventEx
*&) m_pME
;
248 IVideoWindow
*& pVW
= (IVideoWindow
*&) m_pVW
;
249 IBasicAudio
*& pBA
= (IBasicAudio
*&) m_pBA
;
250 IBasicVideo
*& pBV
= (IBasicVideo
*&) m_pBV
;
251 IMediaSeeking
*& pMS
= (IMediaSeeking
*&) m_pMS
;
253 // Hide then disown the window
256 pVW
->put_Visible(OAFALSE
); //OSFALSE == 0
257 pVW
->put_Owner(NULL
);
260 // Release and zero DirectShow interfaces
270 wxSize
wxMovieCtrl::DoGetBestSize() const
279 void wxMovieCtrl::OnSize(wxSizeEvent
& evt
)
281 IVideoWindow
*& pVW
= (IVideoWindow
*&) m_pVW
;
282 wxDSVERIFY( pVW
->SetWindowPosition(0, 0, evt
.GetSize().GetWidth(), evt
.GetSize().GetHeight()) );
287 void wxMovieCtrl::OnActivate(wxActivateEvent& evt)
291 //HACK: Make the window show :)
297 #endif //wxUSE_MOVIECTRL