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 particularly 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()
728 m_pWMPSettings(NULL
),
735 //---------------------------------------------------------------------------
736 // wxWMP10MediaBackend Destructor
737 //---------------------------------------------------------------------------
738 wxWMP10MediaBackend::~wxWMP10MediaBackend()
743 m_pAX
->DissociateHandle();
748 m_ctrl
->RemoveEventHandler(m_evthandler
);
756 m_pWMPPlayer
->Release();
758 m_pWMPSettings
->Release();
760 m_pWMPControls
->Release();
764 //---------------------------------------------------------------------------
765 // wxWMP10MediaBackend::CreateControl
766 //---------------------------------------------------------------------------
767 bool wxWMP10MediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
772 const wxValidator
& validator
,
773 const wxString
& name
)
776 if( ::CoCreateInstance(CLSID_WMP10
, NULL
,
777 CLSCTX_INPROC_SERVER
,
778 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
780 if( ::CoCreateInstance(CLSID_WMP10ALT
, NULL
,
781 CLSCTX_INPROC_SERVER
,
782 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
785 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
787 m_pWMPPlayer
->Release();
788 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
792 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
794 m_pWMPSettings
->Release();
795 m_pWMPPlayer
->Release();
796 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
804 // By default wxWindow(s) is created with a border -
805 // so we need to get rid of those
807 // Since we don't have a child window like most other
808 // backends, we don't need wxCLIP_CHILDREN
810 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
811 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
,
816 // Now create the ActiveX container along with the media player
817 // interface and query them
819 m_ctrl
= wxStaticCast(ctrl
, wxMediaCtrl
);
822 m_pAX
= new wxActiveXContainer(ctrl
, IID_IWMPPlayer
, m_pWMPPlayer
);
824 // Connect for events
825 m_evthandler
= new wxWMP10MediaEvtHandler(this);
826 m_ctrl
->PushEventHandler(m_evthandler
);
828 _Module
.Init(NULL
, ::GetModuleHandle(NULL
));
830 CComPtr
<IAxWinHostWindow
> spHost
;
834 ::GetClientRect((HWND
)ctrl
->GetHandle(), &rcClient
);
835 m_wndView
.Create((HWND
)ctrl
->GetHandle(), rcClient
, NULL
, WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
, WS_EX_CLIENTEDGE
);
836 hr
= m_wndView
.QueryHost(&spHost
);
837 hr
= spHost
->CreateControl(CComBSTR(wxT("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView
, 0);
838 hr
= m_wndView
.QueryControl(&m_pWMPPlayer
);
840 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
842 m_pWMPPlayer
->Release();
843 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
847 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
849 m_pWMPSettings
->Release();
850 m_pWMPPlayer
->Release();
851 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
857 // Here we set up wx-specific stuff for the default
858 // settings wxMediaCtrl says it will stay to
861 IWMPPlayer2
* pWMPPlayer2
; // Only 2 has windowless video and stretchtofit
862 if(m_pWMPPlayer
->QueryInterface(IID_IWMPPlayer2
, (void**)&pWMPPlayer2
) == 0)
864 // We don't check errors here as these arn't particularly important
865 // and may not be implemented (i.e. stretchToFit on CE)
866 pWMPPlayer2
->put_windowlessVideo(VARIANT_TRUE
);
867 pWMPPlayer2
->put_stretchToFit(VARIANT_TRUE
);
868 pWMPPlayer2
->Release();
871 // by default true (see the "introduction")
872 m_pWMPSettings
->put_autoStart(VARIANT_TRUE
);
873 // by default enabled
874 wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE
);
875 // by default with AM only 0.5
876 wxWMP10MediaBackend::SetVolume(1.0);
878 // don't erase the background of our control window so that resizing is a
880 m_ctrl
->SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
886 //---------------------------------------------------------------------------
887 // wxWMP10MediaBackend::Load (file version)
888 //---------------------------------------------------------------------------
889 bool wxWMP10MediaBackend::Load(const wxString
& fileName
)
891 return DoLoad(fileName
);
894 //---------------------------------------------------------------------------
895 // wxWMP10MediaBackend::Load (URL Version)
896 //---------------------------------------------------------------------------
897 bool wxWMP10MediaBackend::Load(const wxURI
& location
)
899 return DoLoad(location
.BuildURI());
902 //---------------------------------------------------------------------------
903 // wxWMP10MediaBackend::Load (URL Version with Proxy)
904 //---------------------------------------------------------------------------
905 bool wxWMP10MediaBackend::Load(const wxURI
& location
,
910 IWMPNetwork
* pWMPNetwork
;
911 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
914 if( pWMPNetwork
->getProxySettings(
915 wxBasicString(location
.GetScheme()).Get(), &lOldSetting
918 pWMPNetwork
->setProxySettings(
919 wxBasicString(location
.GetScheme()).Get(), // protocol
920 2) == 0) // 2 == manually specify
922 BSTR bsOldName
= NULL
;
925 pWMPNetwork
->getProxyName(
926 wxBasicString(location
.GetScheme()).Get(),
928 pWMPNetwork
->getProxyPort(
929 wxBasicString(location
.GetScheme()).Get(),
934 if(proxy
.IsReference())
936 server
= proxy
.GetScheme();
937 lPort
= wxAtoi(proxy
.GetPath());
941 server
= proxy
.GetServer();
942 lPort
= wxAtoi(proxy
.GetPort());
945 if( pWMPNetwork
->setProxyName(
946 wxBasicString(location
.GetScheme()).Get(), // proto
947 wxBasicString(server
).Get() ) == 0 &&
949 pWMPNetwork
->setProxyPort(
950 wxBasicString(location
.GetScheme()).Get(), // proto
955 bOK
= DoLoad(location
.BuildURI());
957 pWMPNetwork
->setProxySettings(
958 wxBasicString(location
.GetScheme()).Get(), // protocol
961 pWMPNetwork
->setProxyName(
962 wxBasicString(location
.GetScheme()).Get(), // protocol
966 pWMPNetwork
->setProxyPort(
967 wxBasicString(location
.GetScheme()).Get(), // protocol
970 pWMPNetwork
->Release();
973 pWMPNetwork
->Release();
977 pWMPNetwork
->Release();
984 //---------------------------------------------------------------------------
985 // wxWMP10MediaBackend::DoLoad
987 // Called by all functions - this actually renders
988 // the file and sets up the filter graph
989 //---------------------------------------------------------------------------
990 bool wxWMP10MediaBackend::DoLoad(const wxString
& location
)
994 #if 0 // See the "introduction" - this is the duration hack
995 // ------------------ BLATENT HACK ALERT -------------------------
996 // Normally we can only get the duration of things already in an
997 // existing playlist or playing - however this clever "workaround"
998 // enables us to get the duration even when stopped :)
999 // http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx
1001 IWMPCore3
* pWMPCore3
;
1003 if(m_pWMPPlayer
->QueryInterface(IID_IWMPCore3
, (void**) &pWMPCore3
) == 0)
1005 IWMPMedia
* pWMPMedia
;
1007 if( (hr
= pWMPCore3
->newMedia(wxBasicString(location
).Get(),
1010 // this (get_duration) will actually FAIL, but it will work.
1011 pWMPMedia
->get_duration(&outDuration
);
1012 pWMPCore3
->put_currentMedia(pWMPMedia
);
1013 pWMPMedia
->Release();
1016 pWMPCore3
->Release();
1021 // just load it the "normal" way
1022 hr
= m_pWMPPlayer
->put_URL( wxBasicString(location
).Get() );
1034 //---------------------------------------------------------------------------
1035 // wxWMP10MediaBackend::FinishLoad
1037 // Called when our media is about to play (a.k.a. wmposMediaOpen)
1038 //---------------------------------------------------------------------------
1039 void wxWMP10MediaBackend::FinishLoad()
1041 // Get the original video size
1042 // THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY
1043 // See the "introduction" - also get_currentMedia will return
1044 // "1" which is a VALID HRESULT value
1045 // and a NULL pWMPMedia if the media isn't the "current" one
1046 // which is rather unintuitive in the sense that it uses it
1047 // (i.e. basically not currently playing)...
1048 IWMPMedia
* pWMPMedia
;
1049 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1051 pWMPMedia
->get_imageSourceWidth((long*)&m_bestSize
.x
);
1052 pWMPMedia
->get_imageSourceHeight((long*)&m_bestSize
.y
);
1053 pWMPMedia
->Release();
1057 wxLogDebug(wxT("Could not get media"));
1060 NotifyMovieLoaded();
1063 //---------------------------------------------------------------------------
1064 // wxWMP10MediaBackend::ShowPlayerControls
1065 //---------------------------------------------------------------------------
1066 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
1070 m_pWMPPlayer
->put_enabled(VARIANT_FALSE
);
1071 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("none")).Get());
1075 // TODO: use "custom"? (note that CE only supports none/full)
1076 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("full")).Get());
1077 m_pWMPPlayer
->put_enabled(VARIANT_TRUE
);
1083 //---------------------------------------------------------------------------
1084 // wxWMP10MediaBackend::Play
1086 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1088 // TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here
1089 // but do we need to?
1090 //---------------------------------------------------------------------------
1091 bool wxWMP10MediaBackend::Play()
1093 // Actually try to play the movie (will fail if not loaded completely)
1094 HRESULT hr
= m_pWMPControls
->play();
1097 m_bWasStateChanged
= true;
1104 //---------------------------------------------------------------------------
1105 // wxWMP10MediaBackend::Pause
1107 // Pauses the stream.
1108 //---------------------------------------------------------------------------
1109 bool wxWMP10MediaBackend::Pause()
1111 HRESULT hr
= m_pWMPControls
->pause();
1114 m_bWasStateChanged
= true;
1121 //---------------------------------------------------------------------------
1122 // wxWMP10MediaBackend::Stop
1124 // Stops the stream.
1125 //---------------------------------------------------------------------------
1126 bool wxWMP10MediaBackend::Stop()
1128 HRESULT hr
= m_pWMPControls
->stop();
1131 // Seek to beginning
1132 wxWMP10MediaBackend::SetPosition(0);
1133 m_bWasStateChanged
= true;
1140 //---------------------------------------------------------------------------
1141 // wxWMP10MediaBackend::SetPosition
1143 // WMP10 position values are a double in seconds - we just translate
1145 //---------------------------------------------------------------------------
1146 bool wxWMP10MediaBackend::SetPosition(wxLongLong where
)
1148 HRESULT hr
= m_pWMPControls
->put_currentPosition(
1149 ((LONGLONG
)where
.GetValue()) / 1000.0
1160 //---------------------------------------------------------------------------
1161 // wxWMP10MediaBackend::GetPosition
1163 // WMP10 position values are a double in seconds - we just translate
1165 //---------------------------------------------------------------------------
1166 wxLongLong
wxWMP10MediaBackend::GetPosition()
1169 HRESULT hr
= m_pWMPControls
->get_currentPosition(&outCur
);
1176 // h,m,s,milli - outCur is in 1 second (double)
1184 //---------------------------------------------------------------------------
1185 // wxWMP10MediaBackend::GetVolume
1188 //---------------------------------------------------------------------------
1189 double wxWMP10MediaBackend::GetVolume()
1192 HRESULT hr
= m_pWMPSettings
->get_volume(&lVolume
);
1199 return (double)lVolume
/ 100.0;
1202 //---------------------------------------------------------------------------
1203 // wxWMP10MediaBackend::SetVolume
1206 //---------------------------------------------------------------------------
1207 bool wxWMP10MediaBackend::SetVolume(double dVolume
)
1209 HRESULT hr
= m_pWMPSettings
->put_volume( (long) (dVolume
* 100.0) );
1218 //---------------------------------------------------------------------------
1219 // wxWMP10MediaBackend::GetDuration
1221 // Obtains the duration of the media.
1223 // See the "introduction"
1225 // The good news is that this doesn't appear to have the XING header
1226 // parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has
1227 //---------------------------------------------------------------------------
1228 wxLongLong
wxWMP10MediaBackend::GetDuration()
1230 double outDuration
= 0.0;
1232 IWMPMedia
* pWMPMedia
;
1233 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1235 if(pWMPMedia
->get_duration(&outDuration
) != 0)
1237 wxLogDebug(wxT("get_duration failed"));
1239 pWMPMedia
->Release();
1243 // h,m,s,milli - outDuration is in 1 second (double)
1244 outDuration
*= 1000;
1246 ll
.Assign(outDuration
);
1251 //---------------------------------------------------------------------------
1252 // wxWMP10MediaBackend::GetState
1254 // Returns the current state
1255 //---------------------------------------------------------------------------
1256 wxMediaState
wxWMP10MediaBackend::GetState()
1258 WMPPlayState nState
;
1259 HRESULT hr
= m_pWMPPlayer
->get_playState(&nState
);
1263 return wxMEDIASTATE_STOPPED
;
1269 return wxMEDIASTATE_PAUSED
;
1271 return wxMEDIASTATE_PLAYING
;
1273 return wxMEDIASTATE_STOPPED
;
1277 //---------------------------------------------------------------------------
1278 // wxWMP10MediaBackend::GetPlaybackRate
1280 // Just get the rate from WMP10
1281 //---------------------------------------------------------------------------
1282 double wxWMP10MediaBackend::GetPlaybackRate()
1285 HRESULT hr
= m_pWMPSettings
->get_rate(&dRate
);
1294 //---------------------------------------------------------------------------
1295 // wxWMP10MediaBackend::SetPlaybackRate
1297 // Sets the playback rate of the media - DirectShow is pretty good
1298 // about this, actually
1299 //---------------------------------------------------------------------------
1300 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate
)
1302 HRESULT hr
= m_pWMPSettings
->put_rate(dRate
);
1312 //---------------------------------------------------------------------------
1313 // wxWMP10MediaBackend::GetVideoSize
1315 // Obtains the cached original video size
1316 //---------------------------------------------------------------------------
1317 wxSize
wxWMP10MediaBackend::GetVideoSize() const
1322 //---------------------------------------------------------------------------
1323 // wxWMP10MediaBackend::Move
1325 // We take care of this in our redrawing
1326 //---------------------------------------------------------------------------
1327 void wxWMP10MediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
),
1331 int WXUNUSED(w
), int WXUNUSED(h
)
1336 m_wndView
.MoveWindow(0,0,w
,h
);
1340 //---------------------------------------------------------------------------
1341 // wxWMP10MediaBackend::GetDownloadProgress()
1342 //---------------------------------------------------------------------------
1343 wxLongLong
wxWMP10MediaBackend::GetDownloadProgress()
1345 IWMPNetwork
* pWMPNetwork
;
1346 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
1349 if(pWMPNetwork
->get_downloadProgress(&lPercentProg
) == 0)
1351 pWMPNetwork
->Release();
1352 return (GetDownloadTotal() * lPercentProg
) / 100;
1354 pWMPNetwork
->Release();
1359 //---------------------------------------------------------------------------
1360 // wxWMP10MediaBackend::GetDownloadTotal()
1361 //---------------------------------------------------------------------------
1362 wxLongLong
wxWMP10MediaBackend::GetDownloadTotal()
1364 IWMPMedia
* pWMPMedia
;
1365 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1368 pWMPMedia
->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
1371 wxString sFileSize
= wxConvertStringFromOle(bsOut
);
1373 sFileSize
.ToLong(&lFS
);
1374 pWMPMedia
->Release();
1382 //---------------------------------------------------------------------------
1383 // wxWMP10MediaBackend::OnActiveX
1385 // Handle events sent from our activex control (_WMPOCXEvents actually).
1387 // The weird numbers in the switch statement here are "dispatch ids"
1388 // (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl
1390 //---------------------------------------------------------------------------
1392 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent
& event
)
1394 switch(event
.GetDispatchId())
1396 case 0x000013ed: // playstatechange
1397 if(event
.ParamCount() >= 1)
1399 switch (event
[0].GetInteger())
1401 case wmppsMediaEnded
: // media ended
1402 if ( m_amb
->SendStopEvent() )
1404 // NB: If we do Stop() or similar here the media
1405 // actually starts over and plays a bit before
1406 // stopping. It stops by default, however, so
1407 // there is no real need to do anything here...
1409 // send the event to our child
1410 m_amb
->QueueFinishEvent();
1414 case wmppsStopped
: // stopping
1415 m_amb
->QueueStopEvent();
1417 case wmppsPaused
: // pause
1418 m_amb
->QueuePauseEvent();
1420 case wmppsPlaying
: // play
1421 m_amb
->QueuePlayEvent();
1431 case 0x00001389: // openstatechange
1432 if(event
.ParamCount() >= 1)
1434 int nState
= event
[0].GetInteger();
1435 if(nState
== wmposMediaOpen
)
1437 // See the "introduction"
1438 m_amb
->m_bWasStateChanged
= false;
1439 m_amb
->FinishLoad();
1440 if(!m_amb
->m_bWasStateChanged
)
1448 case 0x0000196e: // mousedown
1449 m_amb
->m_ctrl
->SetFocus();
1460 // Allow the user code to use wxFORCE_LINK_MODULE() to ensure that this object
1461 // file is not discarded by the linker.
1462 #include "wx/link.h"
1463 wxFORCE_LINK_THIS_MODULE(wxmediabackend_wmp10
)
1465 #if 0 // Windows Media Player Mobile 9 hacks
1467 //------------------WMP Mobile 9 hacks-----------------------------------
1468 // It was mentioned in the introduction that while there was no official
1469 // programming interface on WMP mobile 9
1470 // (SmartPhone/Pocket PC 2003 emulator etc.)
1471 // there were some windows message hacks that are able to get
1472 // you playing a file through WMP.
1474 // Here are those hacks. They do indeed "work" as expected - just call
1475 // SendMessage with one of those myterious values laid out in
1476 // Peter Foot's Friday, May 21, 2004 Blog Post on the issue.
1477 // (He says they are in a registery section entitled "Pendant Bus")
1479 // How do you play a certain file? Simply calling "start [file]" or
1480 // wxWinCEExecute([file]) should do the trick
1482 bool wxWinCEExecute(const wxString
& path
, int nShowStyle
= SW_SHOWNORMAL
)
1484 WinStruct
<SHELLEXECUTEINFO
> sei
;
1485 sei
.lpFile
= path
.c_str();
1486 sei
.lpVerb
= wxT("open");
1487 sei
.nShow
= nShowStyle
;
1489 ::ShellExecuteEx(&sei
);
1491 return ((int) sei
.hInstApp
) > 32;
1494 bool MyApp::OnInit()
1496 HWND hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1499 if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE
) )
1501 hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1508 ::SetWindowPos(hwnd
, HWND_BOTTOM
, 0, 0, 0, 0,
1509 SWP_NOMOVE
|SWP_NOSIZE
|SWP_HIDEWINDOW
);
1512 // Prev Track == 32971
1513 // Next Track == 32972
1517 // Vol Down == 32976
1519 ::SendMessage(hwnd
, 32978, NULL
, 0);
1523 #endif // WMP mobile 9 hacks
1525 #endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX