// Name: msw/mediactrl.cpp
// Purpose: wxMediaCtrl MSW
// Author: Ryan Norton <wxprojects@comcast.net>
-// Modified by:
+// Modified by:
// Created: 11/07/04
// RCS-ID: $Id$
// Copyright: (c) Ryan Norton
//###########################################################################
IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
-IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
-DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
+IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
+DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
//---------------------------------------------------------------------------
// wxMediaCtrlImpl
wxMediaCtrlImpl() : m_bLoaded(false)
{ }
- virtual ~wxMediaCtrlImpl()
+ virtual ~wxMediaCtrlImpl()
{ }
- virtual bool Create(wxMediaCtrl* WXUNUSED(ctrl))
+ virtual bool Create(wxMediaCtrl* WXUNUSED(ctrl))
{ return false; }
virtual bool Play() { return false; }
virtual double GetPlaybackRate() { return 0; }
virtual bool SetPlaybackRate(double) { return false; }
-
+
virtual bool MSWWindowProc(WXUINT, WXWPARAM, WXLPARAM) { return false; }
bool IsLoaded()
//---------------------------------------------------------------------------
#include <mmsystem.h>
-#include <digitalv.h>
class wxWMMEMediaCtrlImpl : public wxMediaCtrlImpl
{
virtual double GetPlaybackRate();
virtual bool SetPlaybackRate(double);
+ bool MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
+
MCIDEVICEID m_hDev;
wxMediaCtrl* m_ctrl;
bool m_bVideo;
};
-//---------------------------------------------------------------------------
-// wxAVIFileMediaCtrlImpl
-//---------------------------------------------------------------------------
-/*
-#include <Vfw.h>
-//msvfw32.dll
-//#pragma comment(lib, "vfw32.lib")
-
-class wxAVIFileMediaCtrlImpl : public wxMediaCtrlImpl
-{
-public:
-
- wxAVIFileMediaCtrlImpl();
- ~wxAVIFileMediaCtrlImpl();
-
- virtual bool Create(wxMediaCtrl* ctrl);
-
- virtual bool Play();
- virtual bool Pause();
- virtual bool Stop();
-
- virtual bool Load(const wxString& fileName);
- virtual bool Load(const wxURI& location);
-
- virtual wxMediaState GetState();
-
- virtual bool SetPosition(long where);
- virtual long GetPosition();
- virtual long GetDuration();
-
- virtual void DoMoveWindow(int x, int y, int w, int h);
- wxSize DoGetBestSize() const;
-
- virtual double GetPlaybackRate();
- virtual bool SetPlaybackRate(double);
-
- HMODULE m_hDll;
- PAVIFILE m_hAVIFile;
- wxMediaCtrl* m_ctrl;
-};
-*/
-
//###########################################################################
//
// IMPLEMENTATION
//
//---------------------------------------------------------------------------
-bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName,
- const wxPoint& pos, const wxSize& size,
+bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName,
+ const wxPoint& pos, const wxSize& size,
long style, long WXUNUSED(driver), const wxString& name)
{
//base create
- if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
+ if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
wxDefaultValidator, name) )
return false;
return true;
}
-bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxURI& location,
- const wxPoint& pos, const wxSize& size,
+bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id, const wxURI& location,
+ const wxPoint& pos, const wxSize& size,
long style, long WXUNUSED(driver), const wxString& name)
{
//base create
- if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
+ if ( !wxControl::Create(parent, id, pos, size, (style | wxNO_BORDER) | wxCLIP_CHILDREN,
wxDefaultValidator, name) )
return false;
//
//---------------------------------------------------------------------------
-#if wxUSE_DIRECTSHOW
+#if wxUSE_DIRECTSHOW
wxDXMediaCtrlImpl::wxDXMediaCtrlImpl() : m_pGB(NULL)
{
bool wxDXMediaCtrlImpl::Load(const wxString& fileName)
{
if(m_bLoaded)
- Cleanup();
-
+ Cleanup();
+
SAFE_RELEASE(m_pGB);
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void**)&m_pGB);
- //load the graph & render
+ //load the graph & render
if( FAILED(m_pGB->RenderFile(fileName.wc_str(wxConvLocal), NULL)) )
return false;
nSX = nSY = 0;
}
- else
+ else
{
m_bVideo = true;
}
bool wxDXMediaCtrlImpl::Stop()
{
- return SUCCEEDED( m_pMC->Stop() ) && SetPosition(0);
+ bool bOK = SUCCEEDED( m_pMC->Stop() );
+
+ //We don't care if it can't get to the beginning in directshow -
+ //it could be a non-seeking filter (wince midi) in which case playing
+ //starts all over again
+ SetPosition(0);
+ return bOK;
}
bool wxDXMediaCtrlImpl::SetPosition(long where)
LONGLONG pos = ((LONGLONG)where) * 10000;
return SUCCEEDED( m_pMS->SetPositions(
- &pos,
+ &pos,
AM_SEEKING_AbsolutePositioning,
- NULL,
+ NULL,
AM_SEEKING_NoPositioning
) );
}
HRESULT hr;
OAFilterState theState;
hr = m_pMC->GetState(INFINITE, &theState);
-
+
wxASSERT( SUCCEEDED(hr) );
//MSW state is the same as ours
// Process all queued events
while(SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
- (LONG_PTR *) &evParam2, 0)
- )
+ (LONG_PTR *) &evParam2, 0)
+ )
)
{
// Free memory associated with callback, since we're not using it
// If this is the end of the clip, notify handler
if(EC_COMPLETE == evCode)
{
+ //Interestingly enough, DirectShow does not actually stop
+ //the filters - even when it reaches the end!
#ifdef __WXDEBUG__
wxASSERT( Stop() );
#else
Stop();
#endif
+
wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, m_ctrl->GetId());
m_ctrl->GetParent()->ProcessEvent(theEvent);
}
- }
+ }
return true;
}
return false;
//
//---------------------------------------------------------------------------
+//
+// Cruft to simulate digitalv.h
+//
+
+typedef struct {
+ DWORD_PTR dwCallback;
+#ifdef MCI_USE_OFFEXT
+ POINT ptOffset;
+ POINT ptExtent;
+#else
+ RECT rc;
+#endif
+} MCI_DGV_RECT_PARMS;
+
+typedef struct {
+ DWORD_PTR dwCallback;
+ HWND hWnd;
+#ifndef _WIN32
+ WORD wReserved1;
+#endif
+ UINT nCmdShow;
+#ifndef _WIN32
+ WORD wReserved2;
+#endif
+ LPSTR lpstrText;
+} MCI_DGV_WINDOW_PARMSA;
+
+typedef struct {
+ DWORD_PTR dwCallback;
+ HWND hWnd;
+#ifndef _WIN32
+ WORD wReserved1;
+#endif
+ UINT nCmdShow;
+#ifndef _WIN32
+ WORD wReserved2;
+#endif
+ LPWSTR lpstrText;
+} MCI_DGV_WINDOW_PARMSW;
+#ifdef UNICODE
+typedef MCI_DGV_WINDOW_PARMSW MCI_DGV_WINDOW_PARMS;
+#else
+typedef MCI_DGV_WINDOW_PARMSA MCI_DGV_WINDOW_PARMS;
+#endif // UNICODE
+
wxWMMEMediaCtrlImpl::wxWMMEMediaCtrlImpl() : m_bVideo(false)
{
-
+/* TCHAR sz[5000];
+ mciGetErrorString(nError, sz, 5000);
+ wxMessageBox(wxString::Format(_T("Error:%s"), sz));
+ */
}
wxWMMEMediaCtrlImpl::~wxWMMEMediaCtrlImpl()
}
bool wxWMMEMediaCtrlImpl::Create(wxMediaCtrl* ctrl)
-{
+{
m_ctrl = ctrl;
return true;
}
-bool wxWMMEMediaCtrlImpl::Play()
-{
- return (mciSendCommand(m_hDev, MCI_PLAY, 0, 0) == 0) ||
- (mciSendCommand(m_hDev, MCI_RESUME, 0, 0) == 0);
-}
-
-bool wxWMMEMediaCtrlImpl::Pause()
-{
- return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
-}
-
-bool wxWMMEMediaCtrlImpl::Stop()
-{
- return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0);
-}
-
-#include "wx/log.h"
-
bool wxWMMEMediaCtrlImpl::Load(const wxString& fileName)
{
if(m_bLoaded)
MCI_OPEN_PARMS openParms;
MCI_SET_PARMS setParms;
- memset(&openParms, 0, sizeof(MCI_DGV_OPEN_PARMS));
openParms.lpstrElementName = (wxChar*) fileName.c_str();
- bool bFound = false;
-
- for(size_t i = MCI_DEVTYPE_FIRST; i <= MCI_DEVTYPE_LAST; ++i)
- {
- openParms.lpstrDeviceType = (LPSTR)i;
-
- DWORD nError;
-
- if ((nError = mciSendCommand(0, MCI_OPEN,
- MCI_OPEN_ELEMENT|MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID,
- (DWORD)(LPVOID)&openParms)) == 0)
- {
- bFound = true;
- break;
- }
- }
-
- if(!bFound)
- return false;
+ //Here's where the trick lies - if you don't specify MCI_OPEN_TYPE,
+ //then it actually automagically finds the device for you!
+ if ( mciSendCommand(0, MCI_OPEN,
+ MCI_OPEN_ELEMENT,
+ (DWORD)(LPVOID)&openParms) != 0)
+ return false;
m_hDev = openParms.wDeviceID;
-
setParms.dwCallback = 0;
setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
(DWORD)(LPVOID)&setParms) != 0)
return false;
-
- //TODO: Does this work?
- /*
MCI_DGV_WINDOW_PARMS windowParms;
- windowParms.hWnd = (HWND)m_ctrl->GetHWND();
+ windowParms.hWnd = (HWND)m_ctrl->GetHandle();
m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
- MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&windowParms) == 0);
-*/
+ 0x00010000L //MCI_DGV_WINDOW_HWND
+ ,
+ (DWORD)(LPVOID)&windowParms) == 0);
m_bLoaded = true;
+ //work around refresh issues
+ m_ctrl->InvalidateBestSize();
+ m_ctrl->GetParent()->Layout();
+ m_ctrl->GetParent()->Refresh();
+ m_ctrl->GetParent()->Update();
+
return true;
}
return false;
}
+bool wxWMMEMediaCtrlImpl::Play()
+{
+ //the directshow driver ("mpegvideo") will crash if we don't do a playParms here
+ MCI_PLAY_PARMS playParms;
+ playParms.dwCallback = (DWORD)(HWND)m_ctrl->GetHWND();
+ bool bOK = mciSendCommand(m_hDev, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&playParms) == 0;
+ return (bOK) ;/*||
+ (mciSendCommand(m_hDev, MCI_RESUME, 0, 0) == 0);*/
+}
+
+bool wxWMMEMediaCtrlImpl::Pause()
+{
+ return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
+}
+
+bool wxWMMEMediaCtrlImpl::Stop()
+{
+ return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0) &&
+ (mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
+}
+
+
wxMediaState wxWMMEMediaCtrlImpl::GetState()
{
MCI_STATUS_PARMS statusParms;
if( mciSendCommand(m_hDev, MCI_SEEK, MCI_TO, (DWORD)(LPVOID)&seekParms) != 0)
return false;
-/* TCHAR sz[5000];
- mciGetErrorString(nError, sz, 5000);
- wxMessageBox(wxString::Format(_T("Error:%s"), sz));
- */
if (bReplay)
return Play();
long wxWMMEMediaCtrlImpl::GetPosition()
{
MCI_STATUS_PARMS statusParms;
-
- statusParms.dwItem = MCI_STATUS_POSITION;
- if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
+
+ statusParms.dwItem = MCI_STATUS_POSITION;
+ if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)(LPSTR)&statusParms) != 0)
return 0;
long wxWMMEMediaCtrlImpl::GetDuration()
{
MCI_STATUS_PARMS statusParms;
-
- statusParms.dwItem = MCI_STATUS_LENGTH;
- if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
+
+ statusParms.dwItem = MCI_STATUS_LENGTH;
+ if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)(LPSTR)&statusParms) != 0)
return 0;
{
if(m_bVideo)
{
- //TODO: Does this work?
- /*
- MCI_DGV_RECT_PARMS rect;
+ MCI_DGV_RECT_PARMS rect;
- mciSendCommand(m_hDev, MCI_WHERE, MCI_DGV_WHERE_SOURCE, (DWORD)(LPSTR)&rect);
+ mciSendCommand(m_hDev, MCI_WHERE, 0x00020000L//MCI_DGV_WHERE_SOURCE
+ ,
+ (DWORD)(LPSTR)&rect);
return wxSize(rect.rc.right, rect.rc.bottom);
- */
}
return wxSize(0,0);
}
return false;
}
-//---------------------------------------------------------------------------
-//
-// wxAVIFileMediaCtrlImpl
-//
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Functions located in msvfw32.dll
-//---------------------------------------------------------------------------
-
-/*
-
-typedef void (WINAPI *LPAVIFileInit) ();
-typedef void (WINAPI *LPAVIFileExit) ();
-
-typedef ULONG (WINAPI *LPAVIFileOpen) (
-PAVIFILE FAR * ppfile,
-const wxChar* szFile,
-UINT uMode,
-LPCLSID lpHandler
-);
-
-typedef ULONG (WINAPI *LPAVIFileRelease) (PAVIFILE pfile);
-
-wxAVIFileMediaCtrlImpl::wxAVIFileMediaCtrlImpl()
-{
-}
-
-wxAVIFileMediaCtrlImpl::~wxAVIFileMediaCtrlImpl()
-{
-}
-
-bool wxAVIFileMediaCtrlImpl::Create(wxMediaCtrl* ctrl)
-{
- m_hDll = ::LoadLibrary(_T("avifil32.dll"));
-
- if(m_hDll == NULL)
- return false;
-
- LPAVIFileInit pAVIFileInit = (LPAVIFileInit) ::GetProcAddress(m_hDll, _T("AVIFileInit"));
-
- if(!pAVIFileInit)
- return false;
-
- (*pAVIFileInit)();
-
- m_ctrl = ctrl;
- return false;
-}
-
-
-bool wxAVIFileMediaCtrlImpl::Load(const wxString& fileName)
-{
-// if( AVIFileOpen(&m_hAVIFile, fileName.c_str(), OF_SHARE_DENY_WRITE, 0L) != 0)
- return false;
-
- m_bLoaded = true;
-
- return true;
-}
-
-bool wxAVIFileMediaCtrlImpl::Load(const wxURI& WXUNUSED(location))
+bool wxWMMEMediaCtrlImpl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
- return false;
-}
-
-bool wxAVIFileMediaCtrlImpl::Play()
-{
- return 0;
-}
-
-bool wxAVIFileMediaCtrlImpl::Pause()
-{
- return 0;
-}
-
-bool wxAVIFileMediaCtrlImpl::Stop()
-{
- return 0;
-}
-
-wxMediaState wxAVIFileMediaCtrlImpl::GetState()
-{
- return wxMEDIASTATE_STOPPED;
-}
-
-bool wxAVIFileMediaCtrlImpl::SetPosition(long where)
-{
- return 0;
-}
-
-long wxAVIFileMediaCtrlImpl::GetPosition()
-{
- return 0;
-}
-
-long wxAVIFileMediaCtrlImpl::GetDuration()
-{
- return 0;
-}
-
-void wxAVIFileMediaCtrlImpl::DoMoveWindow(int, int, int, int)
-{
-}
-
-wxSize wxAVIFileMediaCtrlImpl::DoGetBestSize() const
-{
- return wxSize(0,0);
-}
-
-double wxAVIFileMediaCtrlImpl::GetPlaybackRate()
-{
- return 1.0;
-}
+ if(nMsg == MM_MCINOTIFY)
+ {
+ wxASSERT(lParam == (WXLPARAM) m_hDev);
+ if(wParam == (WXWPARAM) MCI_NOTIFY_SUCCESSFUL && lParam == (WXLPARAM) m_hDev)
+ {
+#ifdef __WXDEBUG__
+ wxASSERT(mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
+#else
+ mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0);
+#endif
-bool wxAVIFileMediaCtrlImpl::SetPlaybackRate(double)
-{
+ wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, m_ctrl->GetId());
+ m_ctrl->GetParent()->ProcessEvent(theEvent);
+ }
+ return true;
+ }
return false;
}
- */
+#endif //wxUSE_MEDIACTRL
-#endif //wxUSE_MEDIACTRL
\ No newline at end of file