Don't support this compiler any more, this allows to get rid of tons of MSVC6-specific workarounds, in particular we can now use Bind() and natural template functions calls in the library code. Also remove MSVC6 project and solution files and don't generate them when bakefile_gen is ran any more (removing the remaining occurrences of msvc6prj from the bakefiles results in weird bake-time errors, so it's simpler to just leave them there). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76532 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1519 lines
52 KiB
C++
1519 lines
52 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/msw/mediactrl_wmp10.cpp
|
|
// Purpose: Windows Media Player 9/10 Media Backend for Windows
|
|
// Author: Ryan Norton <wxprojects@comcast.net>
|
|
// Modified by:
|
|
// Created: 11/07/04
|
|
// Copyright: (c) Ryan Norton
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------Introduction----------------------------------------------
|
|
// This backend is for Desktops with either WMP 9 or 10 and Windows
|
|
// mobile (5.0, some 2003 SmartPhones etc.) WMP 10 only (9 has no automation
|
|
// interface but you can hack it with message hacks to play through
|
|
// a currently running instance of media player).
|
|
//
|
|
// There are quite a few WMP 10 interfaces and unlike other media
|
|
// backends we actually set it to automatically play files as it has
|
|
// as huge caveat that you cannot (technically) obtain media information
|
|
// from IWMPMedia including duration and video size until a media file
|
|
// has literally started to play. There is a hack (and indeed we have
|
|
// it within this file) to enable duration getting from a non-playing
|
|
// file, but there is no hack I (RN) know of to get the video size from
|
|
// a file that isn't playing.
|
|
//
|
|
// The workaround for this is to send the wxEVT_MEDIA_LOADED when the file
|
|
// is about to be played - and if the user didn't change the state of the
|
|
// media (m_bWasStateChanged), when set it back to the stop state.
|
|
//
|
|
// The ActiveX control itself is particularly stubborn, calling
|
|
// IOleInPlaceSite::OnPosRectChange every file change trying to set itself
|
|
// to something different then what we told it to before.
|
|
//
|
|
// The docs are at
|
|
// http://msdn.microsoft.com/library/en-us/wmplay10/mmp_sdk/windowsmediaplayer10sdk.asp
|
|
|
|
//===========================================================================
|
|
// DECLARATIONS
|
|
//===========================================================================
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Pre-compiled header stuff
|
|
//---------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_MEDIACTRL && wxUSE_ACTIVEX
|
|
|
|
#include "wx/mediactrl.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/log.h"
|
|
#endif
|
|
|
|
#include "wx/msw/private.h" // user info and wndproc setting/getting
|
|
#include "wx/msw/ole/activex.h" // wxActiveXContainer - COM-specific stuff
|
|
|
|
//---------------------------------------------------------------------------
|
|
// ATL Includes - define WXTEST_ATL if you
|
|
// want to use CAxWindow instead of wxActiveXContainer (note that
|
|
// this is mainly for testing as the activex events arn't implemented here)
|
|
//---------------------------------------------------------------------------
|
|
#if 0
|
|
#define WXTEST_ATL
|
|
#endif
|
|
|
|
#ifdef WXTEST_ATL
|
|
#include <atlbase.h>
|
|
CComModule _Module;
|
|
#define min(x,y) (x < y ? x : y)
|
|
#include <atlcom.h>
|
|
#include <atlhost.h>
|
|
#include <atlctl.h>
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Other defines
|
|
//---------------------------------------------------------------------------
|
|
|
|
// error logger for HRESULTS (nothing really now)
|
|
#define wxWMP10LOG(x)
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Various definitions dumped from wmp.IDL
|
|
//---------------------------------------------------------------------------
|
|
|
|
// CLSID_WMP10ALT is on CE and in some MS docs - on others it is the plain ver
|
|
const CLSID CLSID_WMP10 = {0x6BF52A50,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
|
|
const CLSID CLSID_WMP10ALT = {0x6BF52A52,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
|
|
|
|
const IID IID_IWMPSettings = {0x9104D1AB,0x80C9,0x4FED,{0xAB,0xF0,0x2E,0x64,0x17,0xA6,0xDF,0x14}};
|
|
const IID IID_IWMPCore = {0xD84CCA99,0xCCE2,0x11D2,{0x9E,0xCC,0x00,0x00,0xF8,0x08,0x59,0x81}};
|
|
#ifndef WXTEST_ATL
|
|
const IID IID_IWMPPlayer = {0x6BF52A4F,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
|
|
#endif
|
|
|
|
const IID IID_IWMPMedia = {0x94D55E95,0x3FAC,0x11D3,{0xB1,0x55,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
|
|
const IID IID_IWMPControls = {0x74C09E02,0xF828,0x11D2,{0xA7,0x4B,0x00,0xA0,0xC9,0x05,0xF3,0x6E}};
|
|
const IID IID_IWMPPlayer2 = {0x0E6B01D1,0xD407,0x4C85,{0xBF,0x5F,0x1C,0x01,0xF6,0x15,0x02,0x80}};
|
|
const IID IID_IWMPCore2 = {0xBC17E5B7,0x7561,0x4C18,{0xBB,0x90,0x17,0xD4,0x85,0x77,0x56,0x59}};
|
|
const IID IID_IWMPCore3 = {0x7587C667,0x628F,0x499F,{0x88,0xE7,0x6A,0x6F,0x4E,0x88,0x84,0x64}};
|
|
const IID IID_IWMPNetwork = {0xEC21B779,0xEDEF,0x462D,{0xBB,0xA4,0xAD,0x9D,0xDE,0x2B,0x29,0xA7}};
|
|
|
|
enum WMPOpenState
|
|
{
|
|
wmposUndefined = 0,
|
|
wmposPlaylistChanging = 1,
|
|
wmposPlaylistLocating = 2,
|
|
wmposPlaylistConnecting = 3,
|
|
wmposPlaylistLoading = 4,
|
|
wmposPlaylistOpening = 5,
|
|
wmposPlaylistOpenNoMedia = 6,
|
|
wmposPlaylistChanged = 7,
|
|
wmposMediaChanging = 8,
|
|
wmposMediaLocating = 9,
|
|
wmposMediaConnecting = 10,
|
|
wmposMediaLoading = 11,
|
|
wmposMediaOpening = 12,
|
|
wmposMediaOpen = 13,
|
|
wmposBeginCodecAcquisition = 14,
|
|
wmposEndCodecAcquisition = 15,
|
|
wmposBeginLicenseAcquisition = 16,
|
|
wmposEndLicenseAcquisition = 17,
|
|
wmposBeginIndividualization = 18,
|
|
wmposEndIndividualization = 19,
|
|
wmposMediaWaiting = 20,
|
|
wmposOpeningUnknownURL = 21
|
|
};
|
|
|
|
enum WMPPlayState
|
|
{
|
|
wmppsUndefined = 0,
|
|
wmppsStopped = 1,
|
|
wmppsPaused = 2,
|
|
wmppsPlaying = 3,
|
|
wmppsScanForward = 4,
|
|
wmppsScanReverse = 5,
|
|
wmppsBuffering = 6,
|
|
wmppsWaiting = 7,
|
|
wmppsMediaEnded = 8,
|
|
wmppsTransitioning = 9,
|
|
wmppsReady = 10,
|
|
wmppsReconnecting = 11,
|
|
wmppsLast = 12
|
|
};
|
|
|
|
|
|
struct IWMPMedia : public IDispatch
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isIdentical(
|
|
/* [in] */ IWMPMedia __RPC_FAR *pIWMPMedia,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvbool) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_sourceURL(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrSourceURL) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_name(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrName) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_name(
|
|
/* [in] */ BSTR pbstrName) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_imageSourceWidth(
|
|
/* [retval][out] */ long __RPC_FAR *pWidth) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_imageSourceHeight(
|
|
/* [retval][out] */ long __RPC_FAR *pHeight) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_markerCount(
|
|
/* [retval][out] */ long __RPC_FAR *pMarkerCount) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMarkerTime(
|
|
/* [in] */ long MarkerNum,
|
|
/* [retval][out] */ double __RPC_FAR *pMarkerTime) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMarkerName(
|
|
/* [in] */ long MarkerNum,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrMarkerName) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_duration(
|
|
/* [retval][out] */ double __RPC_FAR *pDuration) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_durationString(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrDuration) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_attributeCount(
|
|
/* [retval][out] */ long __RPC_FAR *plCount) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getAttributeName(
|
|
/* [in] */ long lIndex,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrItemName) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getItemInfo(
|
|
/* [in] */ BSTR bstrItemName,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrVal) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setItemInfo(
|
|
/* [in] */ BSTR bstrItemName,
|
|
/* [in] */ BSTR bstrVal) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getItemInfoByAtom(
|
|
/* [in] */ long lAtom,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrVal) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE isMemberOf(
|
|
/* [in] */ IUnknown __RPC_FAR *pPlaylist,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfIsMemberOf) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE isReadOnlyItem(
|
|
/* [in] */ BSTR bstrItemName,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfIsReadOnly) = 0;
|
|
|
|
};
|
|
|
|
struct IWMPControls : public IDispatch
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isAvailable(
|
|
/* [in] */ BSTR bstrItem,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pIsAvailable) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE play( void) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE stop( void) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE pause( void) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE fastForward( void) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE fastReverse( void) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPosition(
|
|
/* [retval][out] */ double __RPC_FAR *pdCurrentPosition) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentPosition(
|
|
/* [in] */ double pdCurrentPosition) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPositionString(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrCurrentPosition) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE next( void) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE previous( void) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentItem(
|
|
/* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppIWMPMedia) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentItem(
|
|
/* [in] */ IWMPMedia __RPC_FAR *ppIWMPMedia) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentMarker(
|
|
/* [retval][out] */ long __RPC_FAR *plMarker) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentMarker(
|
|
/* [in] */ long plMarker) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE playItem(
|
|
/* [in] */ IWMPMedia __RPC_FAR *pIWMPMedia) = 0;
|
|
|
|
};
|
|
|
|
|
|
struct IWMPSettings : public IDispatch
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isAvailable(
|
|
/* [in] */ BSTR bstrItem,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pIsAvailable) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_autoStart(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfAutoStart) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_autoStart(
|
|
/* [in] */ VARIANT_BOOL pfAutoStart) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_baseURL(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrBaseURL) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_baseURL(
|
|
/* [in] */ BSTR pbstrBaseURL) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_defaultFrame(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrDefaultFrame) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_defaultFrame(
|
|
/* [in] */ BSTR pbstrDefaultFrame) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_invokeURLs(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfInvokeURLs) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_invokeURLs(
|
|
/* [in] */ VARIANT_BOOL pfInvokeURLs) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_mute(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfMute) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_mute(
|
|
/* [in] */ VARIANT_BOOL pfMute) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playCount(
|
|
/* [retval][out] */ long __RPC_FAR *plCount) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_playCount(
|
|
/* [in] */ long plCount) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_rate(
|
|
/* [retval][out] */ double __RPC_FAR *pdRate) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_rate(
|
|
/* [in] */ double pdRate) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_balance(
|
|
/* [retval][out] */ long __RPC_FAR *plBalance) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_balance(
|
|
/* [in] */ long plBalance) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_volume(
|
|
/* [retval][out] */ long __RPC_FAR *plVolume) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_volume(
|
|
/* [in] */ long plVolume) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMode(
|
|
/* [in] */ BSTR bstrMode,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfMode) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setMode(
|
|
/* [in] */ BSTR bstrMode,
|
|
/* [in] */ VARIANT_BOOL varfMode) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableErrorDialogs(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfEnableErrorDialogs) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableErrorDialogs(
|
|
/* [in] */ VARIANT_BOOL pfEnableErrorDialogs) = 0;
|
|
|
|
};
|
|
|
|
struct IWMPNetwork : public IDispatch
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bandWidth(
|
|
/* [retval][out] */ long __RPC_FAR *plBandwidth) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_recoveredPackets(
|
|
/* [retval][out] */ long __RPC_FAR *plRecoveredPackets) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_sourceProtocol(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrSourceProtocol) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_receivedPackets(
|
|
/* [retval][out] */ long __RPC_FAR *plReceivedPackets) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_lostPackets(
|
|
/* [retval][out] */ long __RPC_FAR *plLostPackets) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_receptionQuality(
|
|
/* [retval][out] */ long __RPC_FAR *plReceptionQuality) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingCount(
|
|
/* [retval][out] */ long __RPC_FAR *plBufferingCount) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingProgress(
|
|
/* [retval][out] */ long __RPC_FAR *plBufferingProgress) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingTime(
|
|
/* [retval][out] */ long __RPC_FAR *plBufferingTime) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_bufferingTime(
|
|
/* [in] */ long plBufferingTime) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_frameRate(
|
|
/* [retval][out] */ long __RPC_FAR *plFrameRate) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_maxBitRate(
|
|
/* [retval][out] */ long __RPC_FAR *plBitRate) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bitRate(
|
|
/* [retval][out] */ long __RPC_FAR *plBitRate) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxySettings(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [retval][out] */ long __RPC_FAR *plProxySetting) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxySettings(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [in] */ long lProxySetting) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyName(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrProxyName) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyName(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [in] */ BSTR bstrProxyName) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyPort(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [retval][out] */ long __RPC_FAR *lProxyPort) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyPort(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [in] */ long lProxyPort) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyExceptionList(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrExceptionList) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyExceptionList(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [in] */ BSTR pbstrExceptionList) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyBypassForLocal(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfBypassForLocal) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyBypassForLocal(
|
|
/* [in] */ BSTR bstrProtocol,
|
|
/* [in] */ VARIANT_BOOL fBypassForLocal) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_maxBandwidth(
|
|
/* [retval][out] */ long __RPC_FAR *lMaxBandwidth) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_maxBandwidth(
|
|
/* [in] */ long lMaxBandwidth) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_downloadProgress(
|
|
/* [retval][out] */ long __RPC_FAR *plDownloadProgress) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_encodedFrameRate(
|
|
/* [retval][out] */ long __RPC_FAR *plFrameRate) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_framesSkipped(
|
|
/* [retval][out] */ long __RPC_FAR *plFrames) = 0;
|
|
|
|
};
|
|
|
|
struct IWMPCore : public IDispatch
|
|
{
|
|
public:
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE close( void) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_URL(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrURL) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_URL(
|
|
/* [in] */ BSTR pbstrURL) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_openState(
|
|
/* [retval][out] */ WMPOpenState __RPC_FAR *pwmpos) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playState(
|
|
/* [retval][out] */ WMPPlayState __RPC_FAR *pwmpps) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_controls(
|
|
/* [retval][out] */ IWMPControls __RPC_FAR *__RPC_FAR *ppControl) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_settings(
|
|
/* [retval][out] */ IWMPSettings __RPC_FAR *__RPC_FAR *ppSettings) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentMedia(
|
|
/* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppMedia) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentMedia(
|
|
/* [in] */ IUnknown __RPC_FAR *ppMedia) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_mediaCollection(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppMediaCollection) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playlistCollection(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppPlaylistCollection) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_versionInfo(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrVersionInfo) = 0;
|
|
|
|
virtual /* [id] */ HRESULT STDMETHODCALLTYPE launchURL(
|
|
/* [in] */ BSTR bstrURL) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_network(
|
|
/* [retval][out] */ IWMPNetwork __RPC_FAR *__RPC_FAR *ppQNI) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPlaylist(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppPL) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentPlaylist(
|
|
/* [in] */ IUnknown __RPC_FAR *ppPL) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_cdromCollection(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppCdromCollection) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_closedCaption(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppClosedCaption) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isOnline(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfOnline) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Error(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppError) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_status(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrStatus) = 0;
|
|
|
|
};
|
|
|
|
struct IWMPCore2 : public IWMPCore
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_dvd(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppDVD) = 0;
|
|
|
|
};
|
|
|
|
struct IWMPCore3 : public IWMPCore2
|
|
{
|
|
public:
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE newPlaylist(
|
|
/* [in] */ BSTR bstrName,
|
|
/* [in] */ BSTR bstrURL,
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppPlaylist) = 0;
|
|
|
|
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE newMedia(
|
|
/* [in] */ BSTR bstrURL,
|
|
/* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppMedia) = 0;
|
|
|
|
};
|
|
|
|
#ifdef WXTEST_ATL
|
|
MIDL_INTERFACE("6BF52A4F-394A-11D3-B153-00C04F79FAA6")
|
|
#else
|
|
struct
|
|
#endif
|
|
IWMPPlayer : public IWMPCore
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enabled(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enabled(
|
|
/* [in] */ VARIANT_BOOL pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_fullScreen(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbFullScreen) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_fullScreen(
|
|
VARIANT_BOOL pbFullScreen) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableContextMenu(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnableContextMenu) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableContextMenu(
|
|
VARIANT_BOOL pbEnableContextMenu) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_uiMode(
|
|
/* [in] */ BSTR pbstrMode) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_uiMode(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrMode) = 0;
|
|
};
|
|
|
|
struct IWMPPlayer2 : public IWMPCore
|
|
{
|
|
public:
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enabled(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enabled(
|
|
/* [in] */ VARIANT_BOOL pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_fullScreen(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbFullScreen) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_fullScreen(
|
|
VARIANT_BOOL pbFullScreen) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableContextMenu(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnableContextMenu) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableContextMenu(
|
|
VARIANT_BOOL pbEnableContextMenu) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_uiMode(
|
|
/* [in] */ BSTR pbstrMode) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_uiMode(
|
|
/* [retval][out] */ BSTR __RPC_FAR *pbstrMode) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_stretchToFit(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_stretchToFit(
|
|
/* [in] */ VARIANT_BOOL pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_windowlessVideo(
|
|
/* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
|
|
|
|
virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_windowlessVideo(
|
|
/* [in] */ VARIANT_BOOL pbEnabled) = 0;
|
|
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// wxWMP10MediaBackend
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend : public wxMediaBackendCommonBase
|
|
{
|
|
public:
|
|
wxWMP10MediaBackend();
|
|
virtual ~wxWMP10MediaBackend();
|
|
|
|
virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name);
|
|
|
|
virtual bool Play();
|
|
virtual bool Pause();
|
|
virtual bool Stop();
|
|
|
|
virtual bool Load(const wxString& fileName);
|
|
virtual bool Load(const wxURI& location);
|
|
virtual bool Load(const wxURI& location, const wxURI& proxy);
|
|
|
|
bool DoLoad(const wxString& location);
|
|
void FinishLoad();
|
|
|
|
virtual wxMediaState GetState();
|
|
|
|
virtual bool SetPosition(wxLongLong where);
|
|
virtual wxLongLong GetPosition();
|
|
virtual wxLongLong GetDuration();
|
|
|
|
virtual void Move(int x, int y, int w, int h);
|
|
wxSize GetVideoSize() const;
|
|
|
|
virtual double GetPlaybackRate();
|
|
virtual bool SetPlaybackRate(double);
|
|
|
|
virtual double GetVolume();
|
|
virtual bool SetVolume(double);
|
|
|
|
virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
|
|
|
|
virtual wxLongLong GetDownloadProgress();
|
|
virtual wxLongLong GetDownloadTotal();
|
|
|
|
|
|
#ifdef WXTEST_ATL
|
|
CAxWindow m_wndView;
|
|
#else
|
|
wxActiveXContainer* m_pAX;
|
|
#endif
|
|
IWMPPlayer* m_pWMPPlayer; // Main activex interface
|
|
IWMPSettings* m_pWMPSettings; // Settings such as volume
|
|
IWMPControls* m_pWMPControls; // Control interface (play etc.)
|
|
wxSize m_bestSize; // Actual movie size
|
|
|
|
bool m_bWasStateChanged; // See the "introduction"
|
|
wxEvtHandler* m_evthandler;
|
|
|
|
friend class wxWMP10MediaEvtHandler;
|
|
DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend)
|
|
};
|
|
|
|
#ifndef WXTEST_ATL
|
|
class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler : public wxEvtHandler
|
|
{
|
|
public:
|
|
wxWMP10MediaEvtHandler(wxWMP10MediaBackend *amb) :
|
|
m_amb(amb)
|
|
{
|
|
m_amb->m_pAX->Connect(m_amb->m_pAX->GetId(),
|
|
wxEVT_ACTIVEX,
|
|
wxActiveXEventHandler(wxWMP10MediaEvtHandler::OnActiveX),
|
|
NULL, this
|
|
);
|
|
}
|
|
|
|
void OnActiveX(wxActiveXEvent& event);
|
|
|
|
private:
|
|
wxWMP10MediaBackend *m_amb;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler);
|
|
};
|
|
#endif
|
|
|
|
//===========================================================================
|
|
// IMPLEMENTATION
|
|
//===========================================================================
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// wxWMP10MediaBackend
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend, wxMediaBackend)
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend Constructor
|
|
//---------------------------------------------------------------------------
|
|
wxWMP10MediaBackend::wxWMP10MediaBackend()
|
|
:
|
|
#ifndef WXTEST_ATL
|
|
m_pAX(NULL),
|
|
#endif
|
|
m_pWMPPlayer(NULL),
|
|
m_pWMPSettings(NULL),
|
|
m_pWMPControls(NULL)
|
|
|
|
{
|
|
m_evthandler = NULL;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend Destructor
|
|
//---------------------------------------------------------------------------
|
|
wxWMP10MediaBackend::~wxWMP10MediaBackend()
|
|
{
|
|
if(m_pWMPPlayer)
|
|
{
|
|
#ifndef WXTEST_ATL
|
|
m_pAX->DissociateHandle();
|
|
delete m_pAX;
|
|
|
|
if (m_evthandler)
|
|
{
|
|
m_ctrl->RemoveEventHandler(m_evthandler);
|
|
delete m_evthandler;
|
|
}
|
|
#else
|
|
AtlAxWinTerm();
|
|
_Module.Term();
|
|
#endif
|
|
|
|
m_pWMPPlayer->Release();
|
|
if (m_pWMPSettings)
|
|
m_pWMPSettings->Release();
|
|
if (m_pWMPControls)
|
|
m_pWMPControls->Release();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::CreateControl
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxValidator& validator,
|
|
const wxString& name)
|
|
{
|
|
#ifndef WXTEST_ATL
|
|
if( ::CoCreateInstance(CLSID_WMP10, NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWMPPlayer, (void**)&m_pWMPPlayer) != 0 )
|
|
{
|
|
if( ::CoCreateInstance(CLSID_WMP10ALT, NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWMPPlayer, (void**)&m_pWMPPlayer) != 0 )
|
|
return false;
|
|
|
|
if( m_pWMPPlayer->get_settings(&m_pWMPSettings) != 0)
|
|
{
|
|
m_pWMPPlayer->Release();
|
|
wxLogSysError(wxT("Could not obtain settings from WMP10!"));
|
|
return false;
|
|
}
|
|
|
|
if( m_pWMPPlayer->get_controls(&m_pWMPControls) != 0)
|
|
{
|
|
m_pWMPSettings->Release();
|
|
m_pWMPPlayer->Release();
|
|
wxLogSysError(wxT("Could not obtain controls from WMP10!"));
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Create window
|
|
// By default wxWindow(s) is created with a border -
|
|
// so we need to get rid of those
|
|
//
|
|
// Since we don't have a child window like most other
|
|
// backends, we don't need wxCLIP_CHILDREN
|
|
//
|
|
if ( !ctrl->wxControl::Create(parent, id, pos, size,
|
|
(style & ~wxBORDER_MASK) | wxBORDER_NONE,
|
|
validator, name) )
|
|
return false;
|
|
|
|
//
|
|
// Now create the ActiveX container along with the media player
|
|
// interface and query them
|
|
//
|
|
m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
|
|
|
|
#ifndef WXTEST_ATL
|
|
m_pAX = new wxActiveXContainer(ctrl, IID_IWMPPlayer, m_pWMPPlayer);
|
|
|
|
// Connect for events
|
|
m_evthandler = new wxWMP10MediaEvtHandler(this);
|
|
m_ctrl->PushEventHandler(m_evthandler);
|
|
#else
|
|
_Module.Init(NULL, ::GetModuleHandle(NULL));
|
|
AtlAxWinInit();
|
|
CComPtr<IAxWinHostWindow> spHost;
|
|
|
|
HRESULT hr;
|
|
RECT rcClient;
|
|
::GetClientRect((HWND)ctrl->GetHandle(), &rcClient);
|
|
m_wndView.Create((HWND)ctrl->GetHandle(), rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
|
|
hr = m_wndView.QueryHost(&spHost);
|
|
hr = spHost->CreateControl(CComBSTR(wxT("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
|
|
hr = m_wndView.QueryControl(&m_pWMPPlayer);
|
|
|
|
if( m_pWMPPlayer->get_settings(&m_pWMPSettings) != 0)
|
|
{
|
|
m_pWMPPlayer->Release();
|
|
wxLogSysError(wxT("Could not obtain settings from WMP10!"));
|
|
return false;
|
|
}
|
|
|
|
if( m_pWMPPlayer->get_controls(&m_pWMPControls) != 0)
|
|
{
|
|
m_pWMPSettings->Release();
|
|
m_pWMPPlayer->Release();
|
|
wxLogSysError(wxT("Could not obtain controls from WMP10!"));
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Here we set up wx-specific stuff for the default
|
|
// settings wxMediaCtrl says it will stay to
|
|
//
|
|
|
|
IWMPPlayer2* pWMPPlayer2; // Only 2 has windowless video and stretchtofit
|
|
if(m_pWMPPlayer->QueryInterface(IID_IWMPPlayer2, (void**)&pWMPPlayer2) == 0)
|
|
{
|
|
// We don't check errors here as these arn't particularly important
|
|
// and may not be implemented (i.e. stretchToFit on CE)
|
|
pWMPPlayer2->put_windowlessVideo(VARIANT_TRUE);
|
|
pWMPPlayer2->put_stretchToFit(VARIANT_TRUE);
|
|
pWMPPlayer2->Release();
|
|
}
|
|
|
|
// by default true (see the "introduction")
|
|
m_pWMPSettings->put_autoStart(VARIANT_TRUE);
|
|
// by default enabled
|
|
wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);
|
|
// by default with AM only 0.5
|
|
wxWMP10MediaBackend::SetVolume(1.0);
|
|
|
|
// don't erase the background of our control window so that resizing is a
|
|
// bit smoother
|
|
m_ctrl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
|
|
|
// success
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Load (file version)
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Load(const wxString& fileName)
|
|
{
|
|
return DoLoad(fileName);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Load (URL Version)
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Load(const wxURI& location)
|
|
{
|
|
return DoLoad(location.BuildURI());
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Load (URL Version with Proxy)
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Load(const wxURI& location,
|
|
const wxURI& proxy)
|
|
{
|
|
bool bOK = false;
|
|
|
|
IWMPNetwork* pWMPNetwork;
|
|
if( m_pWMPPlayer->get_network(&pWMPNetwork) == 0 )
|
|
{
|
|
long lOldSetting;
|
|
if( pWMPNetwork->getProxySettings(
|
|
wxBasicString(location.GetScheme()).Get(), &lOldSetting
|
|
) == 0 &&
|
|
|
|
pWMPNetwork->setProxySettings(
|
|
wxBasicString(location.GetScheme()).Get(), // protocol
|
|
2) == 0) // 2 == manually specify
|
|
{
|
|
BSTR bsOldName = NULL;
|
|
long lOldPort = 0;
|
|
|
|
pWMPNetwork->getProxyName(
|
|
wxBasicString(location.GetScheme()).Get(),
|
|
&bsOldName);
|
|
pWMPNetwork->getProxyPort(
|
|
wxBasicString(location.GetScheme()).Get(),
|
|
&lOldPort);
|
|
|
|
long lPort;
|
|
wxString server;
|
|
if(proxy.IsReference())
|
|
{
|
|
server = proxy.GetScheme();
|
|
lPort = wxAtoi(proxy.GetPath());
|
|
}
|
|
else
|
|
{
|
|
server = proxy.GetServer();
|
|
lPort = wxAtoi(proxy.GetPort());
|
|
}
|
|
|
|
if( pWMPNetwork->setProxyName(
|
|
wxBasicString(location.GetScheme()).Get(), // proto
|
|
wxBasicString(server).Get() ) == 0 &&
|
|
|
|
pWMPNetwork->setProxyPort(
|
|
wxBasicString(location.GetScheme()).Get(), // proto
|
|
lPort
|
|
) == 0
|
|
)
|
|
{
|
|
bOK = DoLoad(location.BuildURI());
|
|
|
|
pWMPNetwork->setProxySettings(
|
|
wxBasicString(location.GetScheme()).Get(), // protocol
|
|
lOldSetting);
|
|
if(bsOldName)
|
|
pWMPNetwork->setProxyName(
|
|
wxBasicString(location.GetScheme()).Get(), // protocol
|
|
bsOldName);
|
|
|
|
if(lOldPort)
|
|
pWMPNetwork->setProxyPort(
|
|
wxBasicString(location.GetScheme()).Get(), // protocol
|
|
lOldPort);
|
|
|
|
pWMPNetwork->Release();
|
|
}
|
|
else
|
|
pWMPNetwork->Release();
|
|
|
|
}
|
|
else
|
|
pWMPNetwork->Release();
|
|
|
|
}
|
|
|
|
return bOK;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::DoLoad
|
|
//
|
|
// Called by all functions - this actually renders
|
|
// the file and sets up the filter graph
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::DoLoad(const wxString& location)
|
|
{
|
|
HRESULT hr;
|
|
|
|
#if 0 // See the "introduction" - this is the duration hack
|
|
// ------------------ BLATENT HACK ALERT -------------------------
|
|
// Normally we can only get the duration of things already in an
|
|
// existing playlist or playing - however this clever "workaround"
|
|
// enables us to get the duration even when stopped :)
|
|
// http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx
|
|
|
|
IWMPCore3* pWMPCore3;
|
|
double outDuration;
|
|
if(m_pWMPPlayer->QueryInterface(IID_IWMPCore3, (void**) &pWMPCore3) == 0)
|
|
{
|
|
IWMPMedia* pWMPMedia;
|
|
|
|
if( (hr = pWMPCore3->newMedia(wxBasicString(location).Get(),
|
|
&pWMPMedia)) == 0)
|
|
{
|
|
// this (get_duration) will actually FAIL, but it will work.
|
|
pWMPMedia->get_duration(&outDuration);
|
|
pWMPCore3->put_currentMedia(pWMPMedia);
|
|
pWMPMedia->Release();
|
|
}
|
|
|
|
pWMPCore3->Release();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
// just load it the "normal" way
|
|
hr = m_pWMPPlayer->put_URL( wxBasicString(location).Get() );
|
|
}
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::FinishLoad
|
|
//
|
|
// Called when our media is about to play (a.k.a. wmposMediaOpen)
|
|
//---------------------------------------------------------------------------
|
|
void wxWMP10MediaBackend::FinishLoad()
|
|
{
|
|
// Get the original video size
|
|
// THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY
|
|
// See the "introduction" - also get_currentMedia will return
|
|
// "1" which is a VALID HRESULT value
|
|
// and a NULL pWMPMedia if the media isn't the "current" one
|
|
// which is rather unintuitive in the sense that it uses it
|
|
// (i.e. basically not currently playing)...
|
|
IWMPMedia* pWMPMedia;
|
|
if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
|
|
{
|
|
pWMPMedia->get_imageSourceWidth((long*)&m_bestSize.x);
|
|
pWMPMedia->get_imageSourceHeight((long*)&m_bestSize.y);
|
|
pWMPMedia->Release();
|
|
}
|
|
else
|
|
{
|
|
wxLogDebug(wxT("Could not get media"));
|
|
}
|
|
|
|
NotifyMovieLoaded();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::ShowPlayerControls
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
|
|
{
|
|
if(!flags)
|
|
{
|
|
m_pWMPPlayer->put_enabled(VARIANT_FALSE);
|
|
m_pWMPPlayer->put_uiMode(wxBasicString(wxT("none")).Get());
|
|
}
|
|
else
|
|
{
|
|
// TODO: use "custom"? (note that CE only supports none/full)
|
|
m_pWMPPlayer->put_uiMode(wxBasicString(wxT("full")).Get());
|
|
m_pWMPPlayer->put_enabled(VARIANT_TRUE);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Play
|
|
//
|
|
// Plays the stream. If it is non-seekable, it will restart it (implicit).
|
|
//
|
|
// TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here
|
|
// but do we need to?
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Play()
|
|
{
|
|
// Actually try to play the movie (will fail if not loaded completely)
|
|
HRESULT hr = m_pWMPControls->play();
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
m_bWasStateChanged = true;
|
|
return true;
|
|
}
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Pause
|
|
//
|
|
// Pauses the stream.
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Pause()
|
|
{
|
|
HRESULT hr = m_pWMPControls->pause();
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
m_bWasStateChanged = true;
|
|
return true;
|
|
}
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Stop
|
|
//
|
|
// Stops the stream.
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::Stop()
|
|
{
|
|
HRESULT hr = m_pWMPControls->stop();
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Seek to beginning
|
|
wxWMP10MediaBackend::SetPosition(0);
|
|
m_bWasStateChanged = true;
|
|
return true;
|
|
}
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::SetPosition
|
|
//
|
|
// WMP10 position values are a double in seconds - we just translate
|
|
// to our base here
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::SetPosition(wxLongLong where)
|
|
{
|
|
HRESULT hr = m_pWMPControls->put_currentPosition(
|
|
((LONGLONG)where.GetValue()) / 1000.0
|
|
);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetPosition
|
|
//
|
|
// WMP10 position values are a double in seconds - we just translate
|
|
// to our base here
|
|
//---------------------------------------------------------------------------
|
|
wxLongLong wxWMP10MediaBackend::GetPosition()
|
|
{
|
|
double outCur;
|
|
HRESULT hr = m_pWMPControls->get_currentPosition(&outCur);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return 0;
|
|
}
|
|
|
|
// h,m,s,milli - outCur is in 1 second (double)
|
|
outCur *= 1000;
|
|
wxLongLong ll;
|
|
ll.Assign(outCur);
|
|
|
|
return ll;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetVolume
|
|
//
|
|
// Volume 0-100
|
|
//---------------------------------------------------------------------------
|
|
double wxWMP10MediaBackend::GetVolume()
|
|
{
|
|
long lVolume;
|
|
HRESULT hr = m_pWMPSettings->get_volume(&lVolume);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return 0.0;
|
|
}
|
|
|
|
return (double)lVolume / 100.0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::SetVolume
|
|
//
|
|
// Volume 0-100
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::SetVolume(double dVolume)
|
|
{
|
|
HRESULT hr = m_pWMPSettings->put_volume( (long) (dVolume * 100.0) );
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetDuration
|
|
//
|
|
// Obtains the duration of the media.
|
|
//
|
|
// See the "introduction"
|
|
//
|
|
// The good news is that this doesn't appear to have the XING header
|
|
// parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has
|
|
//---------------------------------------------------------------------------
|
|
wxLongLong wxWMP10MediaBackend::GetDuration()
|
|
{
|
|
double outDuration = 0.0;
|
|
|
|
IWMPMedia* pWMPMedia;
|
|
if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
|
|
{
|
|
if(pWMPMedia->get_duration(&outDuration) != 0)
|
|
{
|
|
wxLogDebug(wxT("get_duration failed"));
|
|
}
|
|
pWMPMedia->Release();
|
|
}
|
|
|
|
|
|
// h,m,s,milli - outDuration is in 1 second (double)
|
|
outDuration *= 1000;
|
|
wxLongLong ll;
|
|
ll.Assign(outDuration);
|
|
|
|
return ll;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetState
|
|
//
|
|
// Returns the current state
|
|
//---------------------------------------------------------------------------
|
|
wxMediaState wxWMP10MediaBackend::GetState()
|
|
{
|
|
WMPPlayState nState;
|
|
HRESULT hr = m_pWMPPlayer->get_playState(&nState);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return wxMEDIASTATE_STOPPED;
|
|
}
|
|
|
|
switch(nState)
|
|
{
|
|
case wmppsPaused:
|
|
return wxMEDIASTATE_PAUSED;
|
|
case wmppsPlaying:
|
|
return wxMEDIASTATE_PLAYING;
|
|
default:
|
|
return wxMEDIASTATE_STOPPED;
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetPlaybackRate
|
|
//
|
|
// Just get the rate from WMP10
|
|
//---------------------------------------------------------------------------
|
|
double wxWMP10MediaBackend::GetPlaybackRate()
|
|
{
|
|
double dRate;
|
|
HRESULT hr = m_pWMPSettings->get_rate(&dRate);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return 0.0;
|
|
}
|
|
return dRate;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::SetPlaybackRate
|
|
//
|
|
// Sets the playback rate of the media - DirectShow is pretty good
|
|
// about this, actually
|
|
//---------------------------------------------------------------------------
|
|
bool wxWMP10MediaBackend::SetPlaybackRate(double dRate)
|
|
{
|
|
HRESULT hr = m_pWMPSettings->put_rate(dRate);
|
|
if(FAILED(hr))
|
|
{
|
|
wxWMP10LOG(hr);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetVideoSize
|
|
//
|
|
// Obtains the cached original video size
|
|
//---------------------------------------------------------------------------
|
|
wxSize wxWMP10MediaBackend::GetVideoSize() const
|
|
{
|
|
return m_bestSize;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::Move
|
|
//
|
|
// We take care of this in our redrawing
|
|
//---------------------------------------------------------------------------
|
|
void wxWMP10MediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
|
|
#ifdef WXTEST_ATL
|
|
int w, int h
|
|
#else
|
|
int WXUNUSED(w), int WXUNUSED(h)
|
|
#endif
|
|
)
|
|
{
|
|
#ifdef WXTEST_ATL
|
|
m_wndView.MoveWindow(0,0,w,h);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetDownloadProgress()
|
|
//---------------------------------------------------------------------------
|
|
wxLongLong wxWMP10MediaBackend::GetDownloadProgress()
|
|
{
|
|
IWMPNetwork* pWMPNetwork;
|
|
if( m_pWMPPlayer->get_network(&pWMPNetwork) == 0 )
|
|
{
|
|
long lPercentProg;
|
|
if(pWMPNetwork->get_downloadProgress(&lPercentProg) == 0)
|
|
{
|
|
pWMPNetwork->Release();
|
|
return (GetDownloadTotal() * lPercentProg) / 100;
|
|
}
|
|
pWMPNetwork->Release();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::GetDownloadTotal()
|
|
//---------------------------------------------------------------------------
|
|
wxLongLong wxWMP10MediaBackend::GetDownloadTotal()
|
|
{
|
|
IWMPMedia* pWMPMedia;
|
|
if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
|
|
{
|
|
BSTR bsOut;
|
|
pWMPMedia->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
|
|
&bsOut);
|
|
|
|
wxString sFileSize = wxConvertStringFromOle(bsOut);
|
|
long lFS;
|
|
sFileSize.ToLong(&lFS);
|
|
pWMPMedia->Release();
|
|
return lFS;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// wxWMP10MediaBackend::OnActiveX
|
|
//
|
|
// Handle events sent from our activex control (_WMPOCXEvents actually).
|
|
//
|
|
// The weird numbers in the switch statement here are "dispatch ids"
|
|
// (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl
|
|
// and wmp.IDL.
|
|
//---------------------------------------------------------------------------
|
|
#ifndef WXTEST_ATL
|
|
void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent& event)
|
|
{
|
|
switch(event.GetDispatchId())
|
|
{
|
|
case 0x000013ed: // playstatechange
|
|
if(event.ParamCount() >= 1)
|
|
{
|
|
switch (event[0].GetInteger())
|
|
{
|
|
case wmppsMediaEnded: // media ended
|
|
if ( m_amb->SendStopEvent() )
|
|
{
|
|
// NB: If we do Stop() or similar here the media
|
|
// actually starts over and plays a bit before
|
|
// stopping. It stops by default, however, so
|
|
// there is no real need to do anything here...
|
|
|
|
// send the event to our child
|
|
m_amb->QueueFinishEvent();
|
|
}
|
|
break;
|
|
|
|
case wmppsStopped: // stopping
|
|
m_amb->QueueStopEvent();
|
|
break;
|
|
case wmppsPaused: // pause
|
|
m_amb->QueuePauseEvent();
|
|
break;
|
|
case wmppsPlaying: // play
|
|
m_amb->QueuePlayEvent();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
event.Skip();
|
|
break;
|
|
|
|
case 0x00001389: // openstatechange
|
|
if(event.ParamCount() >= 1)
|
|
{
|
|
int nState = event[0].GetInteger();
|
|
if(nState == wmposMediaOpen)
|
|
{
|
|
// See the "introduction"
|
|
m_amb->m_bWasStateChanged = false;
|
|
m_amb->FinishLoad();
|
|
if(!m_amb->m_bWasStateChanged)
|
|
m_amb->Stop();
|
|
}
|
|
}
|
|
else
|
|
event.Skip();
|
|
break;
|
|
|
|
case 0x0000196e: // mousedown
|
|
m_amb->m_ctrl->SetFocus();
|
|
break;
|
|
|
|
default:
|
|
event.Skip();
|
|
return;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
// Allow the user code to use wxFORCE_LINK_MODULE() to ensure that this object
|
|
// file is not discarded by the linker.
|
|
#include "wx/link.h"
|
|
wxFORCE_LINK_THIS_MODULE(wxmediabackend_wmp10)
|
|
|
|
#if 0 // Windows Media Player Mobile 9 hacks
|
|
|
|
//------------------WMP Mobile 9 hacks-----------------------------------
|
|
// It was mentioned in the introduction that while there was no official
|
|
// programming interface on WMP mobile 9
|
|
// (SmartPhone/Pocket PC 2003 emulator etc.)
|
|
// there were some windows message hacks that are able to get
|
|
// you playing a file through WMP.
|
|
//
|
|
// Here are those hacks. They do indeed "work" as expected - just call
|
|
// SendMessage with one of those myterious values laid out in
|
|
// Peter Foot's Friday, May 21, 2004 Blog Post on the issue.
|
|
// (He says they are in a registery section entitled "Pendant Bus")
|
|
//
|
|
// How do you play a certain file? Simply calling "start [file]" or
|
|
// wxWinCEExecute([file]) should do the trick
|
|
|
|
bool wxWinCEExecute(const wxString& path, int nShowStyle = SW_SHOWNORMAL)
|
|
{
|
|
WinStruct<SHELLEXECUTEINFO> sei;
|
|
sei.lpFile = path.c_str();
|
|
sei.lpVerb = wxT("open");
|
|
sei.nShow = nShowStyle;
|
|
|
|
::ShellExecuteEx(&sei);
|
|
|
|
return ((int) sei.hInstApp) > 32;
|
|
}
|
|
|
|
bool MyApp::OnInit()
|
|
{
|
|
HWND hwnd = ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
|
|
if(!hwnd)
|
|
{
|
|
if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE) )
|
|
{
|
|
hwnd = ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
|
|
}
|
|
}
|
|
|
|
if(hwnd)
|
|
{
|
|
// hide wmp window
|
|
::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,
|
|
SWP_NOMOVE|SWP_NOSIZE|SWP_HIDEWINDOW);
|
|
|
|
// Stop == 32970
|
|
// Prev Track == 32971
|
|
// Next Track == 32972
|
|
// Shuffle == 32973
|
|
// Repeat == 32974
|
|
// Vol Up == 32975
|
|
// Vol Down == 32976
|
|
// Play == 32978
|
|
::SendMessage(hwnd, 32978, NULL, 0);
|
|
}
|
|
}
|
|
|
|
#endif // WMP mobile 9 hacks
|
|
|
|
#endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX
|