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