]> git.saurik.com Git - wxWidgets.git/commitdiff
wxMovieCtrl - for playing movies - mac carbon QT 3 MSW-compatable implementation...
authorRyan Norton <wxprojects@comcast.net>
Sun, 7 Nov 2004 08:27:51 +0000 (08:27 +0000)
committerRyan Norton <wxprojects@comcast.net>
Sun, 7 Nov 2004 08:27:51 +0000 (08:27 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30332 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/mac/carbon/moviectrl.h [new file with mode: 0644]
include/wx/moviectrl.h [new file with mode: 0644]
include/wx/msw/moviectrl.h [new file with mode: 0644]
src/mac/carbon/moviectrl.cpp [new file with mode: 0644]
src/msw/moviectrl.cpp [new file with mode: 0644]

diff --git a/include/wx/mac/carbon/moviectrl.h b/include/wx/mac/carbon/moviectrl.h
new file mode 100644 (file)
index 0000000..eac2847
--- /dev/null
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/msw/moviectrl.h
+// Purpose:     DirectX7+ wxMovieCtrl MSW 
+// Author:      Ryan Norton <wxprojects@comcast.net>
+// Modified by: 
+// Created:     11/07/04
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/defs.h"
+
+#if wxUSE_MOVIECTRL
+
+#include "wx/datetime.h"
+
+enum wxMovieCtrlState
+{
+    wxMOVIECTRL_STOPPED,
+    wxMOVIECTRL_PAUSED,
+    wxMOVIECTRL_PLAYING
+};
+
+class wxMovieCtrl : public wxControl
+{
+public:
+    wxMovieCtrl() 
+    {                                                                   }
+
+    wxMovieCtrl(wxWindow* parent, wxWindowID id, const wxString& fileName, const wxString& label = wxT(""),
+                const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 
+                long style = 0, const wxString& name = wxPanelNameStr)
+    {   Create(parent, id, fileName, label, pos, size, style, name);    } 
+
+    ~wxMovieCtrl();
+
+    bool Create(wxWindow* parent, wxWindowID id, const wxString& fileName, const wxString& label = wxT(""),
+                const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 
+                long style = 0, const wxString& name = wxPanelNameStr);
+
+    bool Play();
+    bool Pause();
+    bool Stop();
+    
+    wxMovieCtrlState GetState();
+
+#if wxUSE_DATETIME
+    bool Seek(const wxTimeSpan& where);
+#endif
+
+    virtual void SetLabel(const wxString& label);
+
+protected:
+    void OnSize(wxSizeEvent& evt);
+    wxSize DoGetBestSize() const;
+    bool InitQT();
+
+    struct MovieRecord* m_movie;
+    wxSize m_bestSize;
+    class _wxQTTimer* m_timer;
+    
+    DECLARE_DYNAMIC_CLASS(wxMovieCtrl);
+    DECLARE_EVENT_TABLE()
+};
+
+#endif // wxUSE_MOVIECTRL
\ No newline at end of file
diff --git a/include/wx/moviectrl.h b/include/wx/moviectrl.h
new file mode 100644 (file)
index 0000000..7b8ec9c
--- /dev/null
@@ -0,0 +1,16 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/moviectrl.h
+// Purpose:     wxMovieCtrl class
+// Author:      Ryan Norton <wxprojects@comcast.net>
+// Modified by: 
+// Created:     11/07/04
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(__WXMSW__)
+#include "wx/msw/moviectrl.h"
+#elif defined(__WXMAC__)
+#include "wx/mac/carbon/moviectrl.h"
+#endif
\ No newline at end of file
diff --git a/include/wx/msw/moviectrl.h b/include/wx/msw/moviectrl.h
new file mode 100644 (file)
index 0000000..ceee950
--- /dev/null
@@ -0,0 +1,77 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/msw/moviectrl.h
+// Purpose:     DirectX7+ wxMovieCtrl MSW 
+// Author:      Ryan Norton <wxprojects@comcast.net>
+// Modified by: 
+// Created:     11/07/04
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/defs.h"
+
+#if wxUSE_MOVIECTRL
+
+#include "wx/datetime.h"
+
+enum wxMovieCtrlState
+{
+    wxMOVIECTRL_STOPPED,
+    wxMOVIECTRL_PAUSED,
+    wxMOVIECTRL_PLAYING
+};
+
+class wxMovieCtrl : public wxControl
+{
+public:
+    wxMovieCtrl() 
+    {                                                                   }
+
+    wxMovieCtrl(wxWindow* parent, wxWindowID id, const wxString& fileName, const wxString& label = wxT(""),
+                const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 
+                long style = 0, const wxString& name = wxPanelNameStr)
+    {   Create(parent, id, fileName, label, pos, size, style, name);    } 
+
+    ~wxMovieCtrl();
+
+    bool Create(wxWindow* parent, wxWindowID id, const wxString& fileName, const wxString& label = wxT(""),
+                const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 
+                long style = 0, const wxString& name = wxPanelNameStr);
+
+    bool Play();
+    bool Pause();
+    bool Stop();
+    
+    wxMovieCtrlState GetState();
+
+#if wxUSE_DATETIME
+    bool Seek(const wxTimeSpan& where);
+#endif
+
+    virtual void SetLabel(const wxString& label);
+
+protected:
+    void OnSize(wxSizeEvent& evt);
+    wxSize DoGetBestSize() const;
+
+//    void OnActivate(wxActivateEvent& evt);
+
+    //msw-specific - we need to overload the window proc
+//    WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
+
+    void* m_pGB;
+    void* m_pMC;
+    void* m_pME;
+    void* m_pVW;
+    void* m_pBA;
+    void* m_pBV;
+    void* m_pMS;
+
+    wxSize m_bestSize;
+    
+    DECLARE_DYNAMIC_CLASS(wxMovieCtrl);
+    DECLARE_EVENT_TABLE()
+};
+
+#endif // wxUSE_MOVIECTRL
\ No newline at end of file
diff --git a/src/mac/carbon/moviectrl.cpp b/src/mac/carbon/moviectrl.cpp
new file mode 100644 (file)
index 0000000..db687e7
--- /dev/null
@@ -0,0 +1,304 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mac/carbon/moviectrl.cpp
+// Purpose:     wxMovieCtrl MAC CARBON QT
+// Author:      Ryan Norton <wxprojects@comcast.net>
+// Modified by: 
+// Created:     11/07/04
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+//#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+//#pragma implementation "moviectrl.h"
+//#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#define wxUSE_MOVIECTRL 1
+
+#if wxUSE_MOVIECTRL
+
+#include "wx/moviectrl.h"
+#include "wx/sound.h"
+#include "wx/timer.h"
+
+IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
+
+BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl)
+    EVT_SIZE(wxMovieCtrl::OnSize)
+END_EVENT_TABLE()
+
+//MESSY headers
+#ifdef __WXMAC__
+#include "wx/mac/uma.h"
+#include <Movies.h>
+#include <Gestalt.h>
+#endif
+
+//quicktime media layer only required for mac emulation on pc
+#ifndef __WXMAC__
+#include <qtml.h>
+#endif
+
+#include <QuickTimeComponents.h>
+
+//Time between timer calls
+#define MOVIE_DELAY 100
+
+// ------------------------------------------------------------------
+//          wxQTTimer - Handle Asyncronous Playing
+// ------------------------------------------------------------------
+class _wxQTTimer : public wxTimer
+{
+public:
+    _wxQTTimer(Movie movie) :
+        m_movie(movie), m_bPaused(false)
+    {
+    }
+
+    ~_wxQTTimer()
+    {
+    }
+
+    bool GetPaused() {return m_bPaused;}
+    void SetPaused(bool bPaused) {m_bPaused = bPaused;}
+
+    void Notify()
+    {
+        if (!m_bPaused)
+        {
+            if(!IsMovieDone(m_movie))
+                MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie
+            else
+                Stop();
+        }
+    }
+
+protected:
+    Movie m_movie;
+    bool m_bPaused;
+};
+
+//Determines whether version 3 of QT is installed
+Boolean wxIsQuickTime3Installed (void)
+{
+#ifdef __WXMAC__
+    short error;
+    long result;
+
+    error = Gestalt (gestaltQuickTime, &result);
+    return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0300);
+#else
+    return true;
+#endif
+}
+
+bool wxMovieCtrl::InitQT ()
+{
+    if (wxIsQuickTime3Installed())
+    {
+        #ifndef __WXMAC__
+        int nError;
+        //-2093 no dll
+            if ((nError = InitializeQTML(0)) != noErr)
+            {
+                wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError));
+            }
+        #endif
+        EnterMovies();
+        return true;
+    }
+    else
+    {
+        wxFAIL_MSG(wxT("Quicktime is not installed, or Your Version of Quicktime is <= 4."));
+        return false;
+    }
+}
+
+bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName, 
+                         const wxString& label, const wxPoint& pos, const wxSize& size, 
+                         long WXUNUSED(style), const wxString& name)
+{
+    if ( !InitQT() )
+        return false;
+
+    OSErr err = noErr;
+    short movieResFile;
+    FSSpec sfFile;
+#ifdef __WXMAC__
+    wxMacFilename2FSSpec( m_sndname , &sfFile ) ;
+#else
+    int nError;
+    if ((nError = NativePathNameToFSSpec ((char*) fileName.c_str(), &sfFile, 0)) != noErr)
+    {
+        wxFAIL_MSG(wxString::Format(wxT("File:%s does not exist\nError:%i"),
+                        fileName.c_str(), nError));
+        return false;
+    }
+#endif
+    if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
+    {
+        wxFAIL_MSG(wxT("Quicktime couldn't open the file"));
+        return false;
+    }
+    short movieResID = 0;
+    Str255 movieName;
+
+    err = NewMovieFromFile (
+    &m_movie,
+    movieResFile,
+    &movieResID,
+    movieName,
+    newMovieActive,
+    NULL); //wasChanged
+
+    CloseMovieFile (movieResFile);
+
+    if (err != noErr)
+    {
+        wxFAIL_MSG(wxT("Could not create movie"));
+        return false;
+    }
+
+    m_timer = new _wxQTTimer(m_movie);
+    wxASSERT(m_timer);
+
+    //get the real size of the movie
+    Rect outRect;
+    ::GetMovieNaturalBoundsRect (m_movie, &outRect);
+
+    m_bestSize.x = outRect.right - outRect.left;
+    m_bestSize.y = outRect.bottom - outRect.top;
+
+    //do some window stuff
+    if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER, wxDefaultValidator, name) )
+        return false;
+
+    //Set our background color to black by default
+    SetBackgroundColour(*wxBLACK);
+
+    //reparent movie
+#ifdef __WXMSW__
+    CreatePortAssociation(this->GetHWND(), NULL, 0L);
+#endif
+    SetMovieGWorld(m_movie, (CGrafPtr)
+
+#ifdef __WXMSW__
+    GetNativeWindowPort(this->GetHWND())
+#else
+    this->GetHandle()
+#endif
+    , nil);
+
+    //go!
+    SetLabel(label);
+    Play();
+
+    return true;
+}
+
+void wxMovieCtrl::SetLabel(const wxString& label)
+{
+    wxControl::SetLabel(label);
+}
+
+bool wxMovieCtrl::Play()
+{
+    ::StartMovie(m_movie);
+    m_timer->SetPaused(false);
+    m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
+    return ::GetMoviesError() == noErr;
+}
+
+bool wxMovieCtrl::Pause()
+{
+    ::StopMovie(m_movie);
+    m_timer->SetPaused(true);
+    return ::GetMoviesError() == noErr;
+}
+
+bool wxMovieCtrl::Stop()
+{
+    m_timer->SetPaused(false);
+
+    ::StopMovie(m_movie);
+    if(::GetMoviesError() != noErr)
+        return false;
+    
+    ::GoToEndOfMovie(m_movie);
+    return ::GetMoviesError() == noErr;
+}
+
+#if wxUSE_DATETIME
+
+bool wxMovieCtrl::Seek(const wxTimeSpan& where)
+{
+    TimeRecord theTimeRecord;
+    theTimeRecord.value.lo = ((size_t)where.GetMilliseconds().ToLong()) * 10;
+    theTimeRecord.scale = ::GetMovieTimeScale(m_movie);
+    theTimeRecord.base = ::GetMovieTimeBase(m_movie);
+    ::SetMovieTime(m_movie, &theTimeRecord);
+
+    if (::GetMoviesError() != noErr)
+        return false;
+
+    return true;
+}
+
+#endif // wxUSE_DATETIME
+
+wxMovieCtrlState wxMovieCtrl::GetState()
+{
+    if( m_timer->IsRunning() == true )
+        return wxMOVIECTRL_STOPPED;
+
+    if ( m_timer->GetPaused() == false )
+        return wxMOVIECTRL_PLAYING;
+    else
+        return wxMOVIECTRL_PAUSED;
+}
+
+wxMovieCtrl::~wxMovieCtrl()
+{
+    if (m_timer)
+    {
+        delete m_timer;
+
+        StopMovie(m_movie);
+        DisposeMovie(m_movie);
+        
+        //Note that ExitMovies() is not neccessary, but
+        //the docs are fuzzy on whether or not TerminateQTML is
+        ExitMovies();
+
+    #ifndef __WXMAC__
+        TerminateQTML();
+    #endif
+    }
+}
+
+wxSize wxMovieCtrl::DoGetBestSize() const
+{
+    return m_bestSize;
+}
+
+void wxMovieCtrl::OnSize(wxSizeEvent& evt)
+{
+    Rect theRect;
+    theRect.left = 0;
+    theRect.top = 0;
+    theRect.bottom = evt.GetSize().y;
+    theRect.right = evt.GetSize().x;
+
+    ::SetMovieBox(m_movie, &theRect);
+
+    wxASSERT(::GetMoviesError() == noErr);
+    evt.Skip();
+}
+#endif //wxUSE_MOVIECTRL
diff --git a/src/msw/moviectrl.cpp b/src/msw/moviectrl.cpp
new file mode 100644 (file)
index 0000000..50ef6b3
--- /dev/null
@@ -0,0 +1,295 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        msw/moviectrl.cpp
+// Purpose:     wxMovieCtrl MSW
+// Author:      Ryan Norton <wxprojects@comcast.net>
+// Modified by: 
+// Created:     11/07/04
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+//#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+//#pragma implementation "moviectrl.h"
+//#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if wxUSE_MOVIECTRL
+
+#include "wx/moviectrl.h"
+#include "wx/msw/ole/oleutils.h" //for wxBasicString
+
+#include <dshow.h>
+
+IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
+
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
+
+#define WM_GRAPHNOTIFY  WM_USER+13
+
+#ifdef __WXDEBUG__
+#define wxDSVERIFY(x) wxASSERT( SUCCEEDED ((x)) )
+#else
+#define wxDSVERIFY(x) (x)
+#endif
+
+BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl)
+    EVT_SIZE(wxMovieCtrl::OnSize)
+//    EVT_ACTIVATE(wxMovieCtrl::OnActivate)
+END_EVENT_TABLE()
+
+//it's there someplace :)
+extern "C" WXDLLIMPEXP_BASE HWND
+wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
+
+bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName, 
+                         const wxString& label, const wxPoint& pos, const wxSize& size, 
+                         long style, const wxString& name)
+{
+    //cast helpers
+    IGraphBuilder*& pGB = (IGraphBuilder*&) m_pGB;
+    IMediaControl*& pMC = (IMediaControl*&) m_pMC;
+    IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
+    IVideoWindow*& pVW  = (IVideoWindow*&)  m_pVW;
+    IBasicAudio*& pBA   = (IBasicAudio*&)   m_pBA;
+    IBasicVideo*& pBV   = (IBasicVideo*&)   m_pBV;
+    IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
+
+    //create our filter graph
+    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
+                      IID_IGraphBuilder, (void**)&pGB);
+
+    //load the graph & render 
+    if (FAILED(pGB->RenderFile(fileName.wc_str(wxConvLocal), NULL)))
+    {
+        wxFAIL_MSG("Could not load movie!");
+        return false;
+    }
+
+    //get the interfaces, all of them
+    wxDSVERIFY( pGB->QueryInterface(IID_IMediaControl, (void**)&pMC) );
+    wxDSVERIFY( pGB->QueryInterface(IID_IMediaEventEx, (void**)&pME) );
+    wxDSVERIFY( pGB->QueryInterface(IID_IMediaSeeking, (void**)&pMS) );
+    wxDSVERIFY( pGB->QueryInterface(IID_IVideoWindow, (void**)&pVW) );
+    wxDSVERIFY( pGB->QueryInterface(IID_IBasicAudio, (void**)&pBA) );
+    wxDSVERIFY( pGB->QueryInterface(IID_IBasicVideo, (void**)&pBV) );
+
+    //get the _actual_ size of the movie & remember it
+    long nX, nY, nSX, nSY;
+    pVW->GetWindowPosition(&nX,&nY,&nSX,&nSY);
+
+    m_bestSize.x = nSX;
+    m_bestSize.y = nSY;
+
+    //do some window stuff - ORDER IS IMPORTANT
+    //base create
+    if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER | wxCLIP_CHILDREN, wxDefaultValidator, name) )
+        return false;
+
+    //Set our background color to black by default
+    SetBackgroundColour(*wxBLACK);
+
+    wxDSVERIFY( pVW->put_Owner((OAHWND)this->GetHandle()) );
+    wxDSVERIFY( pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) );
+//    wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) );
+    wxDSVERIFY( pVW->put_Visible(OATRUE) ); //OATRUE actually == -1 :)
+
+    //set the time format
+    wxDSVERIFY( pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME) );
+
+    SetLabel(label);
+    Play();
+
+    return true;
+}
+
+void wxMovieCtrl::SetLabel(const wxString& label)
+{
+    wxControl::SetLabel(label);
+
+    IVideoWindow*& pVW  = (IVideoWindow*&)  m_pVW;
+    
+    //wxBasicString will have a null string on an
+    //empty wxString - gotta love those workarounds!!
+    if(!label.empty())
+    {
+        wxBasicString theBasicString(label.mb_str());
+        wxDSVERIFY( pVW->put_Caption(theBasicString.Get()) );
+    }
+}
+
+bool wxMovieCtrl::Play()
+{
+    return SUCCEEDED( ((IMediaControl*&)m_pMC)->Run() );
+}
+
+bool wxMovieCtrl::Pause()
+{
+    return SUCCEEDED( ((IMediaControl*&)m_pMC)->Pause() );
+}
+
+bool wxMovieCtrl::Stop()
+{
+    return SUCCEEDED( ((IMediaControl*&)m_pMC)->Stop() );
+}
+
+#if wxUSE_DATETIME
+
+bool wxMovieCtrl::Seek(const wxTimeSpan& where)
+{
+    //DS uses 100 nanos - so we need a 10 mult
+    LONGLONG pos = ((size_t)where.GetMilliseconds().ToLong()) * 10;
+
+    return SUCCEEDED( ((IMediaSeeking*&)m_pMS)->SetPositions(
+                                &pos, 
+                                AM_SEEKING_AbsolutePositioning,
+                                NULL, 
+                                AM_SEEKING_NoPositioning
+                                    ) );
+}
+
+#endif // wxUSE_DATETIME
+
+wxMovieCtrlState wxMovieCtrl::GetState()
+{
+    HRESULT hr;
+    OAFilterState theState;
+    hr = ((IMediaControl*&)m_pMC)->GetState(INFINITE, &theState);
+    
+    wxASSERT( SUCCEEDED(hr) );
+
+    //MSW state is the same as ours
+    //State_Stopped   = 0,
+    //State_Paused    = State_Stopped + 1,
+    //State_Running   = State_Paused + 1
+
+    return (wxMovieCtrlState) theState;
+}
+
+//WXLRESULT wxMovieCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+//{
+/*
+    //cast helpers
+    IMediaControl*& pMC = (IMediaControl*&) m_pMC;
+    IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
+    IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
+
+    if (nMsg == WM_GRAPHNOTIFY)
+    {
+        LONG evCode, evParam1, evParam2;
+        HRESULT hr=S_OK;
+
+        //make sure we exist
+        if (!pME)
+            return S_OK;
+
+        // Process all queued events
+        while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
+                                       (LONG_PTR *) &evParam2, 0) 
+                       ) 
+             )
+        {
+            // Free memory associated with callback, since we're not using it
+            hr = pME->FreeEventParams(evCode, evParam1, evParam2);
+
+            // If this is the end of the clip, reset to beginning
+            if(EC_COMPLETE == evCode)
+            {
+                LONGLONG pos=0;
+
+                // Reset to first frame of movie
+                hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
+                                       NULL, AM_SEEKING_NoPositioning);
+                if (FAILED(hr))
+                {
+                    hr = pMC->Stop();
+                    // for filters that don't support seeking do a rewind
+                    if (FAILED(hr))
+                    {
+                        wxFAIL_MSG(
+                            wxString::Format(TEXT("Failed(0x%08lx) to stop media clip!\r\n"), hr)
+                                    );
+                        break;
+                    }
+
+                    hr = hr = pMC->Run();
+
+                    if (FAILED(hr))
+                    {
+                        wxFAIL_MSG(
+                        wxString::Format(TEXT("Failed(0x%08lx) to reset media clip!\r\n"), hr)
+                                    );
+                        break;
+                    }
+                }
+            }
+        }    
+        return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
+    }
+*/
+    //pass the event to our parent
+//    return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+//}
+
+wxMovieCtrl::~wxMovieCtrl()
+{
+    //cast helpers
+    IGraphBuilder*& pGB = (IGraphBuilder*&) m_pGB;
+    IMediaControl*& pMC = (IMediaControl*&) m_pMC;
+    IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
+    IVideoWindow*& pVW  = (IVideoWindow*&)  m_pVW;
+    IBasicAudio*& pBA   = (IBasicAudio*&)   m_pBA;
+    IBasicVideo*& pBV   = (IBasicVideo*&)   m_pBV;
+    IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
+
+    // Hide then disown the window
+    if(pVW)
+    {
+        pVW->put_Visible(OAFALSE); //OSFALSE == 0
+        pVW->put_Owner(NULL);
+    }
+
+    // Release and zero DirectShow interfaces
+    SAFE_RELEASE(pME);
+    SAFE_RELEASE(pMS);
+    SAFE_RELEASE(pMC);
+    SAFE_RELEASE(pBA);
+    SAFE_RELEASE(pBV);
+    SAFE_RELEASE(pVW);
+    SAFE_RELEASE(pGB);
+}
+
+wxSize wxMovieCtrl::DoGetBestSize() const
+{
+    return m_bestSize;
+}
+
+//
+//EVENT OVERRIDES
+//
+
+void wxMovieCtrl::OnSize(wxSizeEvent& evt)
+{
+    IVideoWindow*& pVW  = (IVideoWindow*&)  m_pVW;
+    wxDSVERIFY( pVW->SetWindowPosition(0, 0, evt.GetSize().GetWidth(), evt.GetSize().GetHeight()) );
+
+    evt.Skip();
+}
+/*
+void wxMovieCtrl::OnActivate(wxActivateEvent& evt)
+{
+    if (evt.GetActive())
+    {
+        //HACK: Make the window show :)
+        SetSize(GetSize());
+    }
+}
+*/
+
+#endif //wxUSE_MOVIECTRL
\ No newline at end of file