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"
678 wxEvtHandler
* m_evthandler
;
680 friend class wxWMP10MediaEvtHandler
;
681 DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend
)
685 class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler
: public wxEvtHandler
688 wxWMP10MediaEvtHandler(wxWMP10MediaBackend
*amb
) :
691 m_amb
->m_pAX
->Connect(m_amb
->m_pAX
->GetId(),
693 wxActiveXEventHandler(wxWMP10MediaEvtHandler::OnActiveX
),
698 void OnActiveX(wxActiveXEvent
& event
);
701 wxWMP10MediaBackend
*m_amb
;
703 wxDECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler
);
707 //===========================================================================
709 //===========================================================================
711 //---------------------------------------------------------------------------
713 // wxWMP10MediaBackend
715 //---------------------------------------------------------------------------
717 IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend
, wxMediaBackend
)
719 //---------------------------------------------------------------------------
720 // wxWMP10MediaBackend Constructor
721 //---------------------------------------------------------------------------
722 wxWMP10MediaBackend::wxWMP10MediaBackend()
733 //---------------------------------------------------------------------------
734 // wxWMP10MediaBackend Destructor
735 //---------------------------------------------------------------------------
736 wxWMP10MediaBackend::~wxWMP10MediaBackend()
741 m_pAX
->DissociateHandle();
746 m_ctrl
->RemoveEventHandler(m_evthandler
);
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_evthandler
= new wxWMP10MediaEvtHandler(this);
822 m_ctrl
->PushEventHandler(m_evthandler
);
824 _Module
.Init(NULL
, ::GetModuleHandle(NULL
));
826 CComPtr
<IAxWinHostWindow
> spHost
;
830 ::GetClientRect((HWND
)ctrl
->GetHandle(), &rcClient
);
831 m_wndView
.Create((HWND
)ctrl
->GetHandle(), rcClient
, NULL
, WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
, WS_EX_CLIENTEDGE
);
832 hr
= m_wndView
.QueryHost(&spHost
);
833 hr
= spHost
->CreateControl(CComBSTR(wxT("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView
, 0);
834 hr
= m_wndView
.QueryControl(&m_pWMPPlayer
);
836 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
838 m_pWMPPlayer
->Release();
839 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
843 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
845 m_pWMPSettings
->Release();
846 m_pWMPPlayer
->Release();
847 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
853 // Here we set up wx-specific stuff for the default
854 // settings wxMediaCtrl says it will stay to
857 IWMPPlayer2
* pWMPPlayer2
; // Only 2 has windowless video and stretchtofit
858 if(m_pWMPPlayer
->QueryInterface(IID_IWMPPlayer2
, (void**)&pWMPPlayer2
) == 0)
860 // We don't check errors here as these arn't particularily important
861 // and may not be implemented (i.e. stretchToFit on CE)
862 pWMPPlayer2
->put_windowlessVideo(VARIANT_TRUE
);
863 pWMPPlayer2
->put_stretchToFit(VARIANT_TRUE
);
864 pWMPPlayer2
->Release();
867 // by default true (see the "introduction")
868 m_pWMPSettings
->put_autoStart(VARIANT_TRUE
);
869 // by default enabled
870 wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE
);
871 // by default with AM only 0.5
872 wxWMP10MediaBackend::SetVolume(1.0);
874 // don't erase the background of our control window so that resizing is a
876 m_ctrl
->SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
882 //---------------------------------------------------------------------------
883 // wxWMP10MediaBackend::Load (file version)
884 //---------------------------------------------------------------------------
885 bool wxWMP10MediaBackend::Load(const wxString
& fileName
)
887 return DoLoad(fileName
);
890 //---------------------------------------------------------------------------
891 // wxWMP10MediaBackend::Load (URL Version)
892 //---------------------------------------------------------------------------
893 bool wxWMP10MediaBackend::Load(const wxURI
& location
)
895 return DoLoad(location
.BuildURI());
898 //---------------------------------------------------------------------------
899 // wxWMP10MediaBackend::Load (URL Version with Proxy)
900 //---------------------------------------------------------------------------
901 bool wxWMP10MediaBackend::Load(const wxURI
& location
,
906 IWMPNetwork
* pWMPNetwork
;
907 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
910 if( pWMPNetwork
->getProxySettings(
911 wxBasicString(location
.GetScheme()).Get(), &lOldSetting
914 pWMPNetwork
->setProxySettings(
915 wxBasicString(location
.GetScheme()).Get(), // protocol
916 2) == 0) // 2 == manually specify
918 BSTR bsOldName
= NULL
;
921 pWMPNetwork
->getProxyName(
922 wxBasicString(location
.GetScheme()).Get(),
924 pWMPNetwork
->getProxyPort(
925 wxBasicString(location
.GetScheme()).Get(),
930 if(proxy
.IsReference())
932 server
= proxy
.GetScheme();
933 lPort
= wxAtoi(proxy
.GetPath());
937 server
= proxy
.GetServer();
938 lPort
= wxAtoi(proxy
.GetPort());
941 if( pWMPNetwork
->setProxyName(
942 wxBasicString(location
.GetScheme()).Get(), // proto
943 wxBasicString(server
).Get() ) == 0 &&
945 pWMPNetwork
->setProxyPort(
946 wxBasicString(location
.GetScheme()).Get(), // proto
951 bOK
= DoLoad(location
.BuildURI());
953 pWMPNetwork
->setProxySettings(
954 wxBasicString(location
.GetScheme()).Get(), // protocol
957 pWMPNetwork
->setProxyName(
958 wxBasicString(location
.GetScheme()).Get(), // protocol
962 pWMPNetwork
->setProxyPort(
963 wxBasicString(location
.GetScheme()).Get(), // protocol
966 pWMPNetwork
->Release();
969 pWMPNetwork
->Release();
973 pWMPNetwork
->Release();
980 //---------------------------------------------------------------------------
981 // wxWMP10MediaBackend::DoLoad
983 // Called by all functions - this actually renders
984 // the file and sets up the filter graph
985 //---------------------------------------------------------------------------
986 bool wxWMP10MediaBackend::DoLoad(const wxString
& location
)
990 #if 0 // See the "introduction" - this is the duration hack
991 // ------------------ BLATENT HACK ALERT -------------------------
992 // Normally we can only get the duration of things already in an
993 // existing playlist or playing - however this clever "workaround"
994 // enables us to get the duration even when stopped :)
995 // http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx
997 IWMPCore3
* pWMPCore3
;
999 if(m_pWMPPlayer
->QueryInterface(IID_IWMPCore3
, (void**) &pWMPCore3
) == 0)
1001 IWMPMedia
* pWMPMedia
;
1003 if( (hr
= pWMPCore3
->newMedia(wxBasicString(location
).Get(),
1006 // this (get_duration) will actually FAIL, but it will work.
1007 pWMPMedia
->get_duration(&outDuration
);
1008 pWMPCore3
->put_currentMedia(pWMPMedia
);
1009 pWMPMedia
->Release();
1012 pWMPCore3
->Release();
1017 // just load it the "normal" way
1018 hr
= m_pWMPPlayer
->put_URL( wxBasicString(location
).Get() );
1030 //---------------------------------------------------------------------------
1031 // wxWMP10MediaBackend::FinishLoad
1033 // Called when our media is about to play (a.k.a. wmposMediaOpen)
1034 //---------------------------------------------------------------------------
1035 void wxWMP10MediaBackend::FinishLoad()
1037 // Get the original video size
1038 // THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY
1039 // See the "introduction" - also get_currentMedia will return
1040 // "1" which is a VALID HRESULT value
1041 // and a NULL pWMPMedia if the media isn't the "current" one
1042 // which is rather unintuitive in the sense that it uses it
1043 // (i.e. basically not currently playing)...
1044 IWMPMedia
* pWMPMedia
;
1045 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1047 pWMPMedia
->get_imageSourceWidth((long*)&m_bestSize
.x
);
1048 pWMPMedia
->get_imageSourceHeight((long*)&m_bestSize
.y
);
1049 pWMPMedia
->Release();
1053 wxLogDebug(wxT("Could not get media"));
1056 NotifyMovieLoaded();
1059 //---------------------------------------------------------------------------
1060 // wxWMP10MediaBackend::ShowPlayerControls
1061 //---------------------------------------------------------------------------
1062 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
1066 m_pWMPPlayer
->put_enabled(VARIANT_FALSE
);
1067 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("none")).Get());
1071 // TODO: use "custom"? (note that CE only supports none/full)
1072 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("full")).Get());
1073 m_pWMPPlayer
->put_enabled(VARIANT_TRUE
);
1079 //---------------------------------------------------------------------------
1080 // wxWMP10MediaBackend::Play
1082 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1084 // TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here
1085 // but do we need to?
1086 //---------------------------------------------------------------------------
1087 bool wxWMP10MediaBackend::Play()
1089 // Actually try to play the movie (will fail if not loaded completely)
1090 HRESULT hr
= m_pWMPControls
->play();
1093 m_bWasStateChanged
= true;
1100 //---------------------------------------------------------------------------
1101 // wxWMP10MediaBackend::Pause
1103 // Pauses the stream.
1104 //---------------------------------------------------------------------------
1105 bool wxWMP10MediaBackend::Pause()
1107 HRESULT hr
= m_pWMPControls
->pause();
1110 m_bWasStateChanged
= true;
1117 //---------------------------------------------------------------------------
1118 // wxWMP10MediaBackend::Stop
1120 // Stops the stream.
1121 //---------------------------------------------------------------------------
1122 bool wxWMP10MediaBackend::Stop()
1124 HRESULT hr
= m_pWMPControls
->stop();
1127 // Seek to beginning
1128 wxWMP10MediaBackend::SetPosition(0);
1129 m_bWasStateChanged
= true;
1136 //---------------------------------------------------------------------------
1137 // wxWMP10MediaBackend::SetPosition
1139 // WMP10 position values are a double in seconds - we just translate
1141 //---------------------------------------------------------------------------
1142 bool wxWMP10MediaBackend::SetPosition(wxLongLong where
)
1144 HRESULT hr
= m_pWMPControls
->put_currentPosition(
1145 ((LONGLONG
)where
.GetValue()) / 1000.0
1156 //---------------------------------------------------------------------------
1157 // wxWMP10MediaBackend::GetPosition
1159 // WMP10 position values are a double in seconds - we just translate
1161 //---------------------------------------------------------------------------
1162 wxLongLong
wxWMP10MediaBackend::GetPosition()
1165 HRESULT hr
= m_pWMPControls
->get_currentPosition(&outCur
);
1172 // h,m,s,milli - outCur is in 1 second (double)
1180 //---------------------------------------------------------------------------
1181 // wxWMP10MediaBackend::GetVolume
1184 //---------------------------------------------------------------------------
1185 double wxWMP10MediaBackend::GetVolume()
1188 HRESULT hr
= m_pWMPSettings
->get_volume(&lVolume
);
1195 return (double)lVolume
/ 100.0;
1198 //---------------------------------------------------------------------------
1199 // wxWMP10MediaBackend::SetVolume
1202 //---------------------------------------------------------------------------
1203 bool wxWMP10MediaBackend::SetVolume(double dVolume
)
1205 HRESULT hr
= m_pWMPSettings
->put_volume( (long) (dVolume
* 100.0) );
1214 //---------------------------------------------------------------------------
1215 // wxWMP10MediaBackend::GetDuration
1217 // Obtains the duration of the media.
1219 // See the "introduction"
1221 // The good news is that this doesn't appear to have the XING header
1222 // parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has
1223 //---------------------------------------------------------------------------
1224 wxLongLong
wxWMP10MediaBackend::GetDuration()
1226 double outDuration
= 0.0;
1228 IWMPMedia
* pWMPMedia
;
1229 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1231 if(pWMPMedia
->get_duration(&outDuration
) != 0)
1233 wxLogDebug(wxT("get_duration failed"));
1235 pWMPMedia
->Release();
1239 // h,m,s,milli - outDuration is in 1 second (double)
1240 outDuration
*= 1000;
1242 ll
.Assign(outDuration
);
1247 //---------------------------------------------------------------------------
1248 // wxWMP10MediaBackend::GetState
1250 // Returns the current state
1251 //---------------------------------------------------------------------------
1252 wxMediaState
wxWMP10MediaBackend::GetState()
1254 WMPPlayState nState
;
1255 HRESULT hr
= m_pWMPPlayer
->get_playState(&nState
);
1259 return wxMEDIASTATE_STOPPED
;
1265 return wxMEDIASTATE_PAUSED
;
1267 return wxMEDIASTATE_PLAYING
;
1269 return wxMEDIASTATE_STOPPED
;
1273 //---------------------------------------------------------------------------
1274 // wxWMP10MediaBackend::GetPlaybackRate
1276 // Just get the rate from WMP10
1277 //---------------------------------------------------------------------------
1278 double wxWMP10MediaBackend::GetPlaybackRate()
1281 HRESULT hr
= m_pWMPSettings
->get_rate(&dRate
);
1290 //---------------------------------------------------------------------------
1291 // wxWMP10MediaBackend::SetPlaybackRate
1293 // Sets the playback rate of the media - DirectShow is pretty good
1294 // about this, actually
1295 //---------------------------------------------------------------------------
1296 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate
)
1298 HRESULT hr
= m_pWMPSettings
->put_rate(dRate
);
1308 //---------------------------------------------------------------------------
1309 // wxWMP10MediaBackend::GetVideoSize
1311 // Obtains the cached original video size
1312 //---------------------------------------------------------------------------
1313 wxSize
wxWMP10MediaBackend::GetVideoSize() const
1318 //---------------------------------------------------------------------------
1319 // wxWMP10MediaBackend::Move
1321 // We take care of this in our redrawing
1322 //---------------------------------------------------------------------------
1323 void wxWMP10MediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
),
1327 int WXUNUSED(w
), int WXUNUSED(h
)
1332 m_wndView
.MoveWindow(0,0,w
,h
);
1336 //---------------------------------------------------------------------------
1337 // wxWMP10MediaBackend::GetDownloadProgress()
1338 //---------------------------------------------------------------------------
1339 wxLongLong
wxWMP10MediaBackend::GetDownloadProgress()
1341 IWMPNetwork
* pWMPNetwork
;
1342 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
1345 if(pWMPNetwork
->get_downloadProgress(&lPercentProg
) == 0)
1347 pWMPNetwork
->Release();
1348 return (GetDownloadTotal() * lPercentProg
) / 100;
1350 pWMPNetwork
->Release();
1355 //---------------------------------------------------------------------------
1356 // wxWMP10MediaBackend::GetDownloadTotal()
1357 //---------------------------------------------------------------------------
1358 wxLongLong
wxWMP10MediaBackend::GetDownloadTotal()
1360 IWMPMedia
* pWMPMedia
;
1361 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1364 pWMPMedia
->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
1367 wxString sFileSize
= wxConvertStringFromOle(bsOut
);
1369 sFileSize
.ToLong(&lFS
);
1370 pWMPMedia
->Release();
1378 //---------------------------------------------------------------------------
1379 // wxWMP10MediaBackend::OnActiveX
1381 // Handle events sent from our activex control (_WMPOCXEvents actually).
1383 // The weird numbers in the switch statement here are "dispatch ids"
1384 // (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl
1386 //---------------------------------------------------------------------------
1388 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent
& event
)
1390 switch(event
.GetDispatchId())
1392 case 0x000013ed: // playstatechange
1393 if(event
.ParamCount() >= 1)
1395 switch (event
[0].GetInteger())
1397 case wmppsMediaEnded
: // media ended
1398 if ( m_amb
->SendStopEvent() )
1400 // NB: If we do Stop() or similar here the media
1401 // actually starts over and plays a bit before
1402 // stopping. It stops by default, however, so
1403 // there is no real need to do anything here...
1405 // send the event to our child
1406 m_amb
->QueueFinishEvent();
1410 case wmppsStopped
: // stopping
1411 m_amb
->QueueStopEvent();
1413 case wmppsPaused
: // pause
1414 m_amb
->QueuePauseEvent();
1416 case wmppsPlaying
: // play
1417 m_amb
->QueuePlayEvent();
1427 case 0x00001389: // openstatechange
1428 if(event
.ParamCount() >= 1)
1430 int nState
= event
[0].GetInteger();
1431 if(nState
== wmposMediaOpen
)
1433 // See the "introduction"
1434 m_amb
->m_bWasStateChanged
= false;
1435 m_amb
->FinishLoad();
1436 if(!m_amb
->m_bWasStateChanged
)
1444 case 0x0000196e: // mousedown
1445 m_amb
->m_ctrl
->SetFocus();
1456 // Allow the user code to use wxFORCE_LINK_MODULE() to ensure that this object
1457 // file is not discarded by the linker.
1458 #include "wx/link.h"
1459 wxFORCE_LINK_THIS_MODULE(wxmediabackend_wmp10
)
1461 #if 0 // Windows Media Player Mobile 9 hacks
1463 //------------------WMP Mobile 9 hacks-----------------------------------
1464 // It was mentioned in the introduction that while there was no official
1465 // programming interface on WMP mobile 9
1466 // (SmartPhone/Pocket PC 2003 emulator etc.)
1467 // there were some windows message hacks that are able to get
1468 // you playing a file through WMP.
1470 // Here are those hacks. They do indeed "work" as expected - just call
1471 // SendMessage with one of those myterious values layed out in
1472 // Peter Foot's Friday, May 21, 2004 Blog Post on the issue.
1473 // (He says they are in a registery section entitled "Pendant Bus")
1475 // How do you play a certain file? Simply calling "start [file]" or
1476 // wxWinCEExecute([file]) should do the trick
1478 bool wxWinCEExecute(const wxString
& path
, int nShowStyle
= SW_SHOWNORMAL
)
1480 WinStruct
<SHELLEXECUTEINFO
> sei
;
1481 sei
.lpFile
= path
.c_str();
1482 sei
.lpVerb
= wxT("open");
1483 sei
.nShow
= nShowStyle
;
1485 ::ShellExecuteEx(&sei
);
1487 return ((int) sei
.hInstApp
) > 32;
1490 bool MyApp::OnInit()
1492 HWND hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1495 if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE
) )
1497 hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1504 ::SetWindowPos(hwnd
, HWND_BOTTOM
, 0, 0, 0, 0,
1505 SWP_NOMOVE
|SWP_NOSIZE
|SWP_HIDEWINDOW
);
1508 // Prev Track == 32971
1509 // Next Track == 32972
1513 // Vol Down == 32976
1515 ::SendMessage(hwnd
, 32978, NULL
, 0);
1519 #endif // WMP mobile 9 hacks
1521 #endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX