]> git.saurik.com Git - wxWidgets.git/blob - src/msw/moviectrl.cpp
Moved deletion of wxPrintFacory to module.
[wxWidgets.git] / src / msw / moviectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/moviectrl.cpp
3 // Purpose: wxMovieCtrl MSW
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 11/07/04
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 //#pragma implementation "moviectrl.h"
14 //#endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #define wxUSE_MOVIECTRL 1
24
25 #if wxUSE_MOVIECTRL
26
27 #include "wx/moviectrl.h"
28 #include "wx/msw/ole/oleutils.h" //for wxBasicString
29
30 #include <dshow.h>
31
32 IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
33
34 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
35
36 #define WM_GRAPHNOTIFY WM_USER+13
37
38 #ifdef __WXDEBUG__
39 #define wxDSVERIFY(x) wxASSERT( SUCCEEDED ((x)) )
40 #else
41 #define wxDSVERIFY(x) (x)
42 #endif
43
44 BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl)
45 EVT_SIZE(wxMovieCtrl::OnSize)
46 // EVT_ACTIVATE(wxMovieCtrl::OnActivate)
47 END_EVENT_TABLE()
48
49 //it's there someplace :)
50 extern "C" WXDLLIMPEXP_BASE HWND
51 wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
52
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)
56 {
57 //cast helpers
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;
65
66 //create our filter graph
67 CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
68 IID_IGraphBuilder, (void**)&pGB);
69
70 //load the graph & render
71 if (FAILED(pGB->RenderFile(fileName.wc_str(wxConvLocal), NULL)))
72 {
73 wxFAIL_MSG("Could not load movie!");
74 return false;
75 }
76
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) );
84
85 //get the _actual_ size of the movie & remember it
86 long nX, nY, nSX, nSY;
87 pVW->GetWindowPosition(&nX,&nY,&nSX,&nSY);
88
89 m_bestSize.x = nSX;
90 m_bestSize.y = nSY;
91
92 //do some window stuff - ORDER IS IMPORTANT
93 //base create
94 if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER | wxCLIP_CHILDREN, wxDefaultValidator, name) )
95 return false;
96
97 //Set our background color to black by default
98 SetBackgroundColour(*wxBLACK);
99
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 :)
104
105 //set the time format
106 wxDSVERIFY( pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME) );
107
108 SetLabel(label);
109 Play();
110
111 return true;
112 }
113
114 void wxMovieCtrl::SetLabel(const wxString& label)
115 {
116 wxControl::SetLabel(label);
117
118 IVideoWindow*& pVW = (IVideoWindow*&) m_pVW;
119
120 //wxBasicString will have a null string on an
121 //empty wxString - gotta love those workarounds!!
122 if(!label.empty())
123 {
124 wxBasicString theBasicString(label.mb_str());
125 wxDSVERIFY( pVW->put_Caption(theBasicString.Get()) );
126 }
127 }
128
129 bool wxMovieCtrl::Play()
130 {
131 return SUCCEEDED( ((IMediaControl*&)m_pMC)->Run() );
132 }
133
134 bool wxMovieCtrl::Pause()
135 {
136 return SUCCEEDED( ((IMediaControl*&)m_pMC)->Pause() );
137 }
138
139 bool wxMovieCtrl::Stop()
140 {
141 return SUCCEEDED( ((IMediaControl*&)m_pMC)->Stop() );
142 }
143
144 #if wxUSE_DATETIME
145
146 bool wxMovieCtrl::Seek(const wxTimeSpan& where)
147 {
148 //DS uses 100 nanos - so we need a 10 mult
149 LONGLONG pos = ((size_t)where.GetMilliseconds().ToLong()) * 10;
150
151 return SUCCEEDED( ((IMediaSeeking*&)m_pMS)->SetPositions(
152 &pos,
153 AM_SEEKING_AbsolutePositioning,
154 NULL,
155 AM_SEEKING_NoPositioning
156 ) );
157 }
158
159 #endif // wxUSE_DATETIME
160
161 wxMovieCtrlState wxMovieCtrl::GetState()
162 {
163 HRESULT hr;
164 OAFilterState theState;
165 hr = ((IMediaControl*&)m_pMC)->GetState(INFINITE, &theState);
166
167 wxASSERT( SUCCEEDED(hr) );
168
169 //MSW state is the same as ours
170 //State_Stopped = 0,
171 //State_Paused = State_Stopped + 1,
172 //State_Running = State_Paused + 1
173
174 return (wxMovieCtrlState) theState;
175 }
176
177 //WXLRESULT wxMovieCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
178 //{
179 /*
180 //cast helpers
181 IMediaControl*& pMC = (IMediaControl*&) m_pMC;
182 IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
183 IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
184
185 if (nMsg == WM_GRAPHNOTIFY)
186 {
187 LONG evCode, evParam1, evParam2;
188 HRESULT hr=S_OK;
189
190 //make sure we exist
191 if (!pME)
192 return S_OK;
193
194 // Process all queued events
195 while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
196 (LONG_PTR *) &evParam2, 0)
197 )
198 )
199 {
200 // Free memory associated with callback, since we're not using it
201 hr = pME->FreeEventParams(evCode, evParam1, evParam2);
202
203 // If this is the end of the clip, reset to beginning
204 if(EC_COMPLETE == evCode)
205 {
206 LONGLONG pos=0;
207
208 // Reset to first frame of movie
209 hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
210 NULL, AM_SEEKING_NoPositioning);
211 if (FAILED(hr))
212 {
213 hr = pMC->Stop();
214 // for filters that don't support seeking do a rewind
215 if (FAILED(hr))
216 {
217 wxFAIL_MSG(
218 wxString::Format(TEXT("Failed(0x%08lx) to stop media clip!\r\n"), hr)
219 );
220 break;
221 }
222
223 hr = hr = pMC->Run();
224
225 if (FAILED(hr))
226 {
227 wxFAIL_MSG(
228 wxString::Format(TEXT("Failed(0x%08lx) to reset media clip!\r\n"), hr)
229 );
230 break;
231 }
232 }
233 }
234 }
235 return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
236 }
237 */
238 //pass the event to our parent
239 // return wxControl::MSWWindowProc(nMsg, wParam, lParam);
240 //}
241
242 wxMovieCtrl::~wxMovieCtrl()
243 {
244 //cast helpers
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;
252
253 // Hide then disown the window
254 if(pVW)
255 {
256 pVW->put_Visible(OAFALSE); //OSFALSE == 0
257 pVW->put_Owner(NULL);
258 }
259
260 // Release and zero DirectShow interfaces
261 SAFE_RELEASE(pME);
262 SAFE_RELEASE(pMS);
263 SAFE_RELEASE(pMC);
264 SAFE_RELEASE(pBA);
265 SAFE_RELEASE(pBV);
266 SAFE_RELEASE(pVW);
267 SAFE_RELEASE(pGB);
268 }
269
270 wxSize wxMovieCtrl::DoGetBestSize() const
271 {
272 return m_bestSize;
273 }
274
275 //
276 //EVENT OVERRIDES
277 //
278
279 void wxMovieCtrl::OnSize(wxSizeEvent& evt)
280 {
281 IVideoWindow*& pVW = (IVideoWindow*&) m_pVW;
282 wxDSVERIFY( pVW->SetWindowPosition(0, 0, evt.GetSize().GetWidth(), evt.GetSize().GetHeight()) );
283
284 evt.Skip();
285 }
286 /*
287 void wxMovieCtrl::OnActivate(wxActivateEvent& evt)
288 {
289 if (evt.GetActive())
290 {
291 //HACK: Make the window show :)
292 SetSize(GetSize());
293 }
294 }
295 */
296
297 #endif //wxUSE_MOVIECTRL