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 //---------------------------------------------------------------------------
55 //---------------------------------------------------------------------------
56 #include "wx/mediactrl.h"
58 //---------------------------------------------------------------------------
60 //---------------------------------------------------------------------------
63 //---------------------------------------------------------------------------
65 //---------------------------------------------------------------------------
66 #include "wx/log.h" // wxLogDebug
67 #include "wx/msw/private.h" // user info and wndproc setting/getting
68 #include "wx/msw/ole/activex.h" // wxActiveXContainer - COM-specific stuff
70 //---------------------------------------------------------------------------
71 // ATL Includes - define WXTEST_ATL if you
72 // want to use CAxWindow instead of wxActiveXContainer (note that
73 // this is mainly for testing as the activex events arn't implemented here)
74 //---------------------------------------------------------------------------
82 #define min(x,y) (x < y ? x : y)
88 //---------------------------------------------------------------------------
90 //---------------------------------------------------------------------------
92 // disable "cast truncates constant value" for VARIANT_BOOL values
93 // passed as parameters in VC6
95 #pragma warning (disable:4310)
98 // error logger for HRESULTS (nothing really now)
101 //---------------------------------------------------------------------------
102 // Various definitions dumped from wmp.IDL
103 //---------------------------------------------------------------------------
105 // CLSID_WMP10ALT is on CE and in some MS docs - on others it is the plain ver
106 const CLSID CLSID_WMP10
= {0x6BF52A50,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
107 const CLSID CLSID_WMP10ALT
= {0x6BF52A52,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
109 const IID IID_IWMPSettings
= {0x9104D1AB,0x80C9,0x4FED,{0xAB,0xF0,0x2E,0x64,0x17,0xA6,0xDF,0x14}};
110 const IID IID_IWMPCore
= {0xD84CCA99,0xCCE2,0x11D2,{0x9E,0xCC,0x00,0x00,0xF8,0x08,0x59,0x81}};
112 const IID IID_IWMPPlayer
= {0x6BF52A4F,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
115 const IID IID_IWMPMedia
= {0x94D55E95,0x3FAC,0x11D3,{0xB1,0x55,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
116 const IID IID_IWMPControls
= {0x74C09E02,0xF828,0x11D2,{0xA7,0x4B,0x00,0xA0,0xC9,0x05,0xF3,0x6E}};
117 const IID IID_IWMPPlayer2
= {0x0E6B01D1,0xD407,0x4C85,{0xBF,0x5F,0x1C,0x01,0xF6,0x15,0x02,0x80}};
118 const IID IID_IWMPCore2
= {0xBC17E5B7,0x7561,0x4C18,{0xBB,0x90,0x17,0xD4,0x85,0x77,0x56,0x59}};
119 const IID IID_IWMPCore3
= {0x7587C667,0x628F,0x499F,{0x88,0xE7,0x6A,0x6F,0x4E,0x88,0x84,0x64}};
120 const IID IID_IWMPNetwork
= {0xEC21B779,0xEDEF,0x462D,{0xBB,0xA4,0xAD,0x9D,0xDE,0x2B,0x29,0xA7}};
125 wmposPlaylistChanging
= 1,
126 wmposPlaylistLocating
= 2,
127 wmposPlaylistConnecting
= 3,
128 wmposPlaylistLoading
= 4,
129 wmposPlaylistOpening
= 5,
130 wmposPlaylistOpenNoMedia
= 6,
131 wmposPlaylistChanged
= 7,
132 wmposMediaChanging
= 8,
133 wmposMediaLocating
= 9,
134 wmposMediaConnecting
= 10,
135 wmposMediaLoading
= 11,
136 wmposMediaOpening
= 12,
138 wmposBeginCodecAcquisition
= 14,
139 wmposEndCodecAcquisition
= 15,
140 wmposBeginLicenseAcquisition
= 16,
141 wmposEndLicenseAcquisition
= 17,
142 wmposBeginIndividualization
= 18,
143 wmposEndIndividualization
= 19,
144 wmposMediaWaiting
= 20,
145 wmposOpeningUnknownURL
= 21
154 wmppsScanForward
= 4,
155 wmppsScanReverse
= 5,
159 wmppsTransitioning
= 9,
161 wmppsReconnecting
= 11,
166 struct IWMPMedia
: public IDispatch
169 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isIdentical(
170 /* [in] */ IWMPMedia __RPC_FAR
*pIWMPMedia
,
171 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvbool
) = 0;
173 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_sourceURL(
174 /* [retval][out] */ BSTR __RPC_FAR
*pbstrSourceURL
) = 0;
176 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_name(
177 /* [retval][out] */ BSTR __RPC_FAR
*pbstrName
) = 0;
179 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_name(
180 /* [in] */ BSTR pbstrName
) = 0;
182 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_imageSourceWidth(
183 /* [retval][out] */ long __RPC_FAR
*pWidth
) = 0;
185 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_imageSourceHeight(
186 /* [retval][out] */ long __RPC_FAR
*pHeight
) = 0;
188 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_markerCount(
189 /* [retval][out] */ long __RPC_FAR
*pMarkerCount
) = 0;
191 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMarkerTime(
192 /* [in] */ long MarkerNum
,
193 /* [retval][out] */ double __RPC_FAR
*pMarkerTime
) = 0;
195 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMarkerName(
196 /* [in] */ long MarkerNum
,
197 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMarkerName
) = 0;
199 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_duration(
200 /* [retval][out] */ double __RPC_FAR
*pDuration
) = 0;
202 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_durationString(
203 /* [retval][out] */ BSTR __RPC_FAR
*pbstrDuration
) = 0;
205 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_attributeCount(
206 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
208 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getAttributeName(
209 /* [in] */ long lIndex
,
210 /* [retval][out] */ BSTR __RPC_FAR
*pbstrItemName
) = 0;
212 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getItemInfo(
213 /* [in] */ BSTR bstrItemName
,
214 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVal
) = 0;
216 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setItemInfo(
217 /* [in] */ BSTR bstrItemName
,
218 /* [in] */ BSTR bstrVal
) = 0;
220 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getItemInfoByAtom(
221 /* [in] */ long lAtom
,
222 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVal
) = 0;
224 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
isMemberOf(
225 /* [in] */ IUnknown __RPC_FAR
*pPlaylist
,
226 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfIsMemberOf
) = 0;
228 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
isReadOnlyItem(
229 /* [in] */ BSTR bstrItemName
,
230 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfIsReadOnly
) = 0;
234 struct IWMPControls
: public IDispatch
237 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isAvailable(
238 /* [in] */ BSTR bstrItem
,
239 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pIsAvailable
) = 0;
241 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
play( void) = 0;
243 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
stop( void) = 0;
245 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
pause( void) = 0;
247 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
fastForward( void) = 0;
249 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
fastReverse( void) = 0;
251 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPosition(
252 /* [retval][out] */ double __RPC_FAR
*pdCurrentPosition
) = 0;
254 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentPosition(
255 /* [in] */ double pdCurrentPosition
) = 0;
257 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPositionString(
258 /* [retval][out] */ BSTR __RPC_FAR
*pbstrCurrentPosition
) = 0;
260 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
next( void) = 0;
262 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
previous( void) = 0;
264 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentItem(
265 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppIWMPMedia
) = 0;
267 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentItem(
268 /* [in] */ IWMPMedia __RPC_FAR
*ppIWMPMedia
) = 0;
270 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentMarker(
271 /* [retval][out] */ long __RPC_FAR
*plMarker
) = 0;
273 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentMarker(
274 /* [in] */ long plMarker
) = 0;
276 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
playItem(
277 /* [in] */ IWMPMedia __RPC_FAR
*pIWMPMedia
) = 0;
282 struct IWMPSettings
: public IDispatch
285 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isAvailable(
286 /* [in] */ BSTR bstrItem
,
287 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pIsAvailable
) = 0;
289 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_autoStart(
290 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfAutoStart
) = 0;
292 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_autoStart(
293 /* [in] */ VARIANT_BOOL pfAutoStart
) = 0;
295 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_baseURL(
296 /* [retval][out] */ BSTR __RPC_FAR
*pbstrBaseURL
) = 0;
298 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_baseURL(
299 /* [in] */ BSTR pbstrBaseURL
) = 0;
301 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_defaultFrame(
302 /* [retval][out] */ BSTR __RPC_FAR
*pbstrDefaultFrame
) = 0;
304 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_defaultFrame(
305 /* [in] */ BSTR pbstrDefaultFrame
) = 0;
307 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_invokeURLs(
308 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfInvokeURLs
) = 0;
310 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_invokeURLs(
311 /* [in] */ VARIANT_BOOL pfInvokeURLs
) = 0;
313 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_mute(
314 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfMute
) = 0;
316 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_mute(
317 /* [in] */ VARIANT_BOOL pfMute
) = 0;
319 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playCount(
320 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
322 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_playCount(
323 /* [in] */ long plCount
) = 0;
325 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_rate(
326 /* [retval][out] */ double __RPC_FAR
*pdRate
) = 0;
328 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_rate(
329 /* [in] */ double pdRate
) = 0;
331 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_balance(
332 /* [retval][out] */ long __RPC_FAR
*plBalance
) = 0;
334 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_balance(
335 /* [in] */ long plBalance
) = 0;
337 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_volume(
338 /* [retval][out] */ long __RPC_FAR
*plVolume
) = 0;
340 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_volume(
341 /* [in] */ long plVolume
) = 0;
343 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMode(
344 /* [in] */ BSTR bstrMode
,
345 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfMode
) = 0;
347 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setMode(
348 /* [in] */ BSTR bstrMode
,
349 /* [in] */ VARIANT_BOOL varfMode
) = 0;
351 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableErrorDialogs(
352 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfEnableErrorDialogs
) = 0;
354 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableErrorDialogs(
355 /* [in] */ VARIANT_BOOL pfEnableErrorDialogs
) = 0;
359 struct IWMPNetwork
: public IDispatch
362 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bandWidth(
363 /* [retval][out] */ long __RPC_FAR
*plBandwidth
) = 0;
365 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_recoveredPackets(
366 /* [retval][out] */ long __RPC_FAR
*plRecoveredPackets
) = 0;
368 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_sourceProtocol(
369 /* [retval][out] */ BSTR __RPC_FAR
*pbstrSourceProtocol
) = 0;
371 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_receivedPackets(
372 /* [retval][out] */ long __RPC_FAR
*plReceivedPackets
) = 0;
374 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_lostPackets(
375 /* [retval][out] */ long __RPC_FAR
*plLostPackets
) = 0;
377 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_receptionQuality(
378 /* [retval][out] */ long __RPC_FAR
*plReceptionQuality
) = 0;
380 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingCount(
381 /* [retval][out] */ long __RPC_FAR
*plBufferingCount
) = 0;
383 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingProgress(
384 /* [retval][out] */ long __RPC_FAR
*plBufferingProgress
) = 0;
386 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingTime(
387 /* [retval][out] */ long __RPC_FAR
*plBufferingTime
) = 0;
389 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_bufferingTime(
390 /* [in] */ long plBufferingTime
) = 0;
392 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_frameRate(
393 /* [retval][out] */ long __RPC_FAR
*plFrameRate
) = 0;
395 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_maxBitRate(
396 /* [retval][out] */ long __RPC_FAR
*plBitRate
) = 0;
398 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bitRate(
399 /* [retval][out] */ long __RPC_FAR
*plBitRate
) = 0;
401 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxySettings(
402 /* [in] */ BSTR bstrProtocol
,
403 /* [retval][out] */ long __RPC_FAR
*plProxySetting
) = 0;
405 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxySettings(
406 /* [in] */ BSTR bstrProtocol
,
407 /* [in] */ long lProxySetting
) = 0;
409 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyName(
410 /* [in] */ BSTR bstrProtocol
,
411 /* [retval][out] */ BSTR __RPC_FAR
*pbstrProxyName
) = 0;
413 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyName(
414 /* [in] */ BSTR bstrProtocol
,
415 /* [in] */ BSTR bstrProxyName
) = 0;
417 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyPort(
418 /* [in] */ BSTR bstrProtocol
,
419 /* [retval][out] */ long __RPC_FAR
*lProxyPort
) = 0;
421 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyPort(
422 /* [in] */ BSTR bstrProtocol
,
423 /* [in] */ long lProxyPort
) = 0;
425 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyExceptionList(
426 /* [in] */ BSTR bstrProtocol
,
427 /* [retval][out] */ BSTR __RPC_FAR
*pbstrExceptionList
) = 0;
429 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyExceptionList(
430 /* [in] */ BSTR bstrProtocol
,
431 /* [in] */ BSTR pbstrExceptionList
) = 0;
433 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyBypassForLocal(
434 /* [in] */ BSTR bstrProtocol
,
435 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfBypassForLocal
) = 0;
437 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyBypassForLocal(
438 /* [in] */ BSTR bstrProtocol
,
439 /* [in] */ VARIANT_BOOL fBypassForLocal
) = 0;
441 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_maxBandwidth(
442 /* [retval][out] */ long __RPC_FAR
*lMaxBandwidth
) = 0;
444 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_maxBandwidth(
445 /* [in] */ long lMaxBandwidth
) = 0;
447 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_downloadProgress(
448 /* [retval][out] */ long __RPC_FAR
*plDownloadProgress
) = 0;
450 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_encodedFrameRate(
451 /* [retval][out] */ long __RPC_FAR
*plFrameRate
) = 0;
453 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_framesSkipped(
454 /* [retval][out] */ long __RPC_FAR
*plFrames
) = 0;
458 struct IWMPCore
: public IDispatch
461 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
close( void) = 0;
463 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_URL(
464 /* [retval][out] */ BSTR __RPC_FAR
*pbstrURL
) = 0;
466 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_URL(
467 /* [in] */ BSTR pbstrURL
) = 0;
469 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_openState(
470 /* [retval][out] */ WMPOpenState __RPC_FAR
*pwmpos
) = 0;
472 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playState(
473 /* [retval][out] */ WMPPlayState __RPC_FAR
*pwmpps
) = 0;
475 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_controls(
476 /* [retval][out] */ IWMPControls __RPC_FAR
*__RPC_FAR
*ppControl
) = 0;
478 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_settings(
479 /* [retval][out] */ IWMPSettings __RPC_FAR
*__RPC_FAR
*ppSettings
) = 0;
481 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentMedia(
482 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppMedia
) = 0;
484 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentMedia(
485 /* [in] */ IUnknown __RPC_FAR
*ppMedia
) = 0;
487 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_mediaCollection(
488 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppMediaCollection
) = 0;
490 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playlistCollection(
491 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPlaylistCollection
) = 0;
493 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_versionInfo(
494 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVersionInfo
) = 0;
496 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
launchURL(
497 /* [in] */ BSTR bstrURL
) = 0;
499 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_network(
500 /* [retval][out] */ IWMPNetwork __RPC_FAR
*__RPC_FAR
*ppQNI
) = 0;
502 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPlaylist(
503 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPL
) = 0;
505 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentPlaylist(
506 /* [in] */ IUnknown __RPC_FAR
*ppPL
) = 0;
508 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_cdromCollection(
509 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppCdromCollection
) = 0;
511 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_closedCaption(
512 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppClosedCaption
) = 0;
514 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isOnline(
515 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfOnline
) = 0;
517 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_Error(
518 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppError
) = 0;
520 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_status(
521 /* [retval][out] */ BSTR __RPC_FAR
*pbstrStatus
) = 0;
525 struct IWMPCore2
: public IWMPCore
528 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_dvd(
529 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppDVD
) = 0;
533 struct IWMPCore3
: public IWMPCore2
536 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
newPlaylist(
537 /* [in] */ BSTR bstrName
,
538 /* [in] */ BSTR bstrURL
,
539 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPlaylist
) = 0;
541 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
newMedia(
542 /* [in] */ BSTR bstrURL
,
543 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppMedia
) = 0;
548 MIDL_INTERFACE("6BF52A4F-394A-11D3-B153-00C04F79FAA6")
552 IWMPPlayer
: public IWMPCore
555 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enabled(
556 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
558 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enabled(
559 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
561 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_fullScreen(
562 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbFullScreen
) = 0;
564 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_fullScreen(
565 VARIANT_BOOL pbFullScreen
) = 0;
567 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableContextMenu(
568 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnableContextMenu
) = 0;
570 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableContextMenu(
571 VARIANT_BOOL pbEnableContextMenu
) = 0;
573 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_uiMode(
574 /* [in] */ BSTR pbstrMode
) = 0;
576 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_uiMode(
577 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMode
) = 0;
580 struct IWMPPlayer2
: public IWMPCore
583 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enabled(
584 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
586 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enabled(
587 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
589 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_fullScreen(
590 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbFullScreen
) = 0;
592 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_fullScreen(
593 VARIANT_BOOL pbFullScreen
) = 0;
595 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableContextMenu(
596 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnableContextMenu
) = 0;
598 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableContextMenu(
599 VARIANT_BOOL pbEnableContextMenu
) = 0;
601 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_uiMode(
602 /* [in] */ BSTR pbstrMode
) = 0;
604 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_uiMode(
605 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMode
) = 0;
607 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_stretchToFit(
608 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
610 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_stretchToFit(
611 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
613 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_windowlessVideo(
614 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
616 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_windowlessVideo(
617 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
621 //---------------------------------------------------------------------------
623 // wxWMP10MediaBackend
625 //---------------------------------------------------------------------------
627 class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend
: public wxMediaBackendCommonBase
630 wxWMP10MediaBackend();
631 virtual ~wxWMP10MediaBackend();
633 virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
638 const wxValidator
& validator
,
639 const wxString
& name
);
642 virtual bool Pause();
645 virtual bool Load(const wxString
& fileName
);
646 virtual bool Load(const wxURI
& location
);
647 virtual bool Load(const wxURI
& location
, const wxURI
& proxy
);
649 bool DoLoad(const wxString
& location
);
652 virtual wxMediaState
GetState();
654 virtual bool SetPosition(wxLongLong where
);
655 virtual wxLongLong
GetPosition();
656 virtual wxLongLong
GetDuration();
658 virtual void Move(int x
, int y
, int w
, int h
);
659 wxSize
GetVideoSize() const;
661 virtual double GetPlaybackRate();
662 virtual bool SetPlaybackRate(double);
664 virtual double GetVolume();
665 virtual bool SetVolume(double);
667 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags
);
669 virtual wxLongLong
GetDownloadProgress();
670 virtual wxLongLong
GetDownloadTotal();
676 wxActiveXContainer
* m_pAX
;
678 IWMPPlayer
* m_pWMPPlayer
; // Main activex interface
679 IWMPSettings
* m_pWMPSettings
; // Settings such as volume
680 IWMPControls
* m_pWMPControls
; // Control interface (play etc.)
681 wxSize m_bestSize
; // Actual movie size
683 bool m_bWasStateChanged
; // See the "introduction"
685 friend class wxWMP10MediaEvtHandler
;
686 DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend
)
690 class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler
: public wxEvtHandler
693 wxWMP10MediaEvtHandler(wxWMP10MediaBackend
*amb
) :
696 m_amb
->m_pAX
->Connect(m_amb
->m_pAX
->GetId(),
698 wxActiveXEventHandler(wxWMP10MediaEvtHandler::OnActiveX
),
703 void OnActiveX(wxActiveXEvent
& event
);
706 wxWMP10MediaBackend
*m_amb
;
708 DECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler
)
712 //===========================================================================
714 //===========================================================================
716 //---------------------------------------------------------------------------
718 // wxWMP10MediaBackend
720 //---------------------------------------------------------------------------
722 IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend
, wxMediaBackend
)
724 //---------------------------------------------------------------------------
725 // wxWMP10MediaBackend Constructor
726 //---------------------------------------------------------------------------
727 wxWMP10MediaBackend::wxWMP10MediaBackend()
737 //---------------------------------------------------------------------------
738 // wxWMP10MediaBackend Destructor
739 //---------------------------------------------------------------------------
740 wxWMP10MediaBackend::~wxWMP10MediaBackend()
745 m_pAX
->DissociateHandle();
748 m_ctrl
->PopEventHandler(true);
754 m_pWMPPlayer
->Release();
755 m_pWMPSettings
->Release();
756 m_pWMPControls
->Release();
760 //---------------------------------------------------------------------------
761 // wxWMP10MediaBackend::CreateControl
762 //---------------------------------------------------------------------------
763 bool wxWMP10MediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
768 const wxValidator
& validator
,
769 const wxString
& name
)
772 if( ::CoCreateInstance(CLSID_WMP10
, NULL
,
773 CLSCTX_INPROC_SERVER
,
774 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
776 if( ::CoCreateInstance(CLSID_WMP10ALT
, NULL
,
777 CLSCTX_INPROC_SERVER
,
778 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
781 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
783 m_pWMPPlayer
->Release();
784 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
788 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
790 m_pWMPSettings
->Release();
791 m_pWMPPlayer
->Release();
792 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
800 // By default wxWindow(s) is created with a border -
801 // so we need to get rid of those
803 // Since we don't have a child window like most other
804 // backends, we don't need wxCLIP_CHILDREN
806 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
807 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
,
812 // Now create the ActiveX container along with the media player
813 // interface and query them
815 m_ctrl
= wxStaticCast(ctrl
, wxMediaCtrl
);
818 m_pAX
= new wxActiveXContainer(ctrl
, IID_IWMPPlayer
, m_pWMPPlayer
);
820 // Connect for events
821 m_ctrl
->PushEventHandler(new wxWMP10MediaEvtHandler(this));
823 _Module
.Init(NULL
, ::GetModuleHandle(NULL
));
825 CComPtr
<IAxWinHostWindow
> spHost
;
829 ::GetClientRect((HWND
)ctrl
->GetHandle(), &rcClient
);
830 m_wndView
.Create((HWND
)ctrl
->GetHandle(), rcClient
, NULL
, WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
, WS_EX_CLIENTEDGE
);
831 hr
= m_wndView
.QueryHost(&spHost
);
832 hr
= spHost
->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView
, 0);
833 hr
= m_wndView
.QueryControl(&m_pWMPPlayer
);
835 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
837 m_pWMPPlayer
->Release();
838 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
842 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
844 m_pWMPSettings
->Release();
845 m_pWMPPlayer
->Release();
846 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
852 // Here we set up wx-specific stuff for the default
853 // settings wxMediaCtrl says it will stay to
856 IWMPPlayer2
* pWMPPlayer2
; // Only 2 has windowless video and stretchtofit
857 if(m_pWMPPlayer
->QueryInterface(IID_IWMPPlayer2
, (void**)&pWMPPlayer2
) == 0)
859 // We don't check errors here as these arn't particularily important
860 // and may not be implemented (i.e. stretchToFit on CE)
861 pWMPPlayer2
->put_windowlessVideo(VARIANT_TRUE
);
862 pWMPPlayer2
->put_stretchToFit(VARIANT_TRUE
);
863 pWMPPlayer2
->Release();
866 // by default true (see the "introduction")
867 m_pWMPSettings
->put_autoStart(VARIANT_TRUE
);
868 // by default enabled
869 wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE
);
870 // by default with AM only 0.5
871 wxWMP10MediaBackend::SetVolume(1.0);
873 // don't erase the background of our control window so that resizing is a
875 m_ctrl
->SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
881 //---------------------------------------------------------------------------
882 // wxWMP10MediaBackend::Load (file version)
883 //---------------------------------------------------------------------------
884 bool wxWMP10MediaBackend::Load(const wxString
& fileName
)
886 return DoLoad(fileName
);
889 //---------------------------------------------------------------------------
890 // wxWMP10MediaBackend::Load (URL Version)
891 //---------------------------------------------------------------------------
892 bool wxWMP10MediaBackend::Load(const wxURI
& location
)
894 return DoLoad(location
.BuildURI());
897 //---------------------------------------------------------------------------
898 // wxWMP10MediaBackend::Load (URL Version with Proxy)
899 //---------------------------------------------------------------------------
900 bool wxWMP10MediaBackend::Load(const wxURI
& location
,
905 IWMPNetwork
* pWMPNetwork
;
906 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
909 if( pWMPNetwork
->getProxySettings(
910 wxBasicString(location
.GetScheme()).Get(), &lOldSetting
913 pWMPNetwork
->setProxySettings(
914 wxBasicString(location
.GetScheme()).Get(), // protocol
915 2) == 0) // 2 == manually specify
917 BSTR bsOldName
= NULL
;
920 pWMPNetwork
->getProxyName(
921 wxBasicString(location
.GetScheme()).Get(),
923 pWMPNetwork
->getProxyPort(
924 wxBasicString(location
.GetScheme()).Get(),
929 if(proxy
.IsReference())
931 server
= proxy
.GetScheme();
932 lPort
= wxAtoi(proxy
.GetPath());
936 server
= proxy
.GetServer();
937 lPort
= wxAtoi(proxy
.GetPort());
940 if( pWMPNetwork
->setProxyName(
941 wxBasicString(location
.GetScheme()).Get(), // proto
942 wxBasicString(server
).Get() ) == 0 &&
944 pWMPNetwork
->setProxyPort(
945 wxBasicString(location
.GetScheme()).Get(), // proto
950 bOK
= DoLoad(location
.BuildURI());
952 pWMPNetwork
->setProxySettings(
953 wxBasicString(location
.GetScheme()).Get(), // protocol
956 pWMPNetwork
->setProxyName(
957 wxBasicString(location
.GetScheme()).Get(), // protocol
961 pWMPNetwork
->setProxyPort(
962 wxBasicString(location
.GetScheme()).Get(), // protocol
965 pWMPNetwork
->Release();
968 pWMPNetwork
->Release();
972 pWMPNetwork
->Release();
979 //---------------------------------------------------------------------------
980 // wxWMP10MediaBackend::DoLoad
982 // Called by all functions - this actually renders
983 // the file and sets up the filter graph
984 //---------------------------------------------------------------------------
985 bool wxWMP10MediaBackend::DoLoad(const wxString
& location
)
989 #if 0 // See the "introduction" - this is the duration hack
990 // ------------------ BLATENT HACK ALERT -------------------------
991 // Normally we can only get the duration of things already in an
992 // existing playlist or playing - however this clever "workaround"
993 // enables us to get the duration even when stopped :)
994 // http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx
996 IWMPCore3
* pWMPCore3
;
998 if(m_pWMPPlayer
->QueryInterface(IID_IWMPCore3
, (void**) &pWMPCore3
) == 0)
1000 IWMPMedia
* pWMPMedia
;
1002 if( (hr
= pWMPCore3
->newMedia(wxBasicString(location
).Get(),
1005 // this (get_duration) will actually FAIL, but it will work.
1006 pWMPMedia
->get_duration(&outDuration
);
1007 pWMPCore3
->put_currentMedia(pWMPMedia
);
1008 pWMPMedia
->Release();
1011 pWMPCore3
->Release();
1016 // just load it the "normal" way
1017 hr
= m_pWMPPlayer
->put_URL( wxBasicString(location
).Get() );
1029 //---------------------------------------------------------------------------
1030 // wxWMP10MediaBackend::FinishLoad
1032 // Called when our media is about to play (a.k.a. wmposMediaOpen)
1033 //---------------------------------------------------------------------------
1034 void wxWMP10MediaBackend::FinishLoad()
1036 // Get the original video size
1037 // THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY
1038 // See the "introduction" - also get_currentMedia will return
1039 // "1" which is a VALID HRESULT value
1040 // and a NULL pWMPMedia if the media isn't the "current" one
1041 // which is rather unintuitive in the sense that it uses it
1042 // (i.e. basically not currently playing)...
1043 IWMPMedia
* pWMPMedia
;
1044 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1046 pWMPMedia
->get_imageSourceWidth((long*)&m_bestSize
.x
);
1047 pWMPMedia
->get_imageSourceHeight((long*)&m_bestSize
.y
);
1048 pWMPMedia
->Release();
1052 wxLogDebug(wxT("Could not get media"));
1055 NotifyMovieLoaded();
1058 //---------------------------------------------------------------------------
1059 // wxWMP10MediaBackend::ShowPlayerControls
1060 //---------------------------------------------------------------------------
1061 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
1065 m_pWMPPlayer
->put_enabled(VARIANT_FALSE
);
1066 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("none")).Get());
1070 // TODO: use "custom"? (note that CE only supports none/full)
1071 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("full")).Get());
1072 m_pWMPPlayer
->put_enabled(VARIANT_TRUE
);
1078 //---------------------------------------------------------------------------
1079 // wxWMP10MediaBackend::Play
1081 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1083 // TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here
1084 // but do we need to?
1085 //---------------------------------------------------------------------------
1086 bool wxWMP10MediaBackend::Play()
1088 // Actually try to play the movie (will fail if not loaded completely)
1089 HRESULT hr
= m_pWMPControls
->play();
1092 m_bWasStateChanged
= true;
1099 //---------------------------------------------------------------------------
1100 // wxWMP10MediaBackend::Pause
1102 // Pauses the stream.
1103 //---------------------------------------------------------------------------
1104 bool wxWMP10MediaBackend::Pause()
1106 HRESULT hr
= m_pWMPControls
->pause();
1109 m_bWasStateChanged
= true;
1116 //---------------------------------------------------------------------------
1117 // wxWMP10MediaBackend::Stop
1119 // Stops the stream.
1120 //---------------------------------------------------------------------------
1121 bool wxWMP10MediaBackend::Stop()
1123 HRESULT hr
= m_pWMPControls
->stop();
1126 // Seek to beginning
1127 wxWMP10MediaBackend::SetPosition(0);
1128 m_bWasStateChanged
= true;
1135 //---------------------------------------------------------------------------
1136 // wxWMP10MediaBackend::SetPosition
1138 // WMP10 position values are a double in seconds - we just translate
1140 //---------------------------------------------------------------------------
1141 bool wxWMP10MediaBackend::SetPosition(wxLongLong where
)
1143 HRESULT hr
= m_pWMPControls
->put_currentPosition(
1144 ((LONGLONG
)where
.GetValue()) / 1000.0
1155 //---------------------------------------------------------------------------
1156 // wxWMP10MediaBackend::GetPosition
1158 // WMP10 position values are a double in seconds - we just translate
1160 //---------------------------------------------------------------------------
1161 wxLongLong
wxWMP10MediaBackend::GetPosition()
1164 HRESULT hr
= m_pWMPControls
->get_currentPosition(&outCur
);
1171 // h,m,s,milli - outCur is in 1 second (double)
1179 //---------------------------------------------------------------------------
1180 // wxWMP10MediaBackend::GetVolume
1183 //---------------------------------------------------------------------------
1184 double wxWMP10MediaBackend::GetVolume()
1187 HRESULT hr
= m_pWMPSettings
->get_volume(&lVolume
);
1194 return (double)lVolume
/ 100.0;
1197 //---------------------------------------------------------------------------
1198 // wxWMP10MediaBackend::SetVolume
1201 //---------------------------------------------------------------------------
1202 bool wxWMP10MediaBackend::SetVolume(double dVolume
)
1204 HRESULT hr
= m_pWMPSettings
->put_volume( (long) (dVolume
* 100.0) );
1213 //---------------------------------------------------------------------------
1214 // wxWMP10MediaBackend::GetDuration
1216 // Obtains the duration of the media.
1218 // See the "introduction"
1220 // The good news is that this doesn't appear to have the XING header
1221 // parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has
1222 //---------------------------------------------------------------------------
1223 wxLongLong
wxWMP10MediaBackend::GetDuration()
1225 double outDuration
= 0.0;
1227 IWMPMedia
* pWMPMedia
;
1228 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1230 if(pWMPMedia
->get_duration(&outDuration
) != 0)
1232 wxLogDebug(wxT("get_duration failed"));
1234 pWMPMedia
->Release();
1238 // h,m,s,milli - outDuration is in 1 second (double)
1239 outDuration
*= 1000;
1241 ll
.Assign(outDuration
);
1246 //---------------------------------------------------------------------------
1247 // wxWMP10MediaBackend::GetState
1249 // Returns the current state
1250 //---------------------------------------------------------------------------
1251 wxMediaState
wxWMP10MediaBackend::GetState()
1253 WMPPlayState nState
;
1254 HRESULT hr
= m_pWMPPlayer
->get_playState(&nState
);
1258 return wxMEDIASTATE_STOPPED
;
1264 return wxMEDIASTATE_PAUSED
;
1266 return wxMEDIASTATE_PLAYING
;
1268 return wxMEDIASTATE_STOPPED
;
1272 //---------------------------------------------------------------------------
1273 // wxWMP10MediaBackend::GetPlaybackRate
1275 // Just get the rate from WMP10
1276 //---------------------------------------------------------------------------
1277 double wxWMP10MediaBackend::GetPlaybackRate()
1280 HRESULT hr
= m_pWMPSettings
->get_rate(&dRate
);
1289 //---------------------------------------------------------------------------
1290 // wxWMP10MediaBackend::SetPlaybackRate
1292 // Sets the playback rate of the media - DirectShow is pretty good
1293 // about this, actually
1294 //---------------------------------------------------------------------------
1295 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate
)
1297 HRESULT hr
= m_pWMPSettings
->put_rate(dRate
);
1307 //---------------------------------------------------------------------------
1308 // wxWMP10MediaBackend::GetVideoSize
1310 // Obtains the cached original video size
1311 //---------------------------------------------------------------------------
1312 wxSize
wxWMP10MediaBackend::GetVideoSize() const
1317 //---------------------------------------------------------------------------
1318 // wxWMP10MediaBackend::Move
1320 // We take care of this in our redrawing
1321 //---------------------------------------------------------------------------
1322 void wxWMP10MediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
),
1326 int WXUNUSED(w
), int WXUNUSED(h
)
1331 m_wndView
.MoveWindow(0,0,w
,h
);
1335 //---------------------------------------------------------------------------
1336 // wxWMP10MediaBackend::GetDownloadProgress()
1337 //---------------------------------------------------------------------------
1338 wxLongLong
wxWMP10MediaBackend::GetDownloadProgress()
1340 IWMPNetwork
* pWMPNetwork
;
1341 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
1344 if(pWMPNetwork
->get_downloadProgress(&lPercentProg
) == 0)
1346 pWMPNetwork
->Release();
1347 return (GetDownloadTotal() * lPercentProg
) / 100;
1349 pWMPNetwork
->Release();
1354 //---------------------------------------------------------------------------
1355 // wxWMP10MediaBackend::GetDownloadTotal()
1356 //---------------------------------------------------------------------------
1357 wxLongLong
wxWMP10MediaBackend::GetDownloadTotal()
1359 IWMPMedia
* pWMPMedia
;
1360 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1363 pWMPMedia
->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
1366 wxString sFileSize
= wxConvertStringFromOle(bsOut
);
1368 sFileSize
.ToLong(&lFS
);
1369 pWMPMedia
->Release();
1377 //---------------------------------------------------------------------------
1378 // wxWMP10MediaBackend::OnActiveX
1380 // Handle events sent from our activex control (_WMPOCXEvents actually).
1382 // The weird numbers in the switch statement here are "dispatch ids"
1383 // (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl
1385 //---------------------------------------------------------------------------
1387 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent
& event
)
1389 switch(event
.GetDispatchId())
1391 case 0x000013ed: // playstatechange
1392 if(event
.ParamCount() >= 1)
1394 switch (event
[0].GetInteger())
1396 case wmppsMediaEnded
: // media ended
1397 if ( m_amb
->SendStopEvent() )
1399 // NB: If we do Stop() or similar here the media
1400 // actually starts over and plays a bit before
1401 // stopping. It stops by default, however, so
1402 // there is no real need to do anything here...
1404 // send the event to our child
1405 m_amb
->QueueFinishEvent();
1409 case wmppsStopped
: // stopping
1410 m_amb
->QueueStopEvent();
1412 case wmppsPaused
: // pause
1413 m_amb
->QueuePauseEvent();
1415 case wmppsPlaying
: // play
1416 m_amb
->QueuePlayEvent();
1426 case 0x00001389: // openstatechange
1427 if(event
.ParamCount() >= 1)
1429 int nState
= event
[0].GetInteger();
1430 if(nState
== wmposMediaOpen
)
1432 // See the "introduction"
1433 m_amb
->m_bWasStateChanged
= false;
1434 m_amb
->FinishLoad();
1435 if(!m_amb
->m_bWasStateChanged
)
1443 case 0x0000196e: // mousedown
1444 m_amb
->m_ctrl
->SetFocus();
1454 // in source file that contains stuff you don't directly use
1455 #include "wx/html/forcelnk.h"
1456 FORCE_LINK_ME(wxmediabackend_wmp10
)
1458 #if 0 // Windows Media Player Mobile 9 hacks
1460 //------------------WMP Mobile 9 hacks-----------------------------------
1461 // It was mentioned in the introduction that while there was no official
1462 // programming interface on WMP mobile 9
1463 // (SmartPhone/Pocket PC 2003 emulator etc.)
1464 // there were some windows message hacks that are able to get
1465 // you playing a file through WMP.
1467 // Here are those hacks. They do indeed "work" as expected - just call
1468 // SendMessage with one of those myterious values layed out in
1469 // Peter Foot's Friday, May 21, 2004 Blog Post on the issue.
1470 // (He says they are in a registery section entitled "Pendant Bus")
1472 // How do you play a certain file? Simply calling "start [file]" or
1473 // wxWinCEExecute([file]) should do the trick
1475 bool wxWinCEExecute(const wxString
& path
, int nShowStyle
= SW_SHOWNORMAL
)
1477 WinStruct
<SHELLEXECUTEINFO
> sei
;
1478 sei
.lpFile
= path
.c_str();
1479 sei
.lpVerb
= _T("open");
1480 sei
.nShow
= nShowStyle
;
1482 ::ShellExecuteEx(&sei
);
1484 return ((int) sei
.hInstApp
) > 32;
1487 bool MyApp::OnInit()
1489 HWND hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1492 if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE
) )
1494 hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1501 ::SetWindowPos(hwnd
, HWND_BOTTOM
, 0, 0, 0, 0,
1502 SWP_NOMOVE
|SWP_NOSIZE
|SWP_HIDEWINDOW
);
1505 // Prev Track == 32971
1506 // Next Track == 32972
1510 // Vol Down == 32976
1512 ::SendMessage(hwnd
, 32978, NULL
, 0);
1516 #endif // WMP mobile 9 hacks
1518 //---------------------------------------------------------------------------
1519 // End wxMediaCtrl Compilation Guard and this file
1520 //---------------------------------------------------------------------------
1521 #endif // wxUSE_MEDIACTRL