]> git.saurik.com Git - wxWidgets.git/blob - src/msw/mediactrl.cpp
wxUSE_POSTSCRIPT is not a sufficient test by itself for
[wxWidgets.git] / src / msw / mediactrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/mediactrl.cpp
3 // Purpose: wxMediaCtrl 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 //---------------------------------------------------------------------------
13 // Pre-wx includes
14 //---------------------------------------------------------------------------
15
16 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 //#pragma implementation "moviectrl.h"
18 //#endif
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #include "wx/mediactrl.h"
28
29 #if wxUSE_MEDIACTRL
30
31 //###########################################################################
32 // DECLARATIONS
33 //###########################################################################
34
35 IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
36 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
37 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
38
39 //---------------------------------------------------------------------------
40 // wxMediaCtrlImpl
41 //---------------------------------------------------------------------------
42
43 class wxMediaCtrlImpl
44 {
45 public:
46 wxMediaCtrlImpl() : m_bLoaded(false)
47 { }
48
49 virtual ~wxMediaCtrlImpl()
50 { }
51
52 virtual bool Create(wxMediaCtrl* WXUNUSED(ctrl))
53 { return false; }
54
55 virtual bool Play() { return false; }
56 virtual bool Pause() { return false; }
57 virtual bool Stop() { return false; }
58
59 virtual bool Load(const wxString&) { return false; }
60 virtual bool Load(const wxURI&) { return false; }
61
62 virtual wxMediaState GetState() { return wxMEDIASTATE_STOPPED; }
63
64 virtual bool SetPosition(long) { return 0; }
65 virtual long GetPosition() { return 0; }
66 virtual long GetDuration() { return 0; }
67
68 virtual void DoMoveWindow(int, int, int, int) { }
69 virtual wxSize DoGetBestSize() const { return wxSize(0,0); }
70
71 virtual double GetPlaybackRate() { return 0; }
72 virtual bool SetPlaybackRate(double) { return false; }
73
74 virtual bool MSWWindowProc(WXUINT, WXWPARAM, WXLPARAM) { return false; }
75
76 bool IsLoaded()
77 { return m_bLoaded; }
78
79 bool m_bLoaded;
80 };
81
82 //---------------------------------------------------------------------------
83 // wxDXMediaCtrlImpl
84 //---------------------------------------------------------------------------
85
86 #if wxUSE_DIRECTSHOW
87
88 #include <dshow.h>
89
90 #define WM_GRAPHNOTIFY WM_USER+13
91
92 #ifdef __WXDEBUG__
93 #define wxDSVERIFY(x) wxASSERT( SUCCEEDED ((x)) )
94 #else
95 #define wxDSVERIFY(x) (x)
96 #endif
97
98 class wxDXMediaCtrlImpl : public wxMediaCtrlImpl
99 {
100 public:
101 wxDXMediaCtrlImpl();
102
103 virtual ~wxDXMediaCtrlImpl();
104
105 virtual bool Create(wxMediaCtrl* ctrl);
106
107 virtual bool Play();
108 virtual bool Pause();
109 virtual bool Stop();
110
111 virtual bool Load(const wxString& fileName);
112 virtual bool Load(const wxURI& location);
113
114 virtual wxMediaState GetState();
115
116 virtual bool SetPosition(long where);
117 virtual long GetPosition();
118 virtual long GetDuration();
119
120 virtual void DoMoveWindow(int x, int y, int w, int h);
121 wxSize DoGetBestSize() const;
122
123 virtual double GetPlaybackRate();
124 virtual bool SetPlaybackRate(double);
125
126 void Cleanup();
127
128 bool m_bVideo;
129
130 bool MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
131
132 wxMediaCtrl* m_ctrl;
133
134 IGraphBuilder* m_pGB;
135 IMediaControl* m_pMC;
136 IMediaEventEx* m_pME;
137 IVideoWindow* m_pVW;
138 IBasicAudio* m_pBA;
139 IBasicVideo* m_pBV;
140 IMediaSeeking* m_pMS;
141
142 wxSize m_bestSize;
143 };
144
145 #endif //wxUSE_DIRECTSHOW
146
147 //---------------------------------------------------------------------------
148 // wxWMMEMediaCtrlImpl
149 //---------------------------------------------------------------------------
150
151 #include <mmsystem.h>
152
153 class wxWMMEMediaCtrlImpl : public wxMediaCtrlImpl
154 {
155 public:
156
157 wxWMMEMediaCtrlImpl();
158 ~wxWMMEMediaCtrlImpl();
159
160 virtual bool Create(wxMediaCtrl* ctrl);
161
162 virtual bool Play();
163 virtual bool Pause();
164 virtual bool Stop();
165
166 virtual bool Load(const wxString& fileName);
167 virtual bool Load(const wxURI& location);
168
169 virtual wxMediaState GetState();
170
171 virtual bool SetPosition(long where);
172 virtual long GetPosition();
173 virtual long GetDuration();
174
175 virtual void DoMoveWindow(int x, int y, int w, int h);
176 wxSize DoGetBestSize() const;
177
178 virtual double GetPlaybackRate();
179 virtual bool SetPlaybackRate(double);
180
181 bool MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
182
183 MCIDEVICEID m_hDev;
184 wxMediaCtrl* m_ctrl;
185 bool m_bVideo;
186 };
187
188 //###########################################################################
189 //
190 // IMPLEMENTATION
191 //
192 //###########################################################################
193
194 //---------------------------------------------------------------------------
195 //
196 // wxMediaCtrl
197 //
198 //---------------------------------------------------------------------------
199
200 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName,
201 const wxPoint& pos, const wxSize& size,
202 long style, long WXUNUSED(driver), const wxString& name)
203 {
204 //base create
205 if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
206 wxDefaultValidator, name) )
207 return false;
208
209 //Set our background color to black by default
210 SetBackgroundColour(*wxBLACK);
211
212 #if wxUSE_DIRECTSHOW
213 m_imp = new wxDXMediaCtrlImpl;
214 if(!m_imp->Create(this))
215 {
216 delete m_imp;
217 #endif
218 m_imp = new wxWMMEMediaCtrlImpl;
219 if(!m_imp->Create(this))
220 {
221 delete m_imp;
222 m_imp = NULL;
223 return false;
224 }
225 #if wxUSE_DIRECTSHOW
226 }
227 #endif
228
229 if(!fileName.empty())
230 {
231 if (!Load(fileName))
232 return false;
233 }
234
235 return true;
236 }
237
238 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxURI& location,
239 const wxPoint& pos, const wxSize& size,
240 long style, long WXUNUSED(driver), const wxString& name)
241 {
242 //base create
243 if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
244 wxDefaultValidator, name) )
245 return false;
246
247 //Set our background color to black by default
248 SetBackgroundColour(*wxBLACK);
249
250 #if wxUSE_DIRECTSHOW
251 m_imp = new wxDXMediaCtrlImpl;
252 if(!m_imp->Create(this))
253 {
254 delete m_imp;
255 #endif
256 m_imp = new wxWMMEMediaCtrlImpl;
257 if(!m_imp->Create(this))
258 {
259 delete m_imp;
260 m_imp = NULL;
261 return false;
262 }
263 #if wxUSE_DIRECTSHOW
264 }
265 #endif
266
267 if (!Load(location))
268 return false;
269
270 return true;
271 }
272
273 bool wxMediaCtrl::Load(const wxString& fileName)
274 {
275 if(m_imp)
276 return m_imp->Load(fileName);
277 return false;
278 }
279
280 bool wxMediaCtrl::Load(const wxURI& location)
281 {
282 if(m_imp)
283 return m_imp->Load(location);
284 return false;
285 }
286
287 bool wxMediaCtrl::Play()
288 {
289 if(m_imp && m_imp->IsLoaded())
290 return m_imp->Play();
291 return false;
292 }
293
294 bool wxMediaCtrl::Pause()
295 {
296 if(m_imp && m_imp->IsLoaded())
297 return m_imp->Pause();
298 return false;
299 }
300
301 bool wxMediaCtrl::Stop()
302 {
303 if(m_imp && m_imp->IsLoaded())
304 return m_imp->Stop();
305 return false;
306 }
307
308 double wxMediaCtrl::GetPlaybackRate()
309 {
310 if(m_imp && m_imp->IsLoaded())
311 return m_imp->GetPlaybackRate();
312 return 0;
313 }
314
315 bool wxMediaCtrl::SetPlaybackRate(double dRate)
316 {
317 if(m_imp && m_imp->IsLoaded())
318 return m_imp->SetPlaybackRate(dRate);
319 return false;
320 }
321
322 bool wxMediaCtrl::SetPosition(long where)
323 {
324 if(m_imp && m_imp->IsLoaded())
325 return m_imp->SetPosition(where);
326 return false;
327 }
328
329 long wxMediaCtrl::GetPosition()
330 {
331 if(m_imp && m_imp->IsLoaded())
332 return m_imp->GetPosition();
333 return 0;
334 }
335
336 long wxMediaCtrl::GetDuration()
337 {
338 if(m_imp && m_imp->IsLoaded())
339 return m_imp->GetDuration();
340 return 0;
341 }
342
343 wxMediaState wxMediaCtrl::GetState()
344 {
345 if(m_imp && m_imp->IsLoaded())
346 return m_imp->GetState();
347 return wxMEDIASTATE_STOPPED;
348 }
349
350 WXLRESULT wxMediaCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
351 {
352 if(m_imp && m_imp->IsLoaded() && m_imp->MSWWindowProc(nMsg, wParam, lParam) )
353 return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
354 //pass the event to our parent
355 return wxControl::MSWWindowProc(nMsg, wParam, lParam);
356 }
357
358 wxSize wxMediaCtrl::DoGetBestSize() const
359 {
360 if(m_imp && m_imp->IsLoaded())
361 return m_imp->DoGetBestSize();
362 return wxSize(0,0);
363 }
364
365 void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
366 {
367 wxControl::DoMoveWindow(x,y,w,h);
368
369 if(m_imp && m_imp->IsLoaded())
370 m_imp->DoMoveWindow(x, y, w, h);
371 }
372
373 wxMediaCtrl::~wxMediaCtrl()
374 {
375 if (m_imp)
376 delete m_imp;
377 }
378
379
380 //---------------------------------------------------------------------------
381 //
382 // wxDXMediaCtrlImpl
383 //
384 //---------------------------------------------------------------------------
385
386 #if wxUSE_DIRECTSHOW
387
388 wxDXMediaCtrlImpl::wxDXMediaCtrlImpl() : m_pGB(NULL)
389 {
390 }
391
392 bool wxDXMediaCtrlImpl::Create(wxMediaCtrl* ctrl)
393 {
394 //create our filter graph
395 HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
396 IID_IGraphBuilder, (void**)&m_pGB);
397
398 //directshow not installed?
399 if ( FAILED(hr) )
400 return false;
401
402 m_ctrl = ctrl;
403
404 return true;
405 }
406
407 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
408
409 bool wxDXMediaCtrlImpl::Load(const wxString& fileName)
410 {
411 if(m_bLoaded)
412 Cleanup();
413
414 SAFE_RELEASE(m_pGB);
415
416 CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
417 IID_IGraphBuilder, (void**)&m_pGB);
418
419 //load the graph & render
420 if( FAILED(m_pGB->RenderFile(fileName.wc_str(wxConvLocal), NULL)) )
421 return false;
422
423 //get the interfaces, all of them
424 wxDSVERIFY( m_pGB->QueryInterface(IID_IMediaControl, (void**)&m_pMC) );
425 wxDSVERIFY( m_pGB->QueryInterface(IID_IMediaEventEx, (void**)&m_pME) );
426 wxDSVERIFY( m_pGB->QueryInterface(IID_IMediaSeeking, (void**)&m_pMS) );
427 wxDSVERIFY( m_pGB->QueryInterface(IID_IVideoWindow, (void**)&m_pVW) );
428 wxDSVERIFY( m_pGB->QueryInterface(IID_IBasicAudio, (void**)&m_pBA) );
429 wxDSVERIFY( m_pGB->QueryInterface(IID_IBasicVideo, (void**)&m_pBV) );
430
431 //long lVolume;
432 //pBA->get_Volume(&lVolume);
433 //E_NOTIMPL
434
435 //get the _actual_ size of the movie & remember it
436 long nX, nY, nSX, nSY;
437 if (FAILED(m_pVW->GetWindowPosition(&nX,&nY,&nSX,&nSY)))
438 {
439 m_bVideo = false;
440
441 nSX = nSY = 0;
442 }
443 else
444 {
445 m_bVideo = true;
446 }
447
448 m_bestSize.x = nSX;
449 m_bestSize.y = nSY;
450
451 if (m_bVideo)
452 {
453 wxDSVERIFY( m_pVW->put_Owner((OAHWND)m_ctrl->GetHandle()) );
454 wxDSVERIFY( m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) );
455 wxDSVERIFY( m_pVW->put_Visible(OATRUE) ); //OATRUE == -1
456 }
457
458 //make it so that wxEVT_MOVIE_FINISHED works
459 wxDSVERIFY( m_pME->SetNotifyWindow((OAHWND)m_ctrl->GetHandle(), WM_GRAPHNOTIFY, 0) );
460
461 //set the time format
462 wxDSVERIFY( m_pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME) );
463
464 //so that DoGetBestSize will work :)
465 m_bLoaded = true;
466
467 //work around refresh issues
468 m_ctrl->InvalidateBestSize();
469 m_ctrl->GetParent()->Layout();
470 m_ctrl->GetParent()->Refresh();
471 m_ctrl->GetParent()->Update();
472
473 return true;
474 }
475
476 bool wxDXMediaCtrlImpl::Load(const wxURI& location)
477 {
478 return Load(location.BuildUnescapedURI());
479 }
480
481 bool wxDXMediaCtrlImpl::Play()
482 {
483 return SUCCEEDED( m_pMC->Run() );
484 }
485
486 bool wxDXMediaCtrlImpl::Pause()
487 {
488 return SUCCEEDED( m_pMC->Pause() );
489 }
490
491 bool wxDXMediaCtrlImpl::Stop()
492 {
493 bool bOK = SUCCEEDED( m_pMC->Stop() );
494
495 //We don't care if it can't get to the beginning in directshow -
496 //it could be a non-seeking filter (wince midi) in which case playing
497 //starts all over again
498 SetPosition(0);
499 return bOK;
500 }
501
502 bool wxDXMediaCtrlImpl::SetPosition(long where)
503 {
504 //DS uses 100 nanos - so we need a 10 mult
505 LONGLONG pos = ((LONGLONG)where) * 10000;
506
507 return SUCCEEDED( m_pMS->SetPositions(
508 &pos,
509 AM_SEEKING_AbsolutePositioning,
510 NULL,
511 AM_SEEKING_NoPositioning
512 ) );
513 }
514
515 long wxDXMediaCtrlImpl::GetPosition()
516 {
517 LONGLONG outCur, outStop;
518 wxDSVERIFY( m_pMS->GetPositions(&outCur, &outStop) );
519
520 //h,m,s,milli - outdur is in 100 nanos
521 return outCur/10000;
522 }
523
524 long wxDXMediaCtrlImpl::GetDuration()
525 {
526 LONGLONG outDuration;
527 wxDSVERIFY( m_pMS->GetDuration(&outDuration) );
528
529 //h,m,s,milli - outdur is in 100 nanos
530 return outDuration/10000;
531 }
532
533 wxMediaState wxDXMediaCtrlImpl::GetState()
534 {
535 //TODO: MS recommends against INFINITE here - do it in stages
536 HRESULT hr;
537 OAFilterState theState;
538 hr = m_pMC->GetState(INFINITE, &theState);
539
540 wxASSERT( SUCCEEDED(hr) );
541
542 //MSW state is the same as ours
543 //State_Stopped = 0,
544 //State_Paused = State_Stopped + 1,
545 //State_Running = State_Paused + 1
546
547 return (wxMediaState) theState;
548 }
549
550 double wxDXMediaCtrlImpl::GetPlaybackRate()
551 {
552 double dRate;
553 wxDSVERIFY( m_pMS->GetRate(&dRate) );
554 return dRate;
555 }
556
557 bool wxDXMediaCtrlImpl::SetPlaybackRate(double dRate)
558 {
559 return SUCCEEDED( m_pMS->SetRate(dRate) );
560 }
561
562 bool wxDXMediaCtrlImpl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
563 {
564 if (nMsg == WM_GRAPHNOTIFY)
565 {
566 LONG evCode, evParam1, evParam2;
567 HRESULT hr=S_OK;
568
569 // Process all queued events
570 while(SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
571 (LONG_PTR *) &evParam2, 0)
572 )
573 )
574 {
575 // Free memory associated with callback, since we're not using it
576 hr = m_pME->FreeEventParams(evCode, evParam1, evParam2);
577
578 // If this is the end of the clip, notify handler
579 if(EC_COMPLETE == evCode)
580 {
581 //Interestingly enough, DirectShow does not actually stop
582 //the filters - even when it reaches the end!
583 #ifdef __WXDEBUG__
584 wxASSERT( Stop() );
585 #else
586 Stop();
587 #endif
588
589 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, m_ctrl->GetId());
590 m_ctrl->GetParent()->ProcessEvent(theEvent);
591 }
592 }
593 return true;
594 }
595 return false;
596 }
597
598 void wxDXMediaCtrlImpl::Cleanup()
599 {
600 // Hide then disown the window
601 if(m_pVW)
602 {
603 m_pVW->put_Visible(OAFALSE); //OSFALSE == 0
604 m_pVW->put_Owner(NULL);
605 }
606
607 // Release and zero DirectShow interfaces
608 SAFE_RELEASE(m_pME);
609 SAFE_RELEASE(m_pMS);
610 SAFE_RELEASE(m_pMC);
611 SAFE_RELEASE(m_pBA);
612 SAFE_RELEASE(m_pBV);
613 SAFE_RELEASE(m_pVW);
614 }
615
616 wxDXMediaCtrlImpl::~wxDXMediaCtrlImpl()
617 {
618 if (m_bLoaded)
619 Cleanup();
620
621 SAFE_RELEASE(m_pGB);
622 }
623
624 wxSize wxDXMediaCtrlImpl::DoGetBestSize() const
625 {
626 return m_bestSize;
627 }
628
629 void wxDXMediaCtrlImpl::DoMoveWindow(int x, int y, int w, int h)
630 {
631 if(m_bLoaded && m_bVideo)
632 {
633 wxDSVERIFY( m_pVW->SetWindowPosition(0, 0, w, h) );
634 }
635 }
636
637 #endif //wxUSE_DIRECTSHOW
638
639 //---------------------------------------------------------------------------
640 //
641 // wxWMMEMediaCtrlImpl
642 //
643 //---------------------------------------------------------------------------
644
645 //
646 // Cruft to simulate digitalv.h
647 //
648
649 typedef struct {
650 DWORD_PTR dwCallback;
651 #ifdef MCI_USE_OFFEXT
652 POINT ptOffset;
653 POINT ptExtent;
654 #else
655 RECT rc;
656 #endif
657 } MCI_DGV_RECT_PARMS;
658
659 typedef struct {
660 DWORD_PTR dwCallback;
661 HWND hWnd;
662 #ifndef _WIN32
663 WORD wReserved1;
664 #endif
665 UINT nCmdShow;
666 #ifndef _WIN32
667 WORD wReserved2;
668 #endif
669 LPSTR lpstrText;
670 } MCI_DGV_WINDOW_PARMSA;
671
672 typedef struct {
673 DWORD_PTR dwCallback;
674 HWND hWnd;
675 #ifndef _WIN32
676 WORD wReserved1;
677 #endif
678 UINT nCmdShow;
679 #ifndef _WIN32
680 WORD wReserved2;
681 #endif
682 LPWSTR lpstrText;
683 } MCI_DGV_WINDOW_PARMSW;
684 #ifdef UNICODE
685 typedef MCI_DGV_WINDOW_PARMSW MCI_DGV_WINDOW_PARMS;
686 #else
687 typedef MCI_DGV_WINDOW_PARMSA MCI_DGV_WINDOW_PARMS;
688 #endif // UNICODE
689
690 wxWMMEMediaCtrlImpl::wxWMMEMediaCtrlImpl() : m_bVideo(false)
691 {
692 /* TCHAR sz[5000];
693 mciGetErrorString(nError, sz, 5000);
694 wxMessageBox(wxString::Format(_T("Error:%s"), sz));
695 */
696 }
697
698 wxWMMEMediaCtrlImpl::~wxWMMEMediaCtrlImpl()
699 {
700 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
701 }
702
703 bool wxWMMEMediaCtrlImpl::Create(wxMediaCtrl* ctrl)
704 {
705 m_ctrl = ctrl;
706 return true;
707 }
708
709 bool wxWMMEMediaCtrlImpl::Load(const wxString& fileName)
710 {
711 if(m_bLoaded)
712 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
713
714 MCI_OPEN_PARMS openParms;
715 MCI_SET_PARMS setParms;
716
717 openParms.lpstrElementName = (wxChar*) fileName.c_str();
718
719 //Here's where the trick lies - if you don't specify MCI_OPEN_TYPE,
720 //then it actually automagically finds the device for you!
721 if ( mciSendCommand(0, MCI_OPEN,
722 MCI_OPEN_ELEMENT,
723 (DWORD)(LPVOID)&openParms) != 0)
724 return false;
725
726 m_hDev = openParms.wDeviceID;
727
728 setParms.dwCallback = 0;
729 setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
730
731 if (mciSendCommand(m_hDev, MCI_SET, MCI_SET_TIME_FORMAT,
732 (DWORD)(LPVOID)&setParms) != 0)
733 return false;
734
735 MCI_DGV_WINDOW_PARMS windowParms;
736
737 windowParms.hWnd = (HWND)m_ctrl->GetHandle();
738 m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
739 0x00010000L //MCI_DGV_WINDOW_HWND
740 ,
741 (DWORD)(LPVOID)&windowParms) == 0);
742 m_bLoaded = true;
743
744 //work around refresh issues
745 m_ctrl->InvalidateBestSize();
746 m_ctrl->GetParent()->Layout();
747 m_ctrl->GetParent()->Refresh();
748 m_ctrl->GetParent()->Update();
749
750 return true;
751 }
752
753 bool wxWMMEMediaCtrlImpl::Load(const wxURI& WXUNUSED(location))
754 {
755 return false;
756 }
757
758 bool wxWMMEMediaCtrlImpl::Play()
759 {
760 //the directshow driver ("mpegvideo") will crash if we don't do a playParms here
761 MCI_PLAY_PARMS playParms;
762 playParms.dwCallback = (WORD)(HWND)m_ctrl->GetHWND();
763 bool bOK = mciSendCommand(m_hDev, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&playParms) == 0;
764 return (bOK) ;/*||
765 (mciSendCommand(m_hDev, MCI_RESUME, 0, 0) == 0);*/
766 }
767
768 bool wxWMMEMediaCtrlImpl::Pause()
769 {
770 return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
771 }
772
773 bool wxWMMEMediaCtrlImpl::Stop()
774 {
775 return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0) &&
776 (mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
777 }
778
779
780 wxMediaState wxWMMEMediaCtrlImpl::GetState()
781 {
782 MCI_STATUS_PARMS statusParms;
783 statusParms.dwItem = MCI_STATUS_MODE;
784 mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
785 (DWORD)(LPVOID)&statusParms);
786
787 if(statusParms.dwReturn == MCI_MODE_PAUSE)
788 return wxMEDIASTATE_PAUSED;
789 else if(statusParms.dwReturn == MCI_MODE_PLAY)
790 return wxMEDIASTATE_PLAYING;
791 else
792 return wxMEDIASTATE_STOPPED;
793 }
794
795 bool wxWMMEMediaCtrlImpl::SetPosition(long where)
796 {
797 MCI_SEEK_PARMS seekParms;
798 seekParms.dwCallback = 0;
799 seekParms.dwTo = where;
800
801 bool bReplay = GetState() == wxMEDIASTATE_PLAYING;
802
803 if( mciSendCommand(m_hDev, MCI_SEEK, MCI_TO, (DWORD)(LPVOID)&seekParms) != 0)
804 return false;
805
806 if (bReplay)
807 return Play();
808 else
809 return true;
810 }
811
812 long wxWMMEMediaCtrlImpl::GetPosition()
813 {
814 MCI_STATUS_PARMS statusParms;
815
816 statusParms.dwItem = MCI_STATUS_POSITION;
817 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
818 (DWORD)(LPSTR)&statusParms) != 0)
819 return 0;
820
821 return statusParms.dwReturn;
822 }
823
824 long wxWMMEMediaCtrlImpl::GetDuration()
825 {
826 MCI_STATUS_PARMS statusParms;
827
828 statusParms.dwItem = MCI_STATUS_LENGTH;
829 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
830 (DWORD)(LPSTR)&statusParms) != 0)
831 return 0;
832
833 return statusParms.dwReturn;
834 }
835
836 void wxWMMEMediaCtrlImpl::DoMoveWindow(int, int, int, int)
837 {
838 }
839
840 wxSize wxWMMEMediaCtrlImpl::DoGetBestSize() const
841 {
842 if(m_bVideo)
843 {
844 MCI_DGV_RECT_PARMS rect;
845
846 mciSendCommand(m_hDev, MCI_WHERE, 0x00020000L//MCI_DGV_WHERE_SOURCE
847 ,
848 (DWORD)(LPSTR)&rect);
849 return wxSize(rect.rc.right, rect.rc.bottom);
850 }
851 return wxSize(0,0);
852 }
853
854 double wxWMMEMediaCtrlImpl::GetPlaybackRate()
855 {
856 return 1.0;
857 }
858
859 bool wxWMMEMediaCtrlImpl::SetPlaybackRate(double)
860 {
861 return false;
862 }
863
864 bool wxWMMEMediaCtrlImpl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
865 {
866 if(nMsg == MM_MCINOTIFY)
867 {
868 wxASSERT(lParam == (WXLPARAM) m_hDev);
869 if(wParam == (WXWPARAM) MCI_NOTIFY_SUCCESSFUL && lParam == (WXLPARAM) m_hDev)
870 {
871 #ifdef __WXDEBUG__
872 wxASSERT(mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
873 #else
874 mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0);
875 #endif
876
877 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, m_ctrl->GetId());
878 m_ctrl->GetParent()->ProcessEvent(theEvent);
879 }
880 return true;
881 }
882 return false;
883 }
884
885 #endif //wxUSE_MEDIACTRL
886