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>
7 // Copyright: (c) Ryan Norton
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 //-----------------Introduction----------------------------------------------
12 // This backend is for Desktops with either WMP 9 or 10 and Windows
13 // mobile (5.0, some 2003 SmartPhones etc.) WMP 10 only (9 has no automation
14 // interface but you can hack it with message hacks to play through
15 // a currently running instance of media player).
17 // There are quite a few WMP 10 interfaces and unlike other media
18 // backends we actually set it to automatically play files as it has
19 // as huge caveat that you cannot (technically) obtain media information
20 // from IWMPMedia including duration and video size until a media file
21 // has literally started to play. There is a hack (and indeed we have
22 // it within this file) to enable duration getting from a non-playing
23 // file, but there is no hack I (RN) know of to get the video size from
24 // a file that isn't playing.
26 // The workaround for this is to send the wxEVT_MEDIA_LOADED when the file
27 // is about to be played - and if the user didn't change the state of the
28 // media (m_bWasStateChanged), when set it back to the stop state.
30 // The ActiveX control itself is particularly stubborn, calling
31 // IOleInPlaceSite::OnPosRectChange every file change trying to set itself
32 // to something different then what we told it to before.
35 // http://msdn.microsoft.com/library/en-us/wmplay10/mmp_sdk/windowsmediaplayer10sdk.asp
37 //===========================================================================
39 //===========================================================================
41 //---------------------------------------------------------------------------
42 // Pre-compiled header stuff
43 //---------------------------------------------------------------------------
45 // For compilers that support precompilation, includes "wx.h".
46 #include "wx/wxprec.h"
52 #if wxUSE_MEDIACTRL && wxUSE_ACTIVEX
54 #include "wx/mediactrl.h"
60 #include "wx/msw/private.h" // user info and wndproc setting/getting
61 #include "wx/msw/ole/activex.h" // wxActiveXContainer - COM-specific stuff
63 //---------------------------------------------------------------------------
64 // ATL Includes - define WXTEST_ATL if you
65 // want to use CAxWindow instead of wxActiveXContainer (note that
66 // this is mainly for testing as the activex events arn't implemented here)
67 //---------------------------------------------------------------------------
75 #define min(x,y) (x < y ? x : y)
81 //---------------------------------------------------------------------------
83 //---------------------------------------------------------------------------
85 // disable "cast truncates constant value" for VARIANT_BOOL values
86 // passed as parameters in VC6
88 #pragma warning (disable:4310)
91 // error logger for HRESULTS (nothing really now)
94 //---------------------------------------------------------------------------
95 // Various definitions dumped from wmp.IDL
96 //---------------------------------------------------------------------------
98 // CLSID_WMP10ALT is on CE and in some MS docs - on others it is the plain ver
99 const CLSID CLSID_WMP10
= {0x6BF52A50,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
100 const CLSID CLSID_WMP10ALT
= {0x6BF52A52,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
102 const IID IID_IWMPSettings
= {0x9104D1AB,0x80C9,0x4FED,{0xAB,0xF0,0x2E,0x64,0x17,0xA6,0xDF,0x14}};
103 const IID IID_IWMPCore
= {0xD84CCA99,0xCCE2,0x11D2,{0x9E,0xCC,0x00,0x00,0xF8,0x08,0x59,0x81}};
105 const IID IID_IWMPPlayer
= {0x6BF52A4F,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
108 const IID IID_IWMPMedia
= {0x94D55E95,0x3FAC,0x11D3,{0xB1,0x55,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
109 const IID IID_IWMPControls
= {0x74C09E02,0xF828,0x11D2,{0xA7,0x4B,0x00,0xA0,0xC9,0x05,0xF3,0x6E}};
110 const IID IID_IWMPPlayer2
= {0x0E6B01D1,0xD407,0x4C85,{0xBF,0x5F,0x1C,0x01,0xF6,0x15,0x02,0x80}};
111 const IID IID_IWMPCore2
= {0xBC17E5B7,0x7561,0x4C18,{0xBB,0x90,0x17,0xD4,0x85,0x77,0x56,0x59}};
112 const IID IID_IWMPCore3
= {0x7587C667,0x628F,0x499F,{0x88,0xE7,0x6A,0x6F,0x4E,0x88,0x84,0x64}};
113 const IID IID_IWMPNetwork
= {0xEC21B779,0xEDEF,0x462D,{0xBB,0xA4,0xAD,0x9D,0xDE,0x2B,0x29,0xA7}};
118 wmposPlaylistChanging
= 1,
119 wmposPlaylistLocating
= 2,
120 wmposPlaylistConnecting
= 3,
121 wmposPlaylistLoading
= 4,
122 wmposPlaylistOpening
= 5,
123 wmposPlaylistOpenNoMedia
= 6,
124 wmposPlaylistChanged
= 7,
125 wmposMediaChanging
= 8,
126 wmposMediaLocating
= 9,
127 wmposMediaConnecting
= 10,
128 wmposMediaLoading
= 11,
129 wmposMediaOpening
= 12,
131 wmposBeginCodecAcquisition
= 14,
132 wmposEndCodecAcquisition
= 15,
133 wmposBeginLicenseAcquisition
= 16,
134 wmposEndLicenseAcquisition
= 17,
135 wmposBeginIndividualization
= 18,
136 wmposEndIndividualization
= 19,
137 wmposMediaWaiting
= 20,
138 wmposOpeningUnknownURL
= 21
147 wmppsScanForward
= 4,
148 wmppsScanReverse
= 5,
152 wmppsTransitioning
= 9,
154 wmppsReconnecting
= 11,
159 struct IWMPMedia
: public IDispatch
162 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isIdentical(
163 /* [in] */ IWMPMedia __RPC_FAR
*pIWMPMedia
,
164 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvbool
) = 0;
166 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_sourceURL(
167 /* [retval][out] */ BSTR __RPC_FAR
*pbstrSourceURL
) = 0;
169 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_name(
170 /* [retval][out] */ BSTR __RPC_FAR
*pbstrName
) = 0;
172 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_name(
173 /* [in] */ BSTR pbstrName
) = 0;
175 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_imageSourceWidth(
176 /* [retval][out] */ long __RPC_FAR
*pWidth
) = 0;
178 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_imageSourceHeight(
179 /* [retval][out] */ long __RPC_FAR
*pHeight
) = 0;
181 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_markerCount(
182 /* [retval][out] */ long __RPC_FAR
*pMarkerCount
) = 0;
184 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMarkerTime(
185 /* [in] */ long MarkerNum
,
186 /* [retval][out] */ double __RPC_FAR
*pMarkerTime
) = 0;
188 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMarkerName(
189 /* [in] */ long MarkerNum
,
190 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMarkerName
) = 0;
192 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_duration(
193 /* [retval][out] */ double __RPC_FAR
*pDuration
) = 0;
195 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_durationString(
196 /* [retval][out] */ BSTR __RPC_FAR
*pbstrDuration
) = 0;
198 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_attributeCount(
199 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
201 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getAttributeName(
202 /* [in] */ long lIndex
,
203 /* [retval][out] */ BSTR __RPC_FAR
*pbstrItemName
) = 0;
205 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getItemInfo(
206 /* [in] */ BSTR bstrItemName
,
207 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVal
) = 0;
209 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setItemInfo(
210 /* [in] */ BSTR bstrItemName
,
211 /* [in] */ BSTR bstrVal
) = 0;
213 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getItemInfoByAtom(
214 /* [in] */ long lAtom
,
215 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVal
) = 0;
217 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
isMemberOf(
218 /* [in] */ IUnknown __RPC_FAR
*pPlaylist
,
219 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfIsMemberOf
) = 0;
221 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
isReadOnlyItem(
222 /* [in] */ BSTR bstrItemName
,
223 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfIsReadOnly
) = 0;
227 struct IWMPControls
: public IDispatch
230 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isAvailable(
231 /* [in] */ BSTR bstrItem
,
232 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pIsAvailable
) = 0;
234 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
play( void) = 0;
236 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
stop( void) = 0;
238 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
pause( void) = 0;
240 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
fastForward( void) = 0;
242 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
fastReverse( void) = 0;
244 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPosition(
245 /* [retval][out] */ double __RPC_FAR
*pdCurrentPosition
) = 0;
247 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentPosition(
248 /* [in] */ double pdCurrentPosition
) = 0;
250 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPositionString(
251 /* [retval][out] */ BSTR __RPC_FAR
*pbstrCurrentPosition
) = 0;
253 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
next( void) = 0;
255 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
previous( void) = 0;
257 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentItem(
258 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppIWMPMedia
) = 0;
260 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentItem(
261 /* [in] */ IWMPMedia __RPC_FAR
*ppIWMPMedia
) = 0;
263 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentMarker(
264 /* [retval][out] */ long __RPC_FAR
*plMarker
) = 0;
266 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentMarker(
267 /* [in] */ long plMarker
) = 0;
269 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
playItem(
270 /* [in] */ IWMPMedia __RPC_FAR
*pIWMPMedia
) = 0;
275 struct IWMPSettings
: public IDispatch
278 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isAvailable(
279 /* [in] */ BSTR bstrItem
,
280 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pIsAvailable
) = 0;
282 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_autoStart(
283 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfAutoStart
) = 0;
285 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_autoStart(
286 /* [in] */ VARIANT_BOOL pfAutoStart
) = 0;
288 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_baseURL(
289 /* [retval][out] */ BSTR __RPC_FAR
*pbstrBaseURL
) = 0;
291 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_baseURL(
292 /* [in] */ BSTR pbstrBaseURL
) = 0;
294 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_defaultFrame(
295 /* [retval][out] */ BSTR __RPC_FAR
*pbstrDefaultFrame
) = 0;
297 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_defaultFrame(
298 /* [in] */ BSTR pbstrDefaultFrame
) = 0;
300 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_invokeURLs(
301 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfInvokeURLs
) = 0;
303 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_invokeURLs(
304 /* [in] */ VARIANT_BOOL pfInvokeURLs
) = 0;
306 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_mute(
307 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfMute
) = 0;
309 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_mute(
310 /* [in] */ VARIANT_BOOL pfMute
) = 0;
312 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playCount(
313 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
315 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_playCount(
316 /* [in] */ long plCount
) = 0;
318 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_rate(
319 /* [retval][out] */ double __RPC_FAR
*pdRate
) = 0;
321 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_rate(
322 /* [in] */ double pdRate
) = 0;
324 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_balance(
325 /* [retval][out] */ long __RPC_FAR
*plBalance
) = 0;
327 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_balance(
328 /* [in] */ long plBalance
) = 0;
330 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_volume(
331 /* [retval][out] */ long __RPC_FAR
*plVolume
) = 0;
333 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_volume(
334 /* [in] */ long plVolume
) = 0;
336 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getMode(
337 /* [in] */ BSTR bstrMode
,
338 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pvarfMode
) = 0;
340 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setMode(
341 /* [in] */ BSTR bstrMode
,
342 /* [in] */ VARIANT_BOOL varfMode
) = 0;
344 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableErrorDialogs(
345 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfEnableErrorDialogs
) = 0;
347 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableErrorDialogs(
348 /* [in] */ VARIANT_BOOL pfEnableErrorDialogs
) = 0;
352 struct IWMPNetwork
: public IDispatch
355 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bandWidth(
356 /* [retval][out] */ long __RPC_FAR
*plBandwidth
) = 0;
358 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_recoveredPackets(
359 /* [retval][out] */ long __RPC_FAR
*plRecoveredPackets
) = 0;
361 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_sourceProtocol(
362 /* [retval][out] */ BSTR __RPC_FAR
*pbstrSourceProtocol
) = 0;
364 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_receivedPackets(
365 /* [retval][out] */ long __RPC_FAR
*plReceivedPackets
) = 0;
367 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_lostPackets(
368 /* [retval][out] */ long __RPC_FAR
*plLostPackets
) = 0;
370 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_receptionQuality(
371 /* [retval][out] */ long __RPC_FAR
*plReceptionQuality
) = 0;
373 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingCount(
374 /* [retval][out] */ long __RPC_FAR
*plBufferingCount
) = 0;
376 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingProgress(
377 /* [retval][out] */ long __RPC_FAR
*plBufferingProgress
) = 0;
379 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bufferingTime(
380 /* [retval][out] */ long __RPC_FAR
*plBufferingTime
) = 0;
382 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_bufferingTime(
383 /* [in] */ long plBufferingTime
) = 0;
385 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_frameRate(
386 /* [retval][out] */ long __RPC_FAR
*plFrameRate
) = 0;
388 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_maxBitRate(
389 /* [retval][out] */ long __RPC_FAR
*plBitRate
) = 0;
391 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_bitRate(
392 /* [retval][out] */ long __RPC_FAR
*plBitRate
) = 0;
394 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxySettings(
395 /* [in] */ BSTR bstrProtocol
,
396 /* [retval][out] */ long __RPC_FAR
*plProxySetting
) = 0;
398 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxySettings(
399 /* [in] */ BSTR bstrProtocol
,
400 /* [in] */ long lProxySetting
) = 0;
402 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyName(
403 /* [in] */ BSTR bstrProtocol
,
404 /* [retval][out] */ BSTR __RPC_FAR
*pbstrProxyName
) = 0;
406 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyName(
407 /* [in] */ BSTR bstrProtocol
,
408 /* [in] */ BSTR bstrProxyName
) = 0;
410 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyPort(
411 /* [in] */ BSTR bstrProtocol
,
412 /* [retval][out] */ long __RPC_FAR
*lProxyPort
) = 0;
414 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyPort(
415 /* [in] */ BSTR bstrProtocol
,
416 /* [in] */ long lProxyPort
) = 0;
418 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyExceptionList(
419 /* [in] */ BSTR bstrProtocol
,
420 /* [retval][out] */ BSTR __RPC_FAR
*pbstrExceptionList
) = 0;
422 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyExceptionList(
423 /* [in] */ BSTR bstrProtocol
,
424 /* [in] */ BSTR pbstrExceptionList
) = 0;
426 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
getProxyBypassForLocal(
427 /* [in] */ BSTR bstrProtocol
,
428 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfBypassForLocal
) = 0;
430 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
setProxyBypassForLocal(
431 /* [in] */ BSTR bstrProtocol
,
432 /* [in] */ VARIANT_BOOL fBypassForLocal
) = 0;
434 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_maxBandwidth(
435 /* [retval][out] */ long __RPC_FAR
*lMaxBandwidth
) = 0;
437 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_maxBandwidth(
438 /* [in] */ long lMaxBandwidth
) = 0;
440 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_downloadProgress(
441 /* [retval][out] */ long __RPC_FAR
*plDownloadProgress
) = 0;
443 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_encodedFrameRate(
444 /* [retval][out] */ long __RPC_FAR
*plFrameRate
) = 0;
446 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_framesSkipped(
447 /* [retval][out] */ long __RPC_FAR
*plFrames
) = 0;
451 struct IWMPCore
: public IDispatch
454 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
close( void) = 0;
456 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_URL(
457 /* [retval][out] */ BSTR __RPC_FAR
*pbstrURL
) = 0;
459 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_URL(
460 /* [in] */ BSTR pbstrURL
) = 0;
462 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_openState(
463 /* [retval][out] */ WMPOpenState __RPC_FAR
*pwmpos
) = 0;
465 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playState(
466 /* [retval][out] */ WMPPlayState __RPC_FAR
*pwmpps
) = 0;
468 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_controls(
469 /* [retval][out] */ IWMPControls __RPC_FAR
*__RPC_FAR
*ppControl
) = 0;
471 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_settings(
472 /* [retval][out] */ IWMPSettings __RPC_FAR
*__RPC_FAR
*ppSettings
) = 0;
474 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentMedia(
475 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppMedia
) = 0;
477 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentMedia(
478 /* [in] */ IUnknown __RPC_FAR
*ppMedia
) = 0;
480 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_mediaCollection(
481 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppMediaCollection
) = 0;
483 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_playlistCollection(
484 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPlaylistCollection
) = 0;
486 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_versionInfo(
487 /* [retval][out] */ BSTR __RPC_FAR
*pbstrVersionInfo
) = 0;
489 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
launchURL(
490 /* [in] */ BSTR bstrURL
) = 0;
492 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_network(
493 /* [retval][out] */ IWMPNetwork __RPC_FAR
*__RPC_FAR
*ppQNI
) = 0;
495 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_currentPlaylist(
496 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPL
) = 0;
498 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_currentPlaylist(
499 /* [in] */ IUnknown __RPC_FAR
*ppPL
) = 0;
501 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_cdromCollection(
502 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppCdromCollection
) = 0;
504 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_closedCaption(
505 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppClosedCaption
) = 0;
507 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_isOnline(
508 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pfOnline
) = 0;
510 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_Error(
511 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppError
) = 0;
513 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_status(
514 /* [retval][out] */ BSTR __RPC_FAR
*pbstrStatus
) = 0;
518 struct IWMPCore2
: public IWMPCore
521 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_dvd(
522 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppDVD
) = 0;
526 struct IWMPCore3
: public IWMPCore2
529 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
newPlaylist(
530 /* [in] */ BSTR bstrName
,
531 /* [in] */ BSTR bstrURL
,
532 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppPlaylist
) = 0;
534 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
newMedia(
535 /* [in] */ BSTR bstrURL
,
536 /* [retval][out] */ IWMPMedia __RPC_FAR
*__RPC_FAR
*ppMedia
) = 0;
541 MIDL_INTERFACE("6BF52A4F-394A-11D3-B153-00C04F79FAA6")
545 IWMPPlayer
: public IWMPCore
548 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enabled(
549 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
551 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enabled(
552 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
554 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_fullScreen(
555 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbFullScreen
) = 0;
557 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_fullScreen(
558 VARIANT_BOOL pbFullScreen
) = 0;
560 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableContextMenu(
561 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnableContextMenu
) = 0;
563 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableContextMenu(
564 VARIANT_BOOL pbEnableContextMenu
) = 0;
566 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_uiMode(
567 /* [in] */ BSTR pbstrMode
) = 0;
569 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_uiMode(
570 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMode
) = 0;
573 struct IWMPPlayer2
: public IWMPCore
576 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enabled(
577 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
579 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enabled(
580 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
582 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_fullScreen(
583 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbFullScreen
) = 0;
585 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_fullScreen(
586 VARIANT_BOOL pbFullScreen
) = 0;
588 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_enableContextMenu(
589 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnableContextMenu
) = 0;
591 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_enableContextMenu(
592 VARIANT_BOOL pbEnableContextMenu
) = 0;
594 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_uiMode(
595 /* [in] */ BSTR pbstrMode
) = 0;
597 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_uiMode(
598 /* [retval][out] */ BSTR __RPC_FAR
*pbstrMode
) = 0;
600 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_stretchToFit(
601 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
603 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_stretchToFit(
604 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
606 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE
get_windowlessVideo(
607 /* [retval][out] */ VARIANT_BOOL __RPC_FAR
*pbEnabled
) = 0;
609 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE
put_windowlessVideo(
610 /* [in] */ VARIANT_BOOL pbEnabled
) = 0;
614 //---------------------------------------------------------------------------
616 // wxWMP10MediaBackend
618 //---------------------------------------------------------------------------
620 class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend
: public wxMediaBackendCommonBase
623 wxWMP10MediaBackend();
624 virtual ~wxWMP10MediaBackend();
626 virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
631 const wxValidator
& validator
,
632 const wxString
& name
);
635 virtual bool Pause();
638 virtual bool Load(const wxString
& fileName
);
639 virtual bool Load(const wxURI
& location
);
640 virtual bool Load(const wxURI
& location
, const wxURI
& proxy
);
642 bool DoLoad(const wxString
& location
);
645 virtual wxMediaState
GetState();
647 virtual bool SetPosition(wxLongLong where
);
648 virtual wxLongLong
GetPosition();
649 virtual wxLongLong
GetDuration();
651 virtual void Move(int x
, int y
, int w
, int h
);
652 wxSize
GetVideoSize() const;
654 virtual double GetPlaybackRate();
655 virtual bool SetPlaybackRate(double);
657 virtual double GetVolume();
658 virtual bool SetVolume(double);
660 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags
);
662 virtual wxLongLong
GetDownloadProgress();
663 virtual wxLongLong
GetDownloadTotal();
669 wxActiveXContainer
* m_pAX
;
671 IWMPPlayer
* m_pWMPPlayer
; // Main activex interface
672 IWMPSettings
* m_pWMPSettings
; // Settings such as volume
673 IWMPControls
* m_pWMPControls
; // Control interface (play etc.)
674 wxSize m_bestSize
; // Actual movie size
676 bool m_bWasStateChanged
; // See the "introduction"
677 wxEvtHandler
* m_evthandler
;
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 wxDECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler
);
706 //===========================================================================
708 //===========================================================================
710 //---------------------------------------------------------------------------
712 // wxWMP10MediaBackend
714 //---------------------------------------------------------------------------
716 IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend
, wxMediaBackend
)
718 //---------------------------------------------------------------------------
719 // wxWMP10MediaBackend Constructor
720 //---------------------------------------------------------------------------
721 wxWMP10MediaBackend::wxWMP10MediaBackend()
727 m_pWMPSettings(NULL
),
734 //---------------------------------------------------------------------------
735 // wxWMP10MediaBackend Destructor
736 //---------------------------------------------------------------------------
737 wxWMP10MediaBackend::~wxWMP10MediaBackend()
742 m_pAX
->DissociateHandle();
747 m_ctrl
->RemoveEventHandler(m_evthandler
);
755 m_pWMPPlayer
->Release();
757 m_pWMPSettings
->Release();
759 m_pWMPControls
->Release();
763 //---------------------------------------------------------------------------
764 // wxWMP10MediaBackend::CreateControl
765 //---------------------------------------------------------------------------
766 bool wxWMP10MediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
771 const wxValidator
& validator
,
772 const wxString
& name
)
775 if( ::CoCreateInstance(CLSID_WMP10
, NULL
,
776 CLSCTX_INPROC_SERVER
,
777 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
779 if( ::CoCreateInstance(CLSID_WMP10ALT
, NULL
,
780 CLSCTX_INPROC_SERVER
,
781 IID_IWMPPlayer
, (void**)&m_pWMPPlayer
) != 0 )
784 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
786 m_pWMPPlayer
->Release();
787 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
791 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
793 m_pWMPSettings
->Release();
794 m_pWMPPlayer
->Release();
795 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
803 // By default wxWindow(s) is created with a border -
804 // so we need to get rid of those
806 // Since we don't have a child window like most other
807 // backends, we don't need wxCLIP_CHILDREN
809 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
810 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
,
815 // Now create the ActiveX container along with the media player
816 // interface and query them
818 m_ctrl
= wxStaticCast(ctrl
, wxMediaCtrl
);
821 m_pAX
= new wxActiveXContainer(ctrl
, IID_IWMPPlayer
, m_pWMPPlayer
);
823 // Connect for events
824 m_evthandler
= new wxWMP10MediaEvtHandler(this);
825 m_ctrl
->PushEventHandler(m_evthandler
);
827 _Module
.Init(NULL
, ::GetModuleHandle(NULL
));
829 CComPtr
<IAxWinHostWindow
> spHost
;
833 ::GetClientRect((HWND
)ctrl
->GetHandle(), &rcClient
);
834 m_wndView
.Create((HWND
)ctrl
->GetHandle(), rcClient
, NULL
, WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
, WS_EX_CLIENTEDGE
);
835 hr
= m_wndView
.QueryHost(&spHost
);
836 hr
= spHost
->CreateControl(CComBSTR(wxT("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView
, 0);
837 hr
= m_wndView
.QueryControl(&m_pWMPPlayer
);
839 if( m_pWMPPlayer
->get_settings(&m_pWMPSettings
) != 0)
841 m_pWMPPlayer
->Release();
842 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
846 if( m_pWMPPlayer
->get_controls(&m_pWMPControls
) != 0)
848 m_pWMPSettings
->Release();
849 m_pWMPPlayer
->Release();
850 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
856 // Here we set up wx-specific stuff for the default
857 // settings wxMediaCtrl says it will stay to
860 IWMPPlayer2
* pWMPPlayer2
; // Only 2 has windowless video and stretchtofit
861 if(m_pWMPPlayer
->QueryInterface(IID_IWMPPlayer2
, (void**)&pWMPPlayer2
) == 0)
863 // We don't check errors here as these arn't particularly important
864 // and may not be implemented (i.e. stretchToFit on CE)
865 pWMPPlayer2
->put_windowlessVideo(VARIANT_TRUE
);
866 pWMPPlayer2
->put_stretchToFit(VARIANT_TRUE
);
867 pWMPPlayer2
->Release();
870 // by default true (see the "introduction")
871 m_pWMPSettings
->put_autoStart(VARIANT_TRUE
);
872 // by default enabled
873 wxWMP10MediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE
);
874 // by default with AM only 0.5
875 wxWMP10MediaBackend::SetVolume(1.0);
877 // don't erase the background of our control window so that resizing is a
879 m_ctrl
->SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
885 //---------------------------------------------------------------------------
886 // wxWMP10MediaBackend::Load (file version)
887 //---------------------------------------------------------------------------
888 bool wxWMP10MediaBackend::Load(const wxString
& fileName
)
890 return DoLoad(fileName
);
893 //---------------------------------------------------------------------------
894 // wxWMP10MediaBackend::Load (URL Version)
895 //---------------------------------------------------------------------------
896 bool wxWMP10MediaBackend::Load(const wxURI
& location
)
898 return DoLoad(location
.BuildURI());
901 //---------------------------------------------------------------------------
902 // wxWMP10MediaBackend::Load (URL Version with Proxy)
903 //---------------------------------------------------------------------------
904 bool wxWMP10MediaBackend::Load(const wxURI
& location
,
909 IWMPNetwork
* pWMPNetwork
;
910 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
913 if( pWMPNetwork
->getProxySettings(
914 wxBasicString(location
.GetScheme()).Get(), &lOldSetting
917 pWMPNetwork
->setProxySettings(
918 wxBasicString(location
.GetScheme()).Get(), // protocol
919 2) == 0) // 2 == manually specify
921 BSTR bsOldName
= NULL
;
924 pWMPNetwork
->getProxyName(
925 wxBasicString(location
.GetScheme()).Get(),
927 pWMPNetwork
->getProxyPort(
928 wxBasicString(location
.GetScheme()).Get(),
933 if(proxy
.IsReference())
935 server
= proxy
.GetScheme();
936 lPort
= wxAtoi(proxy
.GetPath());
940 server
= proxy
.GetServer();
941 lPort
= wxAtoi(proxy
.GetPort());
944 if( pWMPNetwork
->setProxyName(
945 wxBasicString(location
.GetScheme()).Get(), // proto
946 wxBasicString(server
).Get() ) == 0 &&
948 pWMPNetwork
->setProxyPort(
949 wxBasicString(location
.GetScheme()).Get(), // proto
954 bOK
= DoLoad(location
.BuildURI());
956 pWMPNetwork
->setProxySettings(
957 wxBasicString(location
.GetScheme()).Get(), // protocol
960 pWMPNetwork
->setProxyName(
961 wxBasicString(location
.GetScheme()).Get(), // protocol
965 pWMPNetwork
->setProxyPort(
966 wxBasicString(location
.GetScheme()).Get(), // protocol
969 pWMPNetwork
->Release();
972 pWMPNetwork
->Release();
976 pWMPNetwork
->Release();
983 //---------------------------------------------------------------------------
984 // wxWMP10MediaBackend::DoLoad
986 // Called by all functions - this actually renders
987 // the file and sets up the filter graph
988 //---------------------------------------------------------------------------
989 bool wxWMP10MediaBackend::DoLoad(const wxString
& location
)
993 #if 0 // See the "introduction" - this is the duration hack
994 // ------------------ BLATENT HACK ALERT -------------------------
995 // Normally we can only get the duration of things already in an
996 // existing playlist or playing - however this clever "workaround"
997 // enables us to get the duration even when stopped :)
998 // http://weblogs.asp.net/rweigelt/archive/2003/07/02/9613.aspx
1000 IWMPCore3
* pWMPCore3
;
1002 if(m_pWMPPlayer
->QueryInterface(IID_IWMPCore3
, (void**) &pWMPCore3
) == 0)
1004 IWMPMedia
* pWMPMedia
;
1006 if( (hr
= pWMPCore3
->newMedia(wxBasicString(location
).Get(),
1009 // this (get_duration) will actually FAIL, but it will work.
1010 pWMPMedia
->get_duration(&outDuration
);
1011 pWMPCore3
->put_currentMedia(pWMPMedia
);
1012 pWMPMedia
->Release();
1015 pWMPCore3
->Release();
1020 // just load it the "normal" way
1021 hr
= m_pWMPPlayer
->put_URL( wxBasicString(location
).Get() );
1033 //---------------------------------------------------------------------------
1034 // wxWMP10MediaBackend::FinishLoad
1036 // Called when our media is about to play (a.k.a. wmposMediaOpen)
1037 //---------------------------------------------------------------------------
1038 void wxWMP10MediaBackend::FinishLoad()
1040 // Get the original video size
1041 // THIS WILL NOT WORK UNLESS THE MEDIA IS ABOUT TO PLAY
1042 // See the "introduction" - also get_currentMedia will return
1043 // "1" which is a VALID HRESULT value
1044 // and a NULL pWMPMedia if the media isn't the "current" one
1045 // which is rather unintuitive in the sense that it uses it
1046 // (i.e. basically not currently playing)...
1047 IWMPMedia
* pWMPMedia
;
1048 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1050 pWMPMedia
->get_imageSourceWidth((long*)&m_bestSize
.x
);
1051 pWMPMedia
->get_imageSourceHeight((long*)&m_bestSize
.y
);
1052 pWMPMedia
->Release();
1056 wxLogDebug(wxT("Could not get media"));
1059 NotifyMovieLoaded();
1062 //---------------------------------------------------------------------------
1063 // wxWMP10MediaBackend::ShowPlayerControls
1064 //---------------------------------------------------------------------------
1065 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
1069 m_pWMPPlayer
->put_enabled(VARIANT_FALSE
);
1070 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("none")).Get());
1074 // TODO: use "custom"? (note that CE only supports none/full)
1075 m_pWMPPlayer
->put_uiMode(wxBasicString(wxT("full")).Get());
1076 m_pWMPPlayer
->put_enabled(VARIANT_TRUE
);
1082 //---------------------------------------------------------------------------
1083 // wxWMP10MediaBackend::Play
1085 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1087 // TODO: We use SUCCEEDED due to pickiness on IMediaPlayer are doing it here
1088 // but do we need to?
1089 //---------------------------------------------------------------------------
1090 bool wxWMP10MediaBackend::Play()
1092 // Actually try to play the movie (will fail if not loaded completely)
1093 HRESULT hr
= m_pWMPControls
->play();
1096 m_bWasStateChanged
= true;
1103 //---------------------------------------------------------------------------
1104 // wxWMP10MediaBackend::Pause
1106 // Pauses the stream.
1107 //---------------------------------------------------------------------------
1108 bool wxWMP10MediaBackend::Pause()
1110 HRESULT hr
= m_pWMPControls
->pause();
1113 m_bWasStateChanged
= true;
1120 //---------------------------------------------------------------------------
1121 // wxWMP10MediaBackend::Stop
1123 // Stops the stream.
1124 //---------------------------------------------------------------------------
1125 bool wxWMP10MediaBackend::Stop()
1127 HRESULT hr
= m_pWMPControls
->stop();
1130 // Seek to beginning
1131 wxWMP10MediaBackend::SetPosition(0);
1132 m_bWasStateChanged
= true;
1139 //---------------------------------------------------------------------------
1140 // wxWMP10MediaBackend::SetPosition
1142 // WMP10 position values are a double in seconds - we just translate
1144 //---------------------------------------------------------------------------
1145 bool wxWMP10MediaBackend::SetPosition(wxLongLong where
)
1147 HRESULT hr
= m_pWMPControls
->put_currentPosition(
1148 ((LONGLONG
)where
.GetValue()) / 1000.0
1159 //---------------------------------------------------------------------------
1160 // wxWMP10MediaBackend::GetPosition
1162 // WMP10 position values are a double in seconds - we just translate
1164 //---------------------------------------------------------------------------
1165 wxLongLong
wxWMP10MediaBackend::GetPosition()
1168 HRESULT hr
= m_pWMPControls
->get_currentPosition(&outCur
);
1175 // h,m,s,milli - outCur is in 1 second (double)
1183 //---------------------------------------------------------------------------
1184 // wxWMP10MediaBackend::GetVolume
1187 //---------------------------------------------------------------------------
1188 double wxWMP10MediaBackend::GetVolume()
1191 HRESULT hr
= m_pWMPSettings
->get_volume(&lVolume
);
1198 return (double)lVolume
/ 100.0;
1201 //---------------------------------------------------------------------------
1202 // wxWMP10MediaBackend::SetVolume
1205 //---------------------------------------------------------------------------
1206 bool wxWMP10MediaBackend::SetVolume(double dVolume
)
1208 HRESULT hr
= m_pWMPSettings
->put_volume( (long) (dVolume
* 100.0) );
1217 //---------------------------------------------------------------------------
1218 // wxWMP10MediaBackend::GetDuration
1220 // Obtains the duration of the media.
1222 // See the "introduction"
1224 // The good news is that this doesn't appear to have the XING header
1225 // parser problem that WMP6 SDK/IActiveMovie/IMediaPlayer/IWMP has
1226 //---------------------------------------------------------------------------
1227 wxLongLong
wxWMP10MediaBackend::GetDuration()
1229 double outDuration
= 0.0;
1231 IWMPMedia
* pWMPMedia
;
1232 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1234 if(pWMPMedia
->get_duration(&outDuration
) != 0)
1236 wxLogDebug(wxT("get_duration failed"));
1238 pWMPMedia
->Release();
1242 // h,m,s,milli - outDuration is in 1 second (double)
1243 outDuration
*= 1000;
1245 ll
.Assign(outDuration
);
1250 //---------------------------------------------------------------------------
1251 // wxWMP10MediaBackend::GetState
1253 // Returns the current state
1254 //---------------------------------------------------------------------------
1255 wxMediaState
wxWMP10MediaBackend::GetState()
1257 WMPPlayState nState
;
1258 HRESULT hr
= m_pWMPPlayer
->get_playState(&nState
);
1262 return wxMEDIASTATE_STOPPED
;
1268 return wxMEDIASTATE_PAUSED
;
1270 return wxMEDIASTATE_PLAYING
;
1272 return wxMEDIASTATE_STOPPED
;
1276 //---------------------------------------------------------------------------
1277 // wxWMP10MediaBackend::GetPlaybackRate
1279 // Just get the rate from WMP10
1280 //---------------------------------------------------------------------------
1281 double wxWMP10MediaBackend::GetPlaybackRate()
1284 HRESULT hr
= m_pWMPSettings
->get_rate(&dRate
);
1293 //---------------------------------------------------------------------------
1294 // wxWMP10MediaBackend::SetPlaybackRate
1296 // Sets the playback rate of the media - DirectShow is pretty good
1297 // about this, actually
1298 //---------------------------------------------------------------------------
1299 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate
)
1301 HRESULT hr
= m_pWMPSettings
->put_rate(dRate
);
1311 //---------------------------------------------------------------------------
1312 // wxWMP10MediaBackend::GetVideoSize
1314 // Obtains the cached original video size
1315 //---------------------------------------------------------------------------
1316 wxSize
wxWMP10MediaBackend::GetVideoSize() const
1321 //---------------------------------------------------------------------------
1322 // wxWMP10MediaBackend::Move
1324 // We take care of this in our redrawing
1325 //---------------------------------------------------------------------------
1326 void wxWMP10MediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
),
1330 int WXUNUSED(w
), int WXUNUSED(h
)
1335 m_wndView
.MoveWindow(0,0,w
,h
);
1339 //---------------------------------------------------------------------------
1340 // wxWMP10MediaBackend::GetDownloadProgress()
1341 //---------------------------------------------------------------------------
1342 wxLongLong
wxWMP10MediaBackend::GetDownloadProgress()
1344 IWMPNetwork
* pWMPNetwork
;
1345 if( m_pWMPPlayer
->get_network(&pWMPNetwork
) == 0 )
1348 if(pWMPNetwork
->get_downloadProgress(&lPercentProg
) == 0)
1350 pWMPNetwork
->Release();
1351 return (GetDownloadTotal() * lPercentProg
) / 100;
1353 pWMPNetwork
->Release();
1358 //---------------------------------------------------------------------------
1359 // wxWMP10MediaBackend::GetDownloadTotal()
1360 //---------------------------------------------------------------------------
1361 wxLongLong
wxWMP10MediaBackend::GetDownloadTotal()
1363 IWMPMedia
* pWMPMedia
;
1364 if(m_pWMPPlayer
->get_currentMedia(&pWMPMedia
) == 0)
1367 pWMPMedia
->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
1370 wxString sFileSize
= wxConvertStringFromOle(bsOut
);
1372 sFileSize
.ToLong(&lFS
);
1373 pWMPMedia
->Release();
1381 //---------------------------------------------------------------------------
1382 // wxWMP10MediaBackend::OnActiveX
1384 // Handle events sent from our activex control (_WMPOCXEvents actually).
1386 // The weird numbers in the switch statement here are "dispatch ids"
1387 // (the numbers in the id field like ( id(xxx) ) ) from amcompat.idl
1389 //---------------------------------------------------------------------------
1391 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent
& event
)
1393 switch(event
.GetDispatchId())
1395 case 0x000013ed: // playstatechange
1396 if(event
.ParamCount() >= 1)
1398 switch (event
[0].GetInteger())
1400 case wmppsMediaEnded
: // media ended
1401 if ( m_amb
->SendStopEvent() )
1403 // NB: If we do Stop() or similar here the media
1404 // actually starts over and plays a bit before
1405 // stopping. It stops by default, however, so
1406 // there is no real need to do anything here...
1408 // send the event to our child
1409 m_amb
->QueueFinishEvent();
1413 case wmppsStopped
: // stopping
1414 m_amb
->QueueStopEvent();
1416 case wmppsPaused
: // pause
1417 m_amb
->QueuePauseEvent();
1419 case wmppsPlaying
: // play
1420 m_amb
->QueuePlayEvent();
1430 case 0x00001389: // openstatechange
1431 if(event
.ParamCount() >= 1)
1433 int nState
= event
[0].GetInteger();
1434 if(nState
== wmposMediaOpen
)
1436 // See the "introduction"
1437 m_amb
->m_bWasStateChanged
= false;
1438 m_amb
->FinishLoad();
1439 if(!m_amb
->m_bWasStateChanged
)
1447 case 0x0000196e: // mousedown
1448 m_amb
->m_ctrl
->SetFocus();
1459 // Allow the user code to use wxFORCE_LINK_MODULE() to ensure that this object
1460 // file is not discarded by the linker.
1461 #include "wx/link.h"
1462 wxFORCE_LINK_THIS_MODULE(wxmediabackend_wmp10
)
1464 #if 0 // Windows Media Player Mobile 9 hacks
1466 //------------------WMP Mobile 9 hacks-----------------------------------
1467 // It was mentioned in the introduction that while there was no official
1468 // programming interface on WMP mobile 9
1469 // (SmartPhone/Pocket PC 2003 emulator etc.)
1470 // there were some windows message hacks that are able to get
1471 // you playing a file through WMP.
1473 // Here are those hacks. They do indeed "work" as expected - just call
1474 // SendMessage with one of those myterious values laid out in
1475 // Peter Foot's Friday, May 21, 2004 Blog Post on the issue.
1476 // (He says they are in a registery section entitled "Pendant Bus")
1478 // How do you play a certain file? Simply calling "start [file]" or
1479 // wxWinCEExecute([file]) should do the trick
1481 bool wxWinCEExecute(const wxString
& path
, int nShowStyle
= SW_SHOWNORMAL
)
1483 WinStruct
<SHELLEXECUTEINFO
> sei
;
1484 sei
.lpFile
= path
.c_str();
1485 sei
.lpVerb
= wxT("open");
1486 sei
.nShow
= nShowStyle
;
1488 ::ShellExecuteEx(&sei
);
1490 return ((int) sei
.hInstApp
) > 32;
1493 bool MyApp::OnInit()
1495 HWND hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1498 if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE
) )
1500 hwnd
= ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1507 ::SetWindowPos(hwnd
, HWND_BOTTOM
, 0, 0, 0, 0,
1508 SWP_NOMOVE
|SWP_NOSIZE
|SWP_HIDEWINDOW
);
1511 // Prev Track == 32971
1512 // Next Track == 32972
1516 // Vol Down == 32976
1518 ::SendMessage(hwnd
, 32978, NULL
, 0);
1522 #endif // WMP mobile 9 hacks
1524 #endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX