1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/mediactrl_wmp10.cpp 
   3 // Purpose:     Windows Media Player 9/10 Media Backend for Windows 
   4 // Author:      Ryan Norton <wxprojects@comcast.net> 
   8 // Copyright:   (c) Ryan Norton 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 //-----------------Introduction---------------------------------------------- 
  13 // This backend is for Desktops with either WMP 9 or 10 and Windows 
  14 // mobile (5.0, some 2003 SmartPhones etc.) WMP 10 only (9 has no automation 
  15 // interface but you can hack it with message hacks to play through 
  16 // a currently running instance of media player). 
  18 // There are quite a few WMP 10 interfaces and unlike other media 
  19 // backends we actually set it to automatically play files as it has 
  20 // as huge caveat that you cannot (technically) obtain media information 
  21 // from IWMPMedia including duration and video size until a media file 
  22 // has literally started to play. There is a hack (and indeed we have 
  23 // it within this file) to enable duration getting from a non-playing 
  24 // file, but there is no hack I (RN) know of to get the video size from 
  25 // a file that isn't playing. 
  27 // The workaround for this is to send the wxEVT_MEDIA_LOADED when the file 
  28 // is about to be played - and if the user didn't change the state of the 
  29 // media (m_bWasStateChanged), when set it back to the stop state. 
  31 // The ActiveX control itself is particularily stubborn, calling 
  32 // IOleInPlaceSite::OnPosRectChange every file change trying to set itself 
  33 // to something different then what we told it to before. 
  36 // http://msdn.microsoft.com/library/en-us/wmplay10/mmp_sdk/windowsmediaplayer10sdk.asp 
  38 //=========================================================================== 
  40 //=========================================================================== 
  42 //--------------------------------------------------------------------------- 
  43 // Pre-compiled header stuff 
  44 //--------------------------------------------------------------------------- 
  46 // For compilers that support precompilation, includes "wx.h". 
  47 #include "wx/wxprec.h" 
  53 #if wxUSE_MEDIACTRL && wxUSE_ACTIVEX 
  55 #include "wx/mediactrl.h" 
  61 #include "wx/msw/private.h" // user info and wndproc setting/getting 
  62 #include "wx/msw/ole/activex.h" // wxActiveXContainer - COM-specific stuff 
  64 //--------------------------------------------------------------------------- 
  65 // ATL Includes - define WXTEST_ATL if you 
  66 // want to use CAxWindow instead of wxActiveXContainer (note that 
  67 // this is mainly for testing as the activex events arn't implemented here) 
  68 //--------------------------------------------------------------------------- 
  76     #define min(x,y) (x < y ? x : y) 
  82 //--------------------------------------------------------------------------- 
  84 //--------------------------------------------------------------------------- 
  86 // disable "cast truncates constant value" for VARIANT_BOOL values 
  87 // passed as parameters in VC6 
  89 #pragma warning (disable:4310) 
  92 // error logger for HRESULTS (nothing really now) 
  95 //--------------------------------------------------------------------------- 
  96 // Various definitions dumped from wmp.IDL 
  97 //--------------------------------------------------------------------------- 
  99 // CLSID_WMP10ALT is on CE and in some MS docs - on others it is the plain ver 
 100 const CLSID CLSID_WMP10              
= {0x6BF52A50,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}}; 
 101 const CLSID CLSID_WMP10ALT           
= {0x6BF52A52,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}}; 
 103 const IID IID_IWMPSettings 
= {0x9104D1AB,0x80C9,0x4FED,{0xAB,0xF0,0x2E,0x64,0x17,0xA6,0xDF,0x14}}; 
 104 const IID IID_IWMPCore 
= {0xD84CCA99,0xCCE2,0x11D2,{0x9E,0xCC,0x00,0x00,0xF8,0x08,0x59,0x81}}; 
 106     const IID IID_IWMPPlayer 
= {0x6BF52A4F,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}}; 
 109 const IID IID_IWMPMedia 
= {0x94D55E95,0x3FAC,0x11D3,{0xB1,0x55,0x00,0xC0,0x4F,0x79,0xFA,0xA6}}; 
 110 const IID IID_IWMPControls 
= {0x74C09E02,0xF828,0x11D2,{0xA7,0x4B,0x00,0xA0,0xC9,0x05,0xF3,0x6E}}; 
 111 const IID IID_IWMPPlayer2 
= {0x0E6B01D1,0xD407,0x4C85,{0xBF,0x5F,0x1C,0x01,0xF6,0x15,0x02,0x80}}; 
 112 const IID IID_IWMPCore2 
= {0xBC17E5B7,0x7561,0x4C18,{0xBB,0x90,0x17,0xD4,0x85,0x77,0x56,0x59}}; 
 113 const IID IID_IWMPCore3 
= {0x7587C667,0x628F,0x499F,{0x88,0xE7,0x6A,0x6F,0x4E,0x88,0x84,0x64}}; 
 114 const IID IID_IWMPNetwork 
= {0xEC21B779,0xEDEF,0x462D,{0xBB,0xA4,0xAD,0x9D,0xDE,0x2B,0x29,0xA7}}; 
 119     wmposPlaylistChanging   
= 1, 
 120     wmposPlaylistLocating   
= 2, 
 121     wmposPlaylistConnecting 
= 3, 
 122     wmposPlaylistLoading    
= 4, 
 123     wmposPlaylistOpening    
= 5, 
 124     wmposPlaylistOpenNoMedia    
= 6, 
 125     wmposPlaylistChanged    
= 7, 
 126     wmposMediaChanging  
= 8, 
 127     wmposMediaLocating  
= 9, 
 128     wmposMediaConnecting    
= 10, 
 129     wmposMediaLoading   
= 11, 
 130     wmposMediaOpening   
= 12, 
 132     wmposBeginCodecAcquisition  
= 14, 
 133     wmposEndCodecAcquisition    
= 15, 
 134     wmposBeginLicenseAcquisition    
= 16, 
 135     wmposEndLicenseAcquisition  
= 17, 
 136     wmposBeginIndividualization 
= 18, 
 137     wmposEndIndividualization   
= 19, 
 138     wmposMediaWaiting   
= 20, 
 139     wmposOpeningUnknownURL  
= 21 
 148     wmppsScanForward    
= 4, 
 149     wmppsScanReverse    
= 5, 
 153     wmppsTransitioning  
= 9, 
 155     wmppsReconnecting   
= 11, 
 160 struct IWMPMedia 
: public IDispatch
 
 163     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_isIdentical( 
 164         /* [in] */ IWMPMedia __RPC_FAR 
*pIWMPMedia
, 
 165         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pvbool
) = 0; 
 167     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_sourceURL( 
 168         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrSourceURL
) = 0; 
 170     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_name( 
 171         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrName
) = 0; 
 173     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_name( 
 174         /* [in] */ BSTR pbstrName
) = 0; 
 176     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_imageSourceWidth( 
 177         /* [retval][out] */ long __RPC_FAR 
*pWidth
) = 0; 
 179     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_imageSourceHeight( 
 180         /* [retval][out] */ long __RPC_FAR 
*pHeight
) = 0; 
 182     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_markerCount( 
 183         /* [retval][out] */ long __RPC_FAR 
*pMarkerCount
) = 0; 
 185     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getMarkerTime( 
 186         /* [in] */ long MarkerNum
, 
 187         /* [retval][out] */ double __RPC_FAR 
*pMarkerTime
) = 0; 
 189     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getMarkerName( 
 190         /* [in] */ long MarkerNum
, 
 191         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrMarkerName
) = 0; 
 193     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_duration( 
 194         /* [retval][out] */ double __RPC_FAR 
*pDuration
) = 0; 
 196     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_durationString( 
 197         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrDuration
) = 0; 
 199     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_attributeCount( 
 200         /* [retval][out] */ long __RPC_FAR 
*plCount
) = 0; 
 202     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getAttributeName( 
 203         /* [in] */ long lIndex
, 
 204         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrItemName
) = 0; 
 206     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getItemInfo( 
 207         /* [in] */ BSTR bstrItemName
, 
 208         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrVal
) = 0; 
 210     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setItemInfo( 
 211         /* [in] */ BSTR bstrItemName
, 
 212         /* [in] */ BSTR bstrVal
) = 0; 
 214     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getItemInfoByAtom( 
 215         /* [in] */ long lAtom
, 
 216         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrVal
) = 0; 
 218     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
isMemberOf( 
 219         /* [in] */ IUnknown __RPC_FAR 
*pPlaylist
, 
 220         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pvarfIsMemberOf
) = 0; 
 222     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
isReadOnlyItem( 
 223         /* [in] */ BSTR bstrItemName
, 
 224         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pvarfIsReadOnly
) = 0; 
 228 struct IWMPControls 
: public IDispatch
 
 231     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_isAvailable( 
 232         /* [in] */ BSTR bstrItem
, 
 233         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pIsAvailable
) = 0; 
 235     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
play( void) = 0; 
 237     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
stop( void) = 0; 
 239     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
pause( void) = 0; 
 241     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
fastForward( void) = 0; 
 243     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
fastReverse( void) = 0; 
 245     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentPosition( 
 246         /* [retval][out] */ double __RPC_FAR 
*pdCurrentPosition
) = 0; 
 248     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_currentPosition( 
 249         /* [in] */ double pdCurrentPosition
) = 0; 
 251     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentPositionString( 
 252         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrCurrentPosition
) = 0; 
 254     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
next( void) = 0; 
 256     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
previous( void) = 0; 
 258     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentItem( 
 259         /* [retval][out] */ IWMPMedia __RPC_FAR 
*__RPC_FAR 
*ppIWMPMedia
) = 0; 
 261     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_currentItem( 
 262         /* [in] */ IWMPMedia __RPC_FAR 
*ppIWMPMedia
) = 0; 
 264     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentMarker( 
 265         /* [retval][out] */ long __RPC_FAR 
*plMarker
) = 0; 
 267     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_currentMarker( 
 268         /* [in] */ long plMarker
) = 0; 
 270     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
playItem( 
 271         /* [in] */ IWMPMedia __RPC_FAR 
*pIWMPMedia
) = 0; 
 276 struct IWMPSettings 
: public IDispatch
 
 279     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_isAvailable( 
 280         /* [in] */ BSTR bstrItem
, 
 281         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pIsAvailable
) = 0; 
 283     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_autoStart( 
 284         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfAutoStart
) = 0; 
 286     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_autoStart( 
 287         /* [in] */ VARIANT_BOOL pfAutoStart
) = 0; 
 289     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_baseURL( 
 290         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrBaseURL
) = 0; 
 292     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_baseURL( 
 293         /* [in] */ BSTR pbstrBaseURL
) = 0; 
 295     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_defaultFrame( 
 296         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrDefaultFrame
) = 0; 
 298     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_defaultFrame( 
 299         /* [in] */ BSTR pbstrDefaultFrame
) = 0; 
 301     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_invokeURLs( 
 302         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfInvokeURLs
) = 0; 
 304     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_invokeURLs( 
 305         /* [in] */ VARIANT_BOOL pfInvokeURLs
) = 0; 
 307     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_mute( 
 308         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfMute
) = 0; 
 310     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_mute( 
 311         /* [in] */ VARIANT_BOOL pfMute
) = 0; 
 313     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_playCount( 
 314         /* [retval][out] */ long __RPC_FAR 
*plCount
) = 0; 
 316     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_playCount( 
 317         /* [in] */ long plCount
) = 0; 
 319     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_rate( 
 320         /* [retval][out] */ double __RPC_FAR 
*pdRate
) = 0; 
 322     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_rate( 
 323         /* [in] */ double pdRate
) = 0; 
 325     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_balance( 
 326         /* [retval][out] */ long __RPC_FAR 
*plBalance
) = 0; 
 328     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_balance( 
 329         /* [in] */ long plBalance
) = 0; 
 331     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_volume( 
 332         /* [retval][out] */ long __RPC_FAR 
*plVolume
) = 0; 
 334     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_volume( 
 335         /* [in] */ long plVolume
) = 0; 
 337     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getMode( 
 338         /* [in] */ BSTR bstrMode
, 
 339         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pvarfMode
) = 0; 
 341     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setMode( 
 342         /* [in] */ BSTR bstrMode
, 
 343         /* [in] */ VARIANT_BOOL varfMode
) = 0; 
 345     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_enableErrorDialogs( 
 346         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfEnableErrorDialogs
) = 0; 
 348     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_enableErrorDialogs( 
 349         /* [in] */ VARIANT_BOOL pfEnableErrorDialogs
) = 0; 
 353 struct IWMPNetwork 
: public IDispatch
 
 356     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_bandWidth( 
 357         /* [retval][out] */ long __RPC_FAR 
*plBandwidth
) = 0; 
 359     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_recoveredPackets( 
 360         /* [retval][out] */ long __RPC_FAR 
*plRecoveredPackets
) = 0; 
 362     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_sourceProtocol( 
 363         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrSourceProtocol
) = 0; 
 365     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_receivedPackets( 
 366         /* [retval][out] */ long __RPC_FAR 
*plReceivedPackets
) = 0; 
 368     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_lostPackets( 
 369         /* [retval][out] */ long __RPC_FAR 
*plLostPackets
) = 0; 
 371     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_receptionQuality( 
 372         /* [retval][out] */ long __RPC_FAR 
*plReceptionQuality
) = 0; 
 374     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_bufferingCount( 
 375         /* [retval][out] */ long __RPC_FAR 
*plBufferingCount
) = 0; 
 377     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_bufferingProgress( 
 378         /* [retval][out] */ long __RPC_FAR 
*plBufferingProgress
) = 0; 
 380     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_bufferingTime( 
 381         /* [retval][out] */ long __RPC_FAR 
*plBufferingTime
) = 0; 
 383     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_bufferingTime( 
 384         /* [in] */ long plBufferingTime
) = 0; 
 386     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_frameRate( 
 387         /* [retval][out] */ long __RPC_FAR 
*plFrameRate
) = 0; 
 389     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_maxBitRate( 
 390         /* [retval][out] */ long __RPC_FAR 
*plBitRate
) = 0; 
 392     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_bitRate( 
 393         /* [retval][out] */ long __RPC_FAR 
*plBitRate
) = 0; 
 395     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getProxySettings( 
 396         /* [in] */ BSTR bstrProtocol
, 
 397         /* [retval][out] */ long __RPC_FAR 
*plProxySetting
) = 0; 
 399     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setProxySettings( 
 400         /* [in] */ BSTR bstrProtocol
, 
 401         /* [in] */ long lProxySetting
) = 0; 
 403     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getProxyName( 
 404         /* [in] */ BSTR bstrProtocol
, 
 405         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrProxyName
) = 0; 
 407     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setProxyName( 
 408         /* [in] */ BSTR bstrProtocol
, 
 409         /* [in] */ BSTR bstrProxyName
) = 0; 
 411     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getProxyPort( 
 412         /* [in] */ BSTR bstrProtocol
, 
 413         /* [retval][out] */ long __RPC_FAR 
*lProxyPort
) = 0; 
 415     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setProxyPort( 
 416         /* [in] */ BSTR bstrProtocol
, 
 417         /* [in] */ long lProxyPort
) = 0; 
 419     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getProxyExceptionList( 
 420         /* [in] */ BSTR bstrProtocol
, 
 421         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrExceptionList
) = 0; 
 423     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setProxyExceptionList( 
 424         /* [in] */ BSTR bstrProtocol
, 
 425         /* [in] */ BSTR pbstrExceptionList
) = 0; 
 427     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
getProxyBypassForLocal( 
 428         /* [in] */ BSTR bstrProtocol
, 
 429         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfBypassForLocal
) = 0; 
 431     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
setProxyBypassForLocal( 
 432         /* [in] */ BSTR bstrProtocol
, 
 433         /* [in] */ VARIANT_BOOL fBypassForLocal
) = 0; 
 435     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_maxBandwidth( 
 436         /* [retval][out] */ long __RPC_FAR 
*lMaxBandwidth
) = 0; 
 438     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_maxBandwidth( 
 439         /* [in] */ long lMaxBandwidth
) = 0; 
 441     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_downloadProgress( 
 442         /* [retval][out] */ long __RPC_FAR 
*plDownloadProgress
) = 0; 
 444     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_encodedFrameRate( 
 445         /* [retval][out] */ long __RPC_FAR 
*plFrameRate
) = 0; 
 447     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_framesSkipped( 
 448         /* [retval][out] */ long __RPC_FAR 
*plFrames
) = 0; 
 452 struct IWMPCore 
: public IDispatch
 
 455     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
close( void) = 0; 
 457     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_URL( 
 458         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrURL
) = 0; 
 460     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_URL( 
 461         /* [in] */ BSTR pbstrURL
) = 0; 
 463     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_openState( 
 464         /* [retval][out] */ WMPOpenState __RPC_FAR 
*pwmpos
) = 0; 
 466     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_playState( 
 467         /* [retval][out] */ WMPPlayState __RPC_FAR 
*pwmpps
) = 0; 
 469     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_controls( 
 470         /* [retval][out] */ IWMPControls __RPC_FAR 
*__RPC_FAR 
*ppControl
) = 0; 
 472     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_settings( 
 473         /* [retval][out] */ IWMPSettings __RPC_FAR 
*__RPC_FAR 
*ppSettings
) = 0; 
 475     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentMedia( 
 476         /* [retval][out] */ IWMPMedia __RPC_FAR 
*__RPC_FAR 
*ppMedia
) = 0; 
 478     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_currentMedia( 
 479         /* [in] */ IUnknown __RPC_FAR 
*ppMedia
) = 0; 
 481     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_mediaCollection( 
 482         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppMediaCollection
) = 0; 
 484     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_playlistCollection( 
 485         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppPlaylistCollection
) = 0; 
 487     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_versionInfo( 
 488         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrVersionInfo
) = 0; 
 490     virtual /* [id] */ HRESULT STDMETHODCALLTYPE 
launchURL( 
 491         /* [in] */ BSTR bstrURL
) = 0; 
 493     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_network( 
 494         /* [retval][out] */ IWMPNetwork __RPC_FAR 
*__RPC_FAR 
*ppQNI
) = 0; 
 496     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_currentPlaylist( 
 497         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppPL
) = 0; 
 499     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_currentPlaylist( 
 500         /* [in] */ IUnknown __RPC_FAR 
*ppPL
) = 0; 
 502     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_cdromCollection( 
 503         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppCdromCollection
) = 0; 
 505     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_closedCaption( 
 506         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppClosedCaption
) = 0; 
 508     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_isOnline( 
 509         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pfOnline
) = 0; 
 511     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_Error( 
 512         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppError
) = 0; 
 514     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_status( 
 515         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrStatus
) = 0; 
 519 struct IWMPCore2 
: public IWMPCore
 
 522     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_dvd( 
 523         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppDVD
) = 0; 
 527 struct IWMPCore3 
: public IWMPCore2
 
 530     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
newPlaylist( 
 531         /* [in] */ BSTR bstrName
, 
 532         /* [in] */ BSTR bstrURL
, 
 533         /* [retval][out] */ IUnknown __RPC_FAR 
*__RPC_FAR 
*ppPlaylist
) = 0; 
 535     virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE 
newMedia( 
 536         /* [in] */ BSTR bstrURL
, 
 537         /* [retval][out] */ IWMPMedia __RPC_FAR 
*__RPC_FAR 
*ppMedia
) = 0; 
 542     MIDL_INTERFACE("6BF52A4F-394A-11D3-B153-00C04F79FAA6") 
 546 IWMPPlayer 
: public IWMPCore
 
 549     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_enabled( 
 550         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnabled
) = 0; 
 552     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_enabled( 
 553         /* [in] */ VARIANT_BOOL pbEnabled
) = 0; 
 555     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_fullScreen( 
 556         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbFullScreen
) = 0; 
 558     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_fullScreen( 
 559         VARIANT_BOOL pbFullScreen
) = 0; 
 561     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_enableContextMenu( 
 562         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnableContextMenu
) = 0; 
 564     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_enableContextMenu( 
 565         VARIANT_BOOL pbEnableContextMenu
) = 0; 
 567     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_uiMode( 
 568         /* [in] */ BSTR pbstrMode
) = 0; 
 570     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_uiMode( 
 571         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrMode
) = 0; 
 574 struct IWMPPlayer2 
: public IWMPCore
 
 577     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_enabled( 
 578         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnabled
) = 0; 
 580     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_enabled( 
 581         /* [in] */ VARIANT_BOOL pbEnabled
) = 0; 
 583     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_fullScreen( 
 584         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbFullScreen
) = 0; 
 586     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_fullScreen( 
 587         VARIANT_BOOL pbFullScreen
) = 0; 
 589     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_enableContextMenu( 
 590         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnableContextMenu
) = 0; 
 592     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_enableContextMenu( 
 593         VARIANT_BOOL pbEnableContextMenu
) = 0; 
 595     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_uiMode( 
 596         /* [in] */ BSTR pbstrMode
) = 0; 
 598     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_uiMode( 
 599         /* [retval][out] */ BSTR __RPC_FAR 
*pbstrMode
) = 0; 
 601     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_stretchToFit( 
 602         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnabled
) = 0; 
 604     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_stretchToFit( 
 605         /* [in] */ VARIANT_BOOL pbEnabled
) = 0; 
 607     virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE 
get_windowlessVideo( 
 608         /* [retval][out] */ VARIANT_BOOL __RPC_FAR 
*pbEnabled
) = 0; 
 610     virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE 
put_windowlessVideo( 
 611         /* [in] */ VARIANT_BOOL pbEnabled
) = 0; 
 615 //--------------------------------------------------------------------------- 
 617 //  wxWMP10MediaBackend 
 619 //--------------------------------------------------------------------------- 
 621 class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend 
: public wxMediaBackendCommonBase
 
 624     wxWMP10MediaBackend(); 
 625     virtual ~wxWMP10MediaBackend(); 
 627     virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
, 
 632                                      const wxValidator
& validator
, 
 633                                      const wxString
& name
); 
 636     virtual bool Pause(); 
 639     virtual bool Load(const wxString
& fileName
); 
 640     virtual bool Load(const wxURI
& location
); 
 641     virtual bool Load(const wxURI
& location
, const wxURI
& proxy
); 
 643     bool DoLoad(const wxString
& location
); 
 646     virtual wxMediaState 
GetState(); 
 648     virtual bool SetPosition(wxLongLong where
); 
 649     virtual wxLongLong 
GetPosition(); 
 650     virtual wxLongLong 
GetDuration(); 
 652     virtual void Move(int x
, int y
, int w
, int h
); 
 653     wxSize 
GetVideoSize() const; 
 655     virtual double GetPlaybackRate(); 
 656     virtual bool SetPlaybackRate(double); 
 658     virtual double GetVolume(); 
 659     virtual bool SetVolume(double); 
 661     virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags
); 
 663     virtual wxLongLong 
GetDownloadProgress(); 
 664     virtual wxLongLong 
GetDownloadTotal(); 
 670         wxActiveXContainer
* m_pAX
; 
 672     IWMPPlayer
* m_pWMPPlayer
;       // Main activex interface 
 673     IWMPSettings
* m_pWMPSettings
;   // Settings such as volume 
 674     IWMPControls
* m_pWMPControls
;   // Control interface (play etc.) 
 675     wxSize m_bestSize
;              // Actual movie size 
 677     bool m_bWasStateChanged
;        // See the "introduction" 
 679     friend class wxWMP10MediaEvtHandler
; 
 680     DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend
) 
 684 class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler 
: public wxEvtHandler
 
 687     wxWMP10MediaEvtHandler(wxWMP10MediaBackend 
*amb
) : 
 690         m_amb
->m_pAX
->Connect(m_amb
->m_pAX
->GetId(), 
 692             wxActiveXEventHandler(wxWMP10MediaEvtHandler::OnActiveX
), 
 697     void OnActiveX(wxActiveXEvent
& event
); 
 700     wxWMP10MediaBackend 
*m_amb
; 
 702     DECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler
) 
 706 //=========================================================================== 
 708 //=========================================================================== 
 710 //--------------------------------------------------------------------------- 
 712 // wxWMP10MediaBackend 
 714 //--------------------------------------------------------------------------- 
 716 IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend
, wxMediaBackend
) 
 718 //--------------------------------------------------------------------------- 
 719 // wxWMP10MediaBackend Constructor 
 720 //--------------------------------------------------------------------------- 
 721 wxWMP10MediaBackend::wxWMP10MediaBackend() 
 731 //--------------------------------------------------------------------------- 
 732 // wxWMP10MediaBackend Destructor 
 733 //--------------------------------------------------------------------------- 
 734 wxWMP10MediaBackend::~wxWMP10MediaBackend() 
 739         m_pAX
->DissociateHandle(); 
 742         m_ctrl
->PopEventHandler(true); 
 748         m_pWMPPlayer
->Release(); 
 749         m_pWMPSettings
->Release(); 
 750         m_pWMPControls
->Release(); 
 754 //--------------------------------------------------------------------------- 
 755 // wxWMP10MediaBackend::CreateControl 
 756 //--------------------------------------------------------------------------- 
 757 bool wxWMP10MediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
, 
 762                                      const wxValidator
& validator
, 
 763                                      const wxString
& name
) 
 766     if( ::CoCreateInstance(CLSID_WMP10
, NULL
, 
 767                                   CLSCTX_INPROC_SERVER
, 
 768                                   IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 ) 
 770         if( ::CoCreateInstance(CLSID_WMP10ALT
, NULL
, 
 771                                   CLSCTX_INPROC_SERVER
, 
 772                                   IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 ) 
 775         if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0) 
 777             m_pWMPPlayer
->Release(); 
 778             wxLogSysError(wxT("Could not obtain settings from WMP10!")); 
 782         if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0) 
 784             m_pWMPSettings
->Release(); 
 785             m_pWMPPlayer
->Release(); 
 786             wxLogSysError(wxT("Could not obtain controls from WMP10!")); 
 794     // By default wxWindow(s) is created with a border - 
 795     // so we need to get rid of those 
 797     // Since we don't have a child window like most other 
 798     // backends, we don't need wxCLIP_CHILDREN 
 800     if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
, 
 801                             (style 
& ~wxBORDER_MASK
) | wxBORDER_NONE
, 
 806     // Now create the ActiveX container along with the media player 
 807     // interface and query them 
 809     m_ctrl 
= wxStaticCast(ctrl
, wxMediaCtrl
); 
 812     m_pAX 
= new wxActiveXContainer(ctrl
, IID_IWMPPlayer
, m_pWMPPlayer
); 
 814     // Connect for events 
 815     m_ctrl
->PushEventHandler(new wxWMP10MediaEvtHandler(this)); 
 817     _Module
.Init(NULL
, ::GetModuleHandle(NULL
)); 
 819     CComPtr
<IAxWinHostWindow
>  spHost
; 
 823     ::GetClientRect((HWND
)ctrl
->GetHandle(), &rcClient
); 
 824     m_wndView
.Create((HWND
)ctrl
->GetHandle(), rcClient
, NULL
, WS_CHILD 
| WS_VISIBLE 
| WS_CLIPCHILDREN
, WS_EX_CLIENTEDGE
); 
 825     hr 
= m_wndView
.QueryHost(&spHost
); 
 826     hr 
= spHost
->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView
, 0); 
 827     hr 
= m_wndView
.QueryControl(&m_pWMPPlayer
); 
 829     if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0) 
 831         m_pWMPPlayer
->Release(); 
 832         wxLogSysError(wxT("Could not obtain settings from WMP10!")); 
 836     if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0) 
 838         m_pWMPSettings
->Release(); 
 839         m_pWMPPlayer
->Release(); 
 840         wxLogSysError(wxT("Could not obtain controls from WMP10!")); 
 846     //  Here we set up wx-specific stuff for the default 
 847     //  settings wxMediaCtrl says it will stay to 
 850     IWMPPlayer2
* pWMPPlayer2
; // Only 2 has windowless video and stretchtofit 
 851     if(m_pWMPPlayer
->QueryInterface(IID_IWMPPlayer2
, (void**)&pWMPPlayer2
) == 0) 
 853         // We don't check errors here as these arn't particularily important 
 854         // and may not be implemented (i.e. stretchToFit on CE) 
 855         pWMPPlayer2
->put_windowlessVideo(VARIANT_TRUE
); 
 856         pWMPPlayer2
->put_stretchToFit(VARIANT_TRUE
); 
 857         pWMPPlayer2
->Release(); 
 860     // by default true (see the "introduction") 
 861     m_pWMPSettings
->put_autoStart(VARIANT_TRUE
); 
 862     // by default enabled 
 863     wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE
); 
 864     // by default with AM only 0.5 
 865     wxWMP10MediaBackend::SetVolume(1.0); 
 867     // don't erase the background of our control window so that resizing is a 
 869     m_ctrl
->SetBackgroundStyle(wxBG_STYLE_CUSTOM
); 
 875 //--------------------------------------------------------------------------- 
 876 // wxWMP10MediaBackend::Load (file version) 
 877 //--------------------------------------------------------------------------- 
 878 bool wxWMP10MediaBackend::Load(const wxString
& fileName
) 
 880     return DoLoad(fileName
); 
 883 //--------------------------------------------------------------------------- 
 884 // wxWMP10MediaBackend::Load (URL Version) 
 885 //--------------------------------------------------------------------------- 
 886 bool wxWMP10MediaBackend::Load(const wxURI
& location
) 
 888     return DoLoad(location
.BuildURI()); 
 891 //--------------------------------------------------------------------------- 
 892 // wxWMP10MediaBackend::Load (URL Version with Proxy) 
 893 //--------------------------------------------------------------------------- 
 894 bool wxWMP10MediaBackend::Load(const wxURI
& location
, 
 899     IWMPNetwork
* pWMPNetwork
; 
 900     if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 ) 
 903         if( pWMPNetwork
->getProxySettings( 
 904                     wxBasicString(location
.GetScheme()).Get(), &lOldSetting
 
 907             pWMPNetwork
->setProxySettings( 
 908                     wxBasicString(location
.GetScheme()).Get(), // protocol 
 909                                 2) == 0) // 2 == manually specify 
 911             BSTR bsOldName 
= NULL
; 
 914             pWMPNetwork
->getProxyName( 
 915                         wxBasicString(location
.GetScheme()).Get(), 
 917             pWMPNetwork
->getProxyPort( 
 918                         wxBasicString(location
.GetScheme()).Get(), 
 923             if(proxy
.IsReference()) 
 925                 server 
= proxy
.GetScheme(); 
 926                 lPort 
= wxAtoi(proxy
.GetPath()); 
 930                 server 
= proxy
.GetServer(); 
 931                 lPort 
= wxAtoi(proxy
.GetPort()); 
 934             if( pWMPNetwork
->setProxyName( 
 935                         wxBasicString(location
.GetScheme()).Get(), // proto 
 936                         wxBasicString(server
).Get() ) == 0  && 
 938                 pWMPNetwork
->setProxyPort( 
 939                         wxBasicString(location
.GetScheme()).Get(), // proto 
 944                 bOK 
= DoLoad(location
.BuildURI()); 
 946                 pWMPNetwork
->setProxySettings( 
 947                     wxBasicString(location
.GetScheme()).Get(), // protocol 
 950                     pWMPNetwork
->setProxyName( 
 951                         wxBasicString(location
.GetScheme()).Get(), // protocol 
 955                     pWMPNetwork
->setProxyPort( 
 956                         wxBasicString(location
.GetScheme()).Get(), // protocol 
 959                 pWMPNetwork
->Release(); 
 962                 pWMPNetwork
->Release(); 
 966             pWMPNetwork
->Release(); 
 973 //--------------------------------------------------------------------------- 
 974 // wxWMP10MediaBackend::DoLoad 
 976 // Called by all functions - this actually renders 
 977 // the file and sets up the filter graph 
 978 //--------------------------------------------------------------------------- 
 979 bool wxWMP10MediaBackend::DoLoad(const wxString
& location
) 
 983 #if 0 // See the "introduction" - this is the duration hack 
 984     // ------------------ BLATENT HACK ALERT ------------------------- 
 985     // Normally we can only get the duration of things already in an 
 986     // existing playlist or playing - however this clever "workaround" 
 987     // enables us to get the duration even when stopped :) 
 988     // http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx 
 990     IWMPCore3
* pWMPCore3
; 
 992     if(m_pWMPPlayer
->QueryInterface(IID_IWMPCore3
, (void**) &pWMPCore3
) == 0) 
 994         IWMPMedia
* pWMPMedia
; 
 996         if( (hr 
= pWMPCore3
->newMedia(wxBasicString(location
).Get(), 
 999             // this (get_duration) will actually FAIL, but it will work. 
1000             pWMPMedia
->get_duration(&outDuration
); 
1001             pWMPCore3
->put_currentMedia(pWMPMedia
); 
1002             pWMPMedia
->Release(); 
1005         pWMPCore3
->Release(); 
1010         // just load it the "normal" way 
1011         hr 
= m_pWMPPlayer
->put_URL( wxBasicString(location
).Get() ); 
1023 //--------------------------------------------------------------------------- 
1024 // wxWMP10MediaBackend::FinishLoad 
1026 // Called when our media is about to play (a.k.a. wmposMediaOpen) 
1027 //--------------------------------------------------------------------------- 
1028 void wxWMP10MediaBackend::FinishLoad() 
1030     // Get the original video size 
1031     // THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY 
1032     // See the "introduction" - also get_currentMedia will return 
1033     // "1" which is a VALID HRESULT value 
1034     // and a NULL pWMPMedia if the media isn't the "current" one 
1035     // which is rather unintuitive in the sense that it uses it 
1036     // (i.e. basically not currently playing)... 
1037     IWMPMedia
* pWMPMedia
; 
1038     if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0) 
1040         pWMPMedia
->get_imageSourceWidth((long*)&m_bestSize
.x
); 
1041         pWMPMedia
->get_imageSourceHeight((long*)&m_bestSize
.y
); 
1042         pWMPMedia
->Release(); 
1046         wxLogDebug(wxT("Could not get media")); 
1049     NotifyMovieLoaded(); 
1052 //--------------------------------------------------------------------------- 
1053 // wxWMP10MediaBackend::ShowPlayerControls 
1054 //--------------------------------------------------------------------------- 
1055 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags
) 
1059         m_pWMPPlayer
->put_enabled(VARIANT_FALSE
); 
1060         m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("none")).Get()); 
1064         // TODO: use "custom"? (note that CE only supports none/full) 
1065         m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("full")).Get()); 
1066         m_pWMPPlayer
->put_enabled(VARIANT_TRUE
); 
1072 //--------------------------------------------------------------------------- 
1073 // wxWMP10MediaBackend::Play 
1075 // Plays the stream.  If it is non-seekable, it will restart it (implicit). 
1077 // TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here 
1078 // but do we need to? 
1079 //--------------------------------------------------------------------------- 
1080 bool wxWMP10MediaBackend::Play() 
1082     // Actually try to play the movie (will fail if not loaded completely) 
1083     HRESULT hr 
= m_pWMPControls
->play(); 
1086        m_bWasStateChanged 
= true; 
1093 //--------------------------------------------------------------------------- 
1094 // wxWMP10MediaBackend::Pause 
1096 // Pauses the stream. 
1097 //--------------------------------------------------------------------------- 
1098 bool wxWMP10MediaBackend::Pause() 
1100     HRESULT hr 
= m_pWMPControls
->pause(); 
1103         m_bWasStateChanged 
= true; 
1110 //--------------------------------------------------------------------------- 
1111 // wxWMP10MediaBackend::Stop 
1113 // Stops the stream. 
1114 //--------------------------------------------------------------------------- 
1115 bool wxWMP10MediaBackend::Stop() 
1117     HRESULT hr 
= m_pWMPControls
->stop(); 
1120         // Seek to beginning 
1121         wxWMP10MediaBackend::SetPosition(0); 
1122         m_bWasStateChanged 
= true; 
1129 //--------------------------------------------------------------------------- 
1130 // wxWMP10MediaBackend::SetPosition 
1132 // WMP10 position values are a double in seconds - we just translate 
1134 //--------------------------------------------------------------------------- 
1135 bool wxWMP10MediaBackend::SetPosition(wxLongLong where
) 
1137     HRESULT hr 
= m_pWMPControls
->put_currentPosition( 
1138                         ((LONGLONG
)where
.GetValue()) / 1000.0 
1149 //--------------------------------------------------------------------------- 
1150 // wxWMP10MediaBackend::GetPosition 
1152 // WMP10 position values are a double in seconds - we just translate 
1154 //--------------------------------------------------------------------------- 
1155 wxLongLong 
wxWMP10MediaBackend::GetPosition() 
1158     HRESULT hr 
= m_pWMPControls
->get_currentPosition(&outCur
); 
1165     // h,m,s,milli - outCur is in 1 second (double) 
1173 //--------------------------------------------------------------------------- 
1174 // wxWMP10MediaBackend::GetVolume 
1177 //--------------------------------------------------------------------------- 
1178 double wxWMP10MediaBackend::GetVolume() 
1181     HRESULT hr 
= m_pWMPSettings
->get_volume(&lVolume
); 
1188     return (double)lVolume 
/ 100.0; 
1191 //--------------------------------------------------------------------------- 
1192 // wxWMP10MediaBackend::SetVolume 
1195 //--------------------------------------------------------------------------- 
1196 bool wxWMP10MediaBackend::SetVolume(double dVolume
) 
1198     HRESULT hr 
= m_pWMPSettings
->put_volume( (long) (dVolume 
* 100.0) ); 
1207 //--------------------------------------------------------------------------- 
1208 // wxWMP10MediaBackend::GetDuration 
1210 // Obtains the duration of the media. 
1212 // See the "introduction" 
1214 // The good news is that this doesn't appear to have the XING header 
1215 // parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has 
1216 //--------------------------------------------------------------------------- 
1217 wxLongLong 
wxWMP10MediaBackend::GetDuration() 
1219     double outDuration 
= 0.0; 
1221     IWMPMedia
* pWMPMedia
; 
1222     if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0) 
1224         if(pWMPMedia
->get_duration(&outDuration
) != 0) 
1226             wxLogDebug(wxT("get_duration failed")); 
1228         pWMPMedia
->Release(); 
1232     // h,m,s,milli - outDuration is in 1 second (double) 
1233     outDuration 
*= 1000; 
1235     ll
.Assign(outDuration
); 
1240 //--------------------------------------------------------------------------- 
1241 // wxWMP10MediaBackend::GetState 
1243 // Returns the current state 
1244 //--------------------------------------------------------------------------- 
1245 wxMediaState 
wxWMP10MediaBackend::GetState() 
1247     WMPPlayState nState
; 
1248     HRESULT hr 
= m_pWMPPlayer
->get_playState(&nState
); 
1252         return wxMEDIASTATE_STOPPED
; 
1258         return wxMEDIASTATE_PAUSED
; 
1260         return wxMEDIASTATE_PLAYING
; 
1262         return wxMEDIASTATE_STOPPED
; 
1266 //--------------------------------------------------------------------------- 
1267 // wxWMP10MediaBackend::GetPlaybackRate 
1269 // Just get the rate from WMP10 
1270 //--------------------------------------------------------------------------- 
1271 double wxWMP10MediaBackend::GetPlaybackRate() 
1274     HRESULT hr 
= m_pWMPSettings
->get_rate(&dRate
); 
1283 //--------------------------------------------------------------------------- 
1284 // wxWMP10MediaBackend::SetPlaybackRate 
1286 // Sets the playback rate of the media - DirectShow is pretty good 
1287 // about this, actually 
1288 //--------------------------------------------------------------------------- 
1289 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate
) 
1291     HRESULT hr 
= m_pWMPSettings
->put_rate(dRate
); 
1301 //--------------------------------------------------------------------------- 
1302 // wxWMP10MediaBackend::GetVideoSize 
1304 // Obtains the cached original video size 
1305 //--------------------------------------------------------------------------- 
1306 wxSize 
wxWMP10MediaBackend::GetVideoSize() const 
1311 //--------------------------------------------------------------------------- 
1312 // wxWMP10MediaBackend::Move 
1314 // We take care of this in our redrawing 
1315 //--------------------------------------------------------------------------- 
1316 void wxWMP10MediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
), 
1320                             int WXUNUSED(w
), int WXUNUSED(h
) 
1325     m_wndView
.MoveWindow(0,0,w
,h
); 
1329 //--------------------------------------------------------------------------- 
1330 // wxWMP10MediaBackend::GetDownloadProgress() 
1331 //--------------------------------------------------------------------------- 
1332 wxLongLong 
wxWMP10MediaBackend::GetDownloadProgress() 
1334     IWMPNetwork
* pWMPNetwork
; 
1335     if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 ) 
1338         if(pWMPNetwork
->get_downloadProgress(&lPercentProg
) == 0) 
1340             pWMPNetwork
->Release(); 
1341             return (GetDownloadTotal() * lPercentProg
) / 100; 
1343         pWMPNetwork
->Release(); 
1348 //--------------------------------------------------------------------------- 
1349 // wxWMP10MediaBackend::GetDownloadTotal() 
1350 //--------------------------------------------------------------------------- 
1351 wxLongLong 
wxWMP10MediaBackend::GetDownloadTotal() 
1353     IWMPMedia
* pWMPMedia
; 
1354     if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0) 
1357         pWMPMedia
->getItemInfo(wxBasicString(wxT("FileSize")).Get(), 
1360         wxString sFileSize 
= wxConvertStringFromOle(bsOut
); 
1362         sFileSize
.ToLong(&lFS
); 
1363         pWMPMedia
->Release(); 
1371 //--------------------------------------------------------------------------- 
1372 // wxWMP10MediaBackend::OnActiveX 
1374 // Handle events sent from our activex control (_WMPOCXEvents actually). 
1376 // The weird numbers in the switch statement here are "dispatch ids" 
1377 // (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl 
1379 //--------------------------------------------------------------------------- 
1381 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent
& event
) 
1383     switch(event
.GetDispatchId()) 
1385     case 0x000013ed: // playstatechange 
1386         if(event
.ParamCount() >= 1) 
1388             switch (event
[0].GetInteger()) 
1390             case wmppsMediaEnded
: // media ended 
1391                 if ( m_amb
->SendStopEvent() ) 
1393                     // NB: If we do Stop() or similar here the media 
1394                     // actually starts over and plays a bit before 
1395                     // stopping. It stops by default, however, so 
1396                     // there is no real need to do anything here... 
1398                     // send the event to our child 
1399                     m_amb
->QueueFinishEvent(); 
1403             case wmppsStopped
: // stopping 
1404                 m_amb
->QueueStopEvent(); 
1406             case wmppsPaused
: // pause 
1407                 m_amb
->QueuePauseEvent(); 
1409             case wmppsPlaying
: // play 
1410                 m_amb
->QueuePlayEvent(); 
1420     case 0x00001389: // openstatechange 
1421         if(event
.ParamCount() >= 1) 
1423             int nState 
= event
[0].GetInteger(); 
1424             if(nState 
== wmposMediaOpen
) 
1426                 // See the "introduction" 
1427                 m_amb
->m_bWasStateChanged 
= false; 
1428                 m_amb
->FinishLoad(); 
1429                 if(!m_amb
->m_bWasStateChanged
) 
1437     case 0x0000196e: // mousedown 
1438         m_amb
->m_ctrl
->SetFocus(); 
1448 // in source file that contains stuff you don't directly use 
1449 #include "wx/html/forcelnk.h" 
1450 FORCE_LINK_ME(wxmediabackend_wmp10
) 
1452 #if 0 // Windows Media Player Mobile 9 hacks 
1454 //------------------WMP Mobile 9 hacks----------------------------------- 
1455 // It was mentioned in the introduction that while there was no official 
1456 // programming interface on WMP mobile 9 
1457 // (SmartPhone/Pocket PC 2003 emulator etc.) 
1458 // there were some windows message hacks that are able to get 
1459 // you playing a file through WMP. 
1461 // Here are those hacks. They do indeed "work" as expected - just call 
1462 // SendMessage with one of those myterious values layed out in 
1463 // Peter Foot's Friday, May 21, 2004 Blog Post on the issue. 
1464 // (He says they are in a registery section entitled "Pendant Bus") 
1466 // How do you play a certain file? Simply calling "start [file]" or 
1467 // wxWinCEExecute([file]) should do the trick 
1469 bool wxWinCEExecute(const wxString
& path
, int nShowStyle 
= SW_SHOWNORMAL
) 
1471     WinStruct
<SHELLEXECUTEINFO
> sei
; 
1472     sei
.lpFile 
= path
.c_str(); 
1473     sei
.lpVerb 
= _T("open"); 
1474     sei
.nShow 
= nShowStyle
; 
1476     ::ShellExecuteEx(&sei
); 
1478     return ((int) sei
.hInstApp
) > 32; 
1481 bool MyApp::OnInit() 
1483     HWND hwnd 
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media")); 
1486         if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE
) ) 
1488             hwnd 
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media")); 
1495         ::SetWindowPos(hwnd
, HWND_BOTTOM
, 0, 0, 0, 0, 
1496                        SWP_NOMOVE
|SWP_NOSIZE
|SWP_HIDEWINDOW
); 
1499         // Prev Track   == 32971 
1500         // Next Track   == 32972 
1504         // Vol Down     == 32976 
1506         ::SendMessage(hwnd
, 32978, NULL
, 0); 
1510 #endif // WMP mobile 9 hacks 
1512 #endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX