]> git.saurik.com Git - wxWidgets.git/blob - src/msw/mediactrl_wmp10.cpp
Upgrade bundled zlib to 1.2.8.
[wxWidgets.git] / src / msw / mediactrl_wmp10.cpp
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>
5 // Modified by:
6 // Created: 11/07/04
7 // Copyright: (c) Ryan Norton
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
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).
16 //
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.
25 //
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.
29 //
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.
33 //
34 // The docs are at
35 // http://msdn.microsoft.com/library/en-us/wmplay10/mmp_sdk/windowsmediaplayer10sdk.asp
36
37 //===========================================================================
38 // DECLARATIONS
39 //===========================================================================
40
41 //---------------------------------------------------------------------------
42 // Pre-compiled header stuff
43 //---------------------------------------------------------------------------
44
45 // For compilers that support precompilation, includes "wx.h".
46 #include "wx/wxprec.h"
47
48 #ifdef __BORLANDC__
49 #pragma hdrstop
50 #endif
51
52 #if wxUSE_MEDIACTRL && wxUSE_ACTIVEX
53
54 #include "wx/mediactrl.h"
55
56 #ifndef WX_PRECOMP
57 #include "wx/log.h"
58 #endif
59
60 #include "wx/msw/private.h" // user info and wndproc setting/getting
61 #include "wx/msw/ole/activex.h" // wxActiveXContainer - COM-specific stuff
62
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 //---------------------------------------------------------------------------
68 #if 0
69 #define WXTEST_ATL
70 #endif
71
72 #ifdef WXTEST_ATL
73 #include <atlbase.h>
74 CComModule _Module;
75 #define min(x,y) (x < y ? x : y)
76 #include <atlcom.h>
77 #include <atlhost.h>
78 #include <atlctl.h>
79 #endif
80
81 //---------------------------------------------------------------------------
82 // Other defines
83 //---------------------------------------------------------------------------
84
85 // disable "cast truncates constant value" for VARIANT_BOOL values
86 // passed as parameters in VC6
87 #ifdef _MSC_VER
88 #pragma warning (disable:4310)
89 #endif
90
91 // error logger for HRESULTS (nothing really now)
92 #define wxWMP10LOG(x)
93
94 //---------------------------------------------------------------------------
95 // Various definitions dumped from wmp.IDL
96 //---------------------------------------------------------------------------
97
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}};
101
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}};
104 #ifndef WXTEST_ATL
105 const IID IID_IWMPPlayer = {0x6BF52A4F,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
106 #endif
107
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}};
114
115 enum WMPOpenState
116 {
117 wmposUndefined = 0,
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,
130 wmposMediaOpen = 13,
131 wmposBeginCodecAcquisition = 14,
132 wmposEndCodecAcquisition = 15,
133 wmposBeginLicenseAcquisition = 16,
134 wmposEndLicenseAcquisition = 17,
135 wmposBeginIndividualization = 18,
136 wmposEndIndividualization = 19,
137 wmposMediaWaiting = 20,
138 wmposOpeningUnknownURL = 21
139 };
140
141 enum WMPPlayState
142 {
143 wmppsUndefined = 0,
144 wmppsStopped = 1,
145 wmppsPaused = 2,
146 wmppsPlaying = 3,
147 wmppsScanForward = 4,
148 wmppsScanReverse = 5,
149 wmppsBuffering = 6,
150 wmppsWaiting = 7,
151 wmppsMediaEnded = 8,
152 wmppsTransitioning = 9,
153 wmppsReady = 10,
154 wmppsReconnecting = 11,
155 wmppsLast = 12
156 };
157
158
159 struct IWMPMedia : public IDispatch
160 {
161 public:
162 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isIdentical(
163 /* [in] */ IWMPMedia __RPC_FAR *pIWMPMedia,
164 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvbool) = 0;
165
166 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_sourceURL(
167 /* [retval][out] */ BSTR __RPC_FAR *pbstrSourceURL) = 0;
168
169 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_name(
170 /* [retval][out] */ BSTR __RPC_FAR *pbstrName) = 0;
171
172 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_name(
173 /* [in] */ BSTR pbstrName) = 0;
174
175 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_imageSourceWidth(
176 /* [retval][out] */ long __RPC_FAR *pWidth) = 0;
177
178 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_imageSourceHeight(
179 /* [retval][out] */ long __RPC_FAR *pHeight) = 0;
180
181 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_markerCount(
182 /* [retval][out] */ long __RPC_FAR *pMarkerCount) = 0;
183
184 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMarkerTime(
185 /* [in] */ long MarkerNum,
186 /* [retval][out] */ double __RPC_FAR *pMarkerTime) = 0;
187
188 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMarkerName(
189 /* [in] */ long MarkerNum,
190 /* [retval][out] */ BSTR __RPC_FAR *pbstrMarkerName) = 0;
191
192 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_duration(
193 /* [retval][out] */ double __RPC_FAR *pDuration) = 0;
194
195 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_durationString(
196 /* [retval][out] */ BSTR __RPC_FAR *pbstrDuration) = 0;
197
198 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_attributeCount(
199 /* [retval][out] */ long __RPC_FAR *plCount) = 0;
200
201 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getAttributeName(
202 /* [in] */ long lIndex,
203 /* [retval][out] */ BSTR __RPC_FAR *pbstrItemName) = 0;
204
205 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getItemInfo(
206 /* [in] */ BSTR bstrItemName,
207 /* [retval][out] */ BSTR __RPC_FAR *pbstrVal) = 0;
208
209 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setItemInfo(
210 /* [in] */ BSTR bstrItemName,
211 /* [in] */ BSTR bstrVal) = 0;
212
213 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getItemInfoByAtom(
214 /* [in] */ long lAtom,
215 /* [retval][out] */ BSTR __RPC_FAR *pbstrVal) = 0;
216
217 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE isMemberOf(
218 /* [in] */ IUnknown __RPC_FAR *pPlaylist,
219 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfIsMemberOf) = 0;
220
221 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE isReadOnlyItem(
222 /* [in] */ BSTR bstrItemName,
223 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfIsReadOnly) = 0;
224
225 };
226
227 struct IWMPControls : public IDispatch
228 {
229 public:
230 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isAvailable(
231 /* [in] */ BSTR bstrItem,
232 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pIsAvailable) = 0;
233
234 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE play( void) = 0;
235
236 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE stop( void) = 0;
237
238 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE pause( void) = 0;
239
240 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE fastForward( void) = 0;
241
242 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE fastReverse( void) = 0;
243
244 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPosition(
245 /* [retval][out] */ double __RPC_FAR *pdCurrentPosition) = 0;
246
247 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentPosition(
248 /* [in] */ double pdCurrentPosition) = 0;
249
250 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPositionString(
251 /* [retval][out] */ BSTR __RPC_FAR *pbstrCurrentPosition) = 0;
252
253 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE next( void) = 0;
254
255 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE previous( void) = 0;
256
257 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentItem(
258 /* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppIWMPMedia) = 0;
259
260 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentItem(
261 /* [in] */ IWMPMedia __RPC_FAR *ppIWMPMedia) = 0;
262
263 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentMarker(
264 /* [retval][out] */ long __RPC_FAR *plMarker) = 0;
265
266 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentMarker(
267 /* [in] */ long plMarker) = 0;
268
269 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE playItem(
270 /* [in] */ IWMPMedia __RPC_FAR *pIWMPMedia) = 0;
271
272 };
273
274
275 struct IWMPSettings : public IDispatch
276 {
277 public:
278 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isAvailable(
279 /* [in] */ BSTR bstrItem,
280 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pIsAvailable) = 0;
281
282 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_autoStart(
283 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfAutoStart) = 0;
284
285 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_autoStart(
286 /* [in] */ VARIANT_BOOL pfAutoStart) = 0;
287
288 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_baseURL(
289 /* [retval][out] */ BSTR __RPC_FAR *pbstrBaseURL) = 0;
290
291 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_baseURL(
292 /* [in] */ BSTR pbstrBaseURL) = 0;
293
294 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_defaultFrame(
295 /* [retval][out] */ BSTR __RPC_FAR *pbstrDefaultFrame) = 0;
296
297 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_defaultFrame(
298 /* [in] */ BSTR pbstrDefaultFrame) = 0;
299
300 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_invokeURLs(
301 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfInvokeURLs) = 0;
302
303 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_invokeURLs(
304 /* [in] */ VARIANT_BOOL pfInvokeURLs) = 0;
305
306 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_mute(
307 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfMute) = 0;
308
309 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_mute(
310 /* [in] */ VARIANT_BOOL pfMute) = 0;
311
312 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playCount(
313 /* [retval][out] */ long __RPC_FAR *plCount) = 0;
314
315 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_playCount(
316 /* [in] */ long plCount) = 0;
317
318 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_rate(
319 /* [retval][out] */ double __RPC_FAR *pdRate) = 0;
320
321 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_rate(
322 /* [in] */ double pdRate) = 0;
323
324 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_balance(
325 /* [retval][out] */ long __RPC_FAR *plBalance) = 0;
326
327 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_balance(
328 /* [in] */ long plBalance) = 0;
329
330 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_volume(
331 /* [retval][out] */ long __RPC_FAR *plVolume) = 0;
332
333 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_volume(
334 /* [in] */ long plVolume) = 0;
335
336 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMode(
337 /* [in] */ BSTR bstrMode,
338 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pvarfMode) = 0;
339
340 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setMode(
341 /* [in] */ BSTR bstrMode,
342 /* [in] */ VARIANT_BOOL varfMode) = 0;
343
344 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableErrorDialogs(
345 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfEnableErrorDialogs) = 0;
346
347 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableErrorDialogs(
348 /* [in] */ VARIANT_BOOL pfEnableErrorDialogs) = 0;
349
350 };
351
352 struct IWMPNetwork : public IDispatch
353 {
354 public:
355 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bandWidth(
356 /* [retval][out] */ long __RPC_FAR *plBandwidth) = 0;
357
358 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_recoveredPackets(
359 /* [retval][out] */ long __RPC_FAR *plRecoveredPackets) = 0;
360
361 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_sourceProtocol(
362 /* [retval][out] */ BSTR __RPC_FAR *pbstrSourceProtocol) = 0;
363
364 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_receivedPackets(
365 /* [retval][out] */ long __RPC_FAR *plReceivedPackets) = 0;
366
367 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_lostPackets(
368 /* [retval][out] */ long __RPC_FAR *plLostPackets) = 0;
369
370 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_receptionQuality(
371 /* [retval][out] */ long __RPC_FAR *plReceptionQuality) = 0;
372
373 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingCount(
374 /* [retval][out] */ long __RPC_FAR *plBufferingCount) = 0;
375
376 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingProgress(
377 /* [retval][out] */ long __RPC_FAR *plBufferingProgress) = 0;
378
379 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bufferingTime(
380 /* [retval][out] */ long __RPC_FAR *plBufferingTime) = 0;
381
382 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_bufferingTime(
383 /* [in] */ long plBufferingTime) = 0;
384
385 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_frameRate(
386 /* [retval][out] */ long __RPC_FAR *plFrameRate) = 0;
387
388 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_maxBitRate(
389 /* [retval][out] */ long __RPC_FAR *plBitRate) = 0;
390
391 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_bitRate(
392 /* [retval][out] */ long __RPC_FAR *plBitRate) = 0;
393
394 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxySettings(
395 /* [in] */ BSTR bstrProtocol,
396 /* [retval][out] */ long __RPC_FAR *plProxySetting) = 0;
397
398 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxySettings(
399 /* [in] */ BSTR bstrProtocol,
400 /* [in] */ long lProxySetting) = 0;
401
402 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyName(
403 /* [in] */ BSTR bstrProtocol,
404 /* [retval][out] */ BSTR __RPC_FAR *pbstrProxyName) = 0;
405
406 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyName(
407 /* [in] */ BSTR bstrProtocol,
408 /* [in] */ BSTR bstrProxyName) = 0;
409
410 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyPort(
411 /* [in] */ BSTR bstrProtocol,
412 /* [retval][out] */ long __RPC_FAR *lProxyPort) = 0;
413
414 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyPort(
415 /* [in] */ BSTR bstrProtocol,
416 /* [in] */ long lProxyPort) = 0;
417
418 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyExceptionList(
419 /* [in] */ BSTR bstrProtocol,
420 /* [retval][out] */ BSTR __RPC_FAR *pbstrExceptionList) = 0;
421
422 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyExceptionList(
423 /* [in] */ BSTR bstrProtocol,
424 /* [in] */ BSTR pbstrExceptionList) = 0;
425
426 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getProxyBypassForLocal(
427 /* [in] */ BSTR bstrProtocol,
428 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfBypassForLocal) = 0;
429
430 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setProxyBypassForLocal(
431 /* [in] */ BSTR bstrProtocol,
432 /* [in] */ VARIANT_BOOL fBypassForLocal) = 0;
433
434 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_maxBandwidth(
435 /* [retval][out] */ long __RPC_FAR *lMaxBandwidth) = 0;
436
437 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_maxBandwidth(
438 /* [in] */ long lMaxBandwidth) = 0;
439
440 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_downloadProgress(
441 /* [retval][out] */ long __RPC_FAR *plDownloadProgress) = 0;
442
443 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_encodedFrameRate(
444 /* [retval][out] */ long __RPC_FAR *plFrameRate) = 0;
445
446 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_framesSkipped(
447 /* [retval][out] */ long __RPC_FAR *plFrames) = 0;
448
449 };
450
451 struct IWMPCore : public IDispatch
452 {
453 public:
454 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE close( void) = 0;
455
456 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_URL(
457 /* [retval][out] */ BSTR __RPC_FAR *pbstrURL) = 0;
458
459 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_URL(
460 /* [in] */ BSTR pbstrURL) = 0;
461
462 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_openState(
463 /* [retval][out] */ WMPOpenState __RPC_FAR *pwmpos) = 0;
464
465 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playState(
466 /* [retval][out] */ WMPPlayState __RPC_FAR *pwmpps) = 0;
467
468 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_controls(
469 /* [retval][out] */ IWMPControls __RPC_FAR *__RPC_FAR *ppControl) = 0;
470
471 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_settings(
472 /* [retval][out] */ IWMPSettings __RPC_FAR *__RPC_FAR *ppSettings) = 0;
473
474 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentMedia(
475 /* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppMedia) = 0;
476
477 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentMedia(
478 /* [in] */ IUnknown __RPC_FAR *ppMedia) = 0;
479
480 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_mediaCollection(
481 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppMediaCollection) = 0;
482
483 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_playlistCollection(
484 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppPlaylistCollection) = 0;
485
486 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_versionInfo(
487 /* [retval][out] */ BSTR __RPC_FAR *pbstrVersionInfo) = 0;
488
489 virtual /* [id] */ HRESULT STDMETHODCALLTYPE launchURL(
490 /* [in] */ BSTR bstrURL) = 0;
491
492 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_network(
493 /* [retval][out] */ IWMPNetwork __RPC_FAR *__RPC_FAR *ppQNI) = 0;
494
495 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_currentPlaylist(
496 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppPL) = 0;
497
498 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_currentPlaylist(
499 /* [in] */ IUnknown __RPC_FAR *ppPL) = 0;
500
501 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_cdromCollection(
502 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppCdromCollection) = 0;
503
504 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_closedCaption(
505 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppClosedCaption) = 0;
506
507 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_isOnline(
508 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pfOnline) = 0;
509
510 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Error(
511 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppError) = 0;
512
513 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_status(
514 /* [retval][out] */ BSTR __RPC_FAR *pbstrStatus) = 0;
515
516 };
517
518 struct IWMPCore2 : public IWMPCore
519 {
520 public:
521 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_dvd(
522 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppDVD) = 0;
523
524 };
525
526 struct IWMPCore3 : public IWMPCore2
527 {
528 public:
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;
533
534 virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE newMedia(
535 /* [in] */ BSTR bstrURL,
536 /* [retval][out] */ IWMPMedia __RPC_FAR *__RPC_FAR *ppMedia) = 0;
537
538 };
539
540 #ifdef WXTEST_ATL
541 MIDL_INTERFACE("6BF52A4F-394A-11D3-B153-00C04F79FAA6")
542 #else
543 struct
544 #endif
545 IWMPPlayer : public IWMPCore
546 {
547 public:
548 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enabled(
549 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
550
551 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enabled(
552 /* [in] */ VARIANT_BOOL pbEnabled) = 0;
553
554 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_fullScreen(
555 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbFullScreen) = 0;
556
557 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_fullScreen(
558 VARIANT_BOOL pbFullScreen) = 0;
559
560 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableContextMenu(
561 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnableContextMenu) = 0;
562
563 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableContextMenu(
564 VARIANT_BOOL pbEnableContextMenu) = 0;
565
566 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_uiMode(
567 /* [in] */ BSTR pbstrMode) = 0;
568
569 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_uiMode(
570 /* [retval][out] */ BSTR __RPC_FAR *pbstrMode) = 0;
571 };
572
573 struct IWMPPlayer2 : public IWMPCore
574 {
575 public:
576 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enabled(
577 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
578
579 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enabled(
580 /* [in] */ VARIANT_BOOL pbEnabled) = 0;
581
582 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_fullScreen(
583 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbFullScreen) = 0;
584
585 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_fullScreen(
586 VARIANT_BOOL pbFullScreen) = 0;
587
588 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_enableContextMenu(
589 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnableContextMenu) = 0;
590
591 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_enableContextMenu(
592 VARIANT_BOOL pbEnableContextMenu) = 0;
593
594 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_uiMode(
595 /* [in] */ BSTR pbstrMode) = 0;
596
597 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_uiMode(
598 /* [retval][out] */ BSTR __RPC_FAR *pbstrMode) = 0;
599
600 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_stretchToFit(
601 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
602
603 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_stretchToFit(
604 /* [in] */ VARIANT_BOOL pbEnabled) = 0;
605
606 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_windowlessVideo(
607 /* [retval][out] */ VARIANT_BOOL __RPC_FAR *pbEnabled) = 0;
608
609 virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_windowlessVideo(
610 /* [in] */ VARIANT_BOOL pbEnabled) = 0;
611
612 };
613
614 //---------------------------------------------------------------------------
615 //
616 // wxWMP10MediaBackend
617 //
618 //---------------------------------------------------------------------------
619
620 class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend : public wxMediaBackendCommonBase
621 {
622 public:
623 wxWMP10MediaBackend();
624 virtual ~wxWMP10MediaBackend();
625
626 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
627 wxWindowID id,
628 const wxPoint& pos,
629 const wxSize& size,
630 long style,
631 const wxValidator& validator,
632 const wxString& name);
633
634 virtual bool Play();
635 virtual bool Pause();
636 virtual bool Stop();
637
638 virtual bool Load(const wxString& fileName);
639 virtual bool Load(const wxURI& location);
640 virtual bool Load(const wxURI& location, const wxURI& proxy);
641
642 bool DoLoad(const wxString& location);
643 void FinishLoad();
644
645 virtual wxMediaState GetState();
646
647 virtual bool SetPosition(wxLongLong where);
648 virtual wxLongLong GetPosition();
649 virtual wxLongLong GetDuration();
650
651 virtual void Move(int x, int y, int w, int h);
652 wxSize GetVideoSize() const;
653
654 virtual double GetPlaybackRate();
655 virtual bool SetPlaybackRate(double);
656
657 virtual double GetVolume();
658 virtual bool SetVolume(double);
659
660 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
661
662 virtual wxLongLong GetDownloadProgress();
663 virtual wxLongLong GetDownloadTotal();
664
665
666 #ifdef WXTEST_ATL
667 CAxWindow m_wndView;
668 #else
669 wxActiveXContainer* m_pAX;
670 #endif
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
675
676 bool m_bWasStateChanged; // See the "introduction"
677 wxEvtHandler* m_evthandler;
678
679 friend class wxWMP10MediaEvtHandler;
680 DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend)
681 };
682
683 #ifndef WXTEST_ATL
684 class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler : public wxEvtHandler
685 {
686 public:
687 wxWMP10MediaEvtHandler(wxWMP10MediaBackend *amb) :
688 m_amb(amb)
689 {
690 m_amb->m_pAX->Connect(m_amb->m_pAX->GetId(),
691 wxEVT_ACTIVEX,
692 wxActiveXEventHandler(wxWMP10MediaEvtHandler::OnActiveX),
693 NULL, this
694 );
695 }
696
697 void OnActiveX(wxActiveXEvent& event);
698
699 private:
700 wxWMP10MediaBackend *m_amb;
701
702 wxDECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler);
703 };
704 #endif
705
706 //===========================================================================
707 // IMPLEMENTATION
708 //===========================================================================
709
710 //---------------------------------------------------------------------------
711 //
712 // wxWMP10MediaBackend
713 //
714 //---------------------------------------------------------------------------
715
716 IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend, wxMediaBackend)
717
718 //---------------------------------------------------------------------------
719 // wxWMP10MediaBackend Constructor
720 //---------------------------------------------------------------------------
721 wxWMP10MediaBackend::wxWMP10MediaBackend()
722 :
723 #ifndef WXTEST_ATL
724 m_pAX(NULL),
725 #endif
726 m_pWMPPlayer(NULL),
727 m_pWMPSettings(NULL),
728 m_pWMPControls(NULL)
729
730 {
731 m_evthandler = NULL;
732 }
733
734 //---------------------------------------------------------------------------
735 // wxWMP10MediaBackend Destructor
736 //---------------------------------------------------------------------------
737 wxWMP10MediaBackend::~wxWMP10MediaBackend()
738 {
739 if(m_pWMPPlayer)
740 {
741 #ifndef WXTEST_ATL
742 m_pAX->DissociateHandle();
743 delete m_pAX;
744
745 if (m_evthandler)
746 {
747 m_ctrl->RemoveEventHandler(m_evthandler);
748 delete m_evthandler;
749 }
750 #else
751 AtlAxWinTerm();
752 _Module.Term();
753 #endif
754
755 m_pWMPPlayer->Release();
756 if (m_pWMPSettings)
757 m_pWMPSettings->Release();
758 if (m_pWMPControls)
759 m_pWMPControls->Release();
760 }
761 }
762
763 //---------------------------------------------------------------------------
764 // wxWMP10MediaBackend::CreateControl
765 //---------------------------------------------------------------------------
766 bool wxWMP10MediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
767 wxWindowID id,
768 const wxPoint& pos,
769 const wxSize& size,
770 long style,
771 const wxValidator& validator,
772 const wxString& name)
773 {
774 #ifndef WXTEST_ATL
775 if( ::CoCreateInstance(CLSID_WMP10, NULL,
776 CLSCTX_INPROC_SERVER,
777 IID_IWMPPlayer, (void**)&m_pWMPPlayer) != 0 )
778 {
779 if( ::CoCreateInstance(CLSID_WMP10ALT, NULL,
780 CLSCTX_INPROC_SERVER,
781 IID_IWMPPlayer, (void**)&m_pWMPPlayer) != 0 )
782 return false;
783
784 if( m_pWMPPlayer->get_settings(&m_pWMPSettings) != 0)
785 {
786 m_pWMPPlayer->Release();
787 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
788 return false;
789 }
790
791 if( m_pWMPPlayer->get_controls(&m_pWMPControls) != 0)
792 {
793 m_pWMPSettings->Release();
794 m_pWMPPlayer->Release();
795 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
796 return false;
797 }
798 }
799 #endif
800
801 //
802 // Create window
803 // By default wxWindow(s) is created with a border -
804 // so we need to get rid of those
805 //
806 // Since we don't have a child window like most other
807 // backends, we don't need wxCLIP_CHILDREN
808 //
809 if ( !ctrl->wxControl::Create(parent, id, pos, size,
810 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
811 validator, name) )
812 return false;
813
814 //
815 // Now create the ActiveX container along with the media player
816 // interface and query them
817 //
818 m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
819
820 #ifndef WXTEST_ATL
821 m_pAX = new wxActiveXContainer(ctrl, IID_IWMPPlayer, m_pWMPPlayer);
822
823 // Connect for events
824 m_evthandler = new wxWMP10MediaEvtHandler(this);
825 m_ctrl->PushEventHandler(m_evthandler);
826 #else
827 _Module.Init(NULL, ::GetModuleHandle(NULL));
828 AtlAxWinInit();
829 CComPtr<IAxWinHostWindow> spHost;
830
831 HRESULT hr;
832 RECT rcClient;
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);
838
839 if( m_pWMPPlayer->get_settings(&m_pWMPSettings) != 0)
840 {
841 m_pWMPPlayer->Release();
842 wxLogSysError(wxT("Could not obtain settings from WMP10!"));
843 return false;
844 }
845
846 if( m_pWMPPlayer->get_controls(&m_pWMPControls) != 0)
847 {
848 m_pWMPSettings->Release();
849 m_pWMPPlayer->Release();
850 wxLogSysError(wxT("Could not obtain controls from WMP10!"));
851 return false;
852 }
853 #endif
854
855 //
856 // Here we set up wx-specific stuff for the default
857 // settings wxMediaCtrl says it will stay to
858 //
859
860 IWMPPlayer2* pWMPPlayer2; // Only 2 has windowless video and stretchtofit
861 if(m_pWMPPlayer->QueryInterface(IID_IWMPPlayer2, (void**)&pWMPPlayer2) == 0)
862 {
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();
868 }
869
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);
876
877 // don't erase the background of our control window so that resizing is a
878 // bit smoother
879 m_ctrl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
880
881 // success
882 return true;
883 }
884
885 //---------------------------------------------------------------------------
886 // wxWMP10MediaBackend::Load (file version)
887 //---------------------------------------------------------------------------
888 bool wxWMP10MediaBackend::Load(const wxString& fileName)
889 {
890 return DoLoad(fileName);
891 }
892
893 //---------------------------------------------------------------------------
894 // wxWMP10MediaBackend::Load (URL Version)
895 //---------------------------------------------------------------------------
896 bool wxWMP10MediaBackend::Load(const wxURI& location)
897 {
898 return DoLoad(location.BuildURI());
899 }
900
901 //---------------------------------------------------------------------------
902 // wxWMP10MediaBackend::Load (URL Version with Proxy)
903 //---------------------------------------------------------------------------
904 bool wxWMP10MediaBackend::Load(const wxURI& location,
905 const wxURI& proxy)
906 {
907 bool bOK = false;
908
909 IWMPNetwork* pWMPNetwork;
910 if( m_pWMPPlayer->get_network(&pWMPNetwork) == 0 )
911 {
912 long lOldSetting;
913 if( pWMPNetwork->getProxySettings(
914 wxBasicString(location.GetScheme()).Get(), &lOldSetting
915 ) == 0 &&
916
917 pWMPNetwork->setProxySettings(
918 wxBasicString(location.GetScheme()).Get(), // protocol
919 2) == 0) // 2 == manually specify
920 {
921 BSTR bsOldName = NULL;
922 long lOldPort = 0;
923
924 pWMPNetwork->getProxyName(
925 wxBasicString(location.GetScheme()).Get(),
926 &bsOldName);
927 pWMPNetwork->getProxyPort(
928 wxBasicString(location.GetScheme()).Get(),
929 &lOldPort);
930
931 long lPort;
932 wxString server;
933 if(proxy.IsReference())
934 {
935 server = proxy.GetScheme();
936 lPort = wxAtoi(proxy.GetPath());
937 }
938 else
939 {
940 server = proxy.GetServer();
941 lPort = wxAtoi(proxy.GetPort());
942 }
943
944 if( pWMPNetwork->setProxyName(
945 wxBasicString(location.GetScheme()).Get(), // proto
946 wxBasicString(server).Get() ) == 0 &&
947
948 pWMPNetwork->setProxyPort(
949 wxBasicString(location.GetScheme()).Get(), // proto
950 lPort
951 ) == 0
952 )
953 {
954 bOK = DoLoad(location.BuildURI());
955
956 pWMPNetwork->setProxySettings(
957 wxBasicString(location.GetScheme()).Get(), // protocol
958 lOldSetting);
959 if(bsOldName)
960 pWMPNetwork->setProxyName(
961 wxBasicString(location.GetScheme()).Get(), // protocol
962 bsOldName);
963
964 if(lOldPort)
965 pWMPNetwork->setProxyPort(
966 wxBasicString(location.GetScheme()).Get(), // protocol
967 lOldPort);
968
969 pWMPNetwork->Release();
970 }
971 else
972 pWMPNetwork->Release();
973
974 }
975 else
976 pWMPNetwork->Release();
977
978 }
979
980 return bOK;
981 }
982
983 //---------------------------------------------------------------------------
984 // wxWMP10MediaBackend::DoLoad
985 //
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)
990 {
991 HRESULT hr;
992
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
999
1000 IWMPCore3* pWMPCore3;
1001 double outDuration;
1002 if(m_pWMPPlayer->QueryInterface(IID_IWMPCore3, (void**) &pWMPCore3) == 0)
1003 {
1004 IWMPMedia* pWMPMedia;
1005
1006 if( (hr = pWMPCore3->newMedia(wxBasicString(location).Get(),
1007 &pWMPMedia)) == 0)
1008 {
1009 // this (get_duration) will actually FAIL, but it will work.
1010 pWMPMedia->get_duration(&outDuration);
1011 pWMPCore3->put_currentMedia(pWMPMedia);
1012 pWMPMedia->Release();
1013 }
1014
1015 pWMPCore3->Release();
1016 }
1017 else
1018 #endif
1019 {
1020 // just load it the "normal" way
1021 hr = m_pWMPPlayer->put_URL( wxBasicString(location).Get() );
1022 }
1023
1024 if(FAILED(hr))
1025 {
1026 wxWMP10LOG(hr);
1027 return false;
1028 }
1029
1030 return true;
1031 }
1032
1033 //---------------------------------------------------------------------------
1034 // wxWMP10MediaBackend::FinishLoad
1035 //
1036 // Called when our media is about to play (a.k.a. wmposMediaOpen)
1037 //---------------------------------------------------------------------------
1038 void wxWMP10MediaBackend::FinishLoad()
1039 {
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)
1049 {
1050 pWMPMedia->get_imageSourceWidth((long*)&m_bestSize.x);
1051 pWMPMedia->get_imageSourceHeight((long*)&m_bestSize.y);
1052 pWMPMedia->Release();
1053 }
1054 else
1055 {
1056 wxLogDebug(wxT("Could not get media"));
1057 }
1058
1059 NotifyMovieLoaded();
1060 }
1061
1062 //---------------------------------------------------------------------------
1063 // wxWMP10MediaBackend::ShowPlayerControls
1064 //---------------------------------------------------------------------------
1065 bool wxWMP10MediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
1066 {
1067 if(!flags)
1068 {
1069 m_pWMPPlayer->put_enabled(VARIANT_FALSE);
1070 m_pWMPPlayer->put_uiMode(wxBasicString(wxT("none")).Get());
1071 }
1072 else
1073 {
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);
1077 }
1078
1079 return true;
1080 }
1081
1082 //---------------------------------------------------------------------------
1083 // wxWMP10MediaBackend::Play
1084 //
1085 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1086 //
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()
1091 {
1092 // Actually try to play the movie (will fail if not loaded completely)
1093 HRESULT hr = m_pWMPControls->play();
1094 if(SUCCEEDED(hr))
1095 {
1096 m_bWasStateChanged = true;
1097 return true;
1098 }
1099 wxWMP10LOG(hr);
1100 return false;
1101 }
1102
1103 //---------------------------------------------------------------------------
1104 // wxWMP10MediaBackend::Pause
1105 //
1106 // Pauses the stream.
1107 //---------------------------------------------------------------------------
1108 bool wxWMP10MediaBackend::Pause()
1109 {
1110 HRESULT hr = m_pWMPControls->pause();
1111 if(SUCCEEDED(hr))
1112 {
1113 m_bWasStateChanged = true;
1114 return true;
1115 }
1116 wxWMP10LOG(hr);
1117 return false;
1118 }
1119
1120 //---------------------------------------------------------------------------
1121 // wxWMP10MediaBackend::Stop
1122 //
1123 // Stops the stream.
1124 //---------------------------------------------------------------------------
1125 bool wxWMP10MediaBackend::Stop()
1126 {
1127 HRESULT hr = m_pWMPControls->stop();
1128 if(SUCCEEDED(hr))
1129 {
1130 // Seek to beginning
1131 wxWMP10MediaBackend::SetPosition(0);
1132 m_bWasStateChanged = true;
1133 return true;
1134 }
1135 wxWMP10LOG(hr);
1136 return false;
1137 }
1138
1139 //---------------------------------------------------------------------------
1140 // wxWMP10MediaBackend::SetPosition
1141 //
1142 // WMP10 position values are a double in seconds - we just translate
1143 // to our base here
1144 //---------------------------------------------------------------------------
1145 bool wxWMP10MediaBackend::SetPosition(wxLongLong where)
1146 {
1147 HRESULT hr = m_pWMPControls->put_currentPosition(
1148 ((LONGLONG)where.GetValue()) / 1000.0
1149 );
1150 if(FAILED(hr))
1151 {
1152 wxWMP10LOG(hr);
1153 return false;
1154 }
1155
1156 return true;
1157 }
1158
1159 //---------------------------------------------------------------------------
1160 // wxWMP10MediaBackend::GetPosition
1161 //
1162 // WMP10 position values are a double in seconds - we just translate
1163 // to our base here
1164 //---------------------------------------------------------------------------
1165 wxLongLong wxWMP10MediaBackend::GetPosition()
1166 {
1167 double outCur;
1168 HRESULT hr = m_pWMPControls->get_currentPosition(&outCur);
1169 if(FAILED(hr))
1170 {
1171 wxWMP10LOG(hr);
1172 return 0;
1173 }
1174
1175 // h,m,s,milli - outCur is in 1 second (double)
1176 outCur *= 1000;
1177 wxLongLong ll;
1178 ll.Assign(outCur);
1179
1180 return ll;
1181 }
1182
1183 //---------------------------------------------------------------------------
1184 // wxWMP10MediaBackend::GetVolume
1185 //
1186 // Volume 0-100
1187 //---------------------------------------------------------------------------
1188 double wxWMP10MediaBackend::GetVolume()
1189 {
1190 long lVolume;
1191 HRESULT hr = m_pWMPSettings->get_volume(&lVolume);
1192 if(FAILED(hr))
1193 {
1194 wxWMP10LOG(hr);
1195 return 0.0;
1196 }
1197
1198 return (double)lVolume / 100.0;
1199 }
1200
1201 //---------------------------------------------------------------------------
1202 // wxWMP10MediaBackend::SetVolume
1203 //
1204 // Volume 0-100
1205 //---------------------------------------------------------------------------
1206 bool wxWMP10MediaBackend::SetVolume(double dVolume)
1207 {
1208 HRESULT hr = m_pWMPSettings->put_volume( (long) (dVolume * 100.0) );
1209 if(FAILED(hr))
1210 {
1211 wxWMP10LOG(hr);
1212 return false;
1213 }
1214 return true;
1215 }
1216
1217 //---------------------------------------------------------------------------
1218 // wxWMP10MediaBackend::GetDuration
1219 //
1220 // Obtains the duration of the media.
1221 //
1222 // See the "introduction"
1223 //
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()
1228 {
1229 double outDuration = 0.0;
1230
1231 IWMPMedia* pWMPMedia;
1232 if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
1233 {
1234 if(pWMPMedia->get_duration(&outDuration) != 0)
1235 {
1236 wxLogDebug(wxT("get_duration failed"));
1237 }
1238 pWMPMedia->Release();
1239 }
1240
1241
1242 // h,m,s,milli - outDuration is in 1 second (double)
1243 outDuration *= 1000;
1244 wxLongLong ll;
1245 ll.Assign(outDuration);
1246
1247 return ll;
1248 }
1249
1250 //---------------------------------------------------------------------------
1251 // wxWMP10MediaBackend::GetState
1252 //
1253 // Returns the current state
1254 //---------------------------------------------------------------------------
1255 wxMediaState wxWMP10MediaBackend::GetState()
1256 {
1257 WMPPlayState nState;
1258 HRESULT hr = m_pWMPPlayer->get_playState(&nState);
1259 if(FAILED(hr))
1260 {
1261 wxWMP10LOG(hr);
1262 return wxMEDIASTATE_STOPPED;
1263 }
1264
1265 switch(nState)
1266 {
1267 case wmppsPaused:
1268 return wxMEDIASTATE_PAUSED;
1269 case wmppsPlaying:
1270 return wxMEDIASTATE_PLAYING;
1271 default:
1272 return wxMEDIASTATE_STOPPED;
1273 }
1274 }
1275
1276 //---------------------------------------------------------------------------
1277 // wxWMP10MediaBackend::GetPlaybackRate
1278 //
1279 // Just get the rate from WMP10
1280 //---------------------------------------------------------------------------
1281 double wxWMP10MediaBackend::GetPlaybackRate()
1282 {
1283 double dRate;
1284 HRESULT hr = m_pWMPSettings->get_rate(&dRate);
1285 if(FAILED(hr))
1286 {
1287 wxWMP10LOG(hr);
1288 return 0.0;
1289 }
1290 return dRate;
1291 }
1292
1293 //---------------------------------------------------------------------------
1294 // wxWMP10MediaBackend::SetPlaybackRate
1295 //
1296 // Sets the playback rate of the media - DirectShow is pretty good
1297 // about this, actually
1298 //---------------------------------------------------------------------------
1299 bool wxWMP10MediaBackend::SetPlaybackRate(double dRate)
1300 {
1301 HRESULT hr = m_pWMPSettings->put_rate(dRate);
1302 if(FAILED(hr))
1303 {
1304 wxWMP10LOG(hr);
1305 return false;
1306 }
1307
1308 return true;
1309 }
1310
1311 //---------------------------------------------------------------------------
1312 // wxWMP10MediaBackend::GetVideoSize
1313 //
1314 // Obtains the cached original video size
1315 //---------------------------------------------------------------------------
1316 wxSize wxWMP10MediaBackend::GetVideoSize() const
1317 {
1318 return m_bestSize;
1319 }
1320
1321 //---------------------------------------------------------------------------
1322 // wxWMP10MediaBackend::Move
1323 //
1324 // We take care of this in our redrawing
1325 //---------------------------------------------------------------------------
1326 void wxWMP10MediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
1327 #ifdef WXTEST_ATL
1328 int w, int h
1329 #else
1330 int WXUNUSED(w), int WXUNUSED(h)
1331 #endif
1332 )
1333 {
1334 #ifdef WXTEST_ATL
1335 m_wndView.MoveWindow(0,0,w,h);
1336 #endif
1337 }
1338
1339 //---------------------------------------------------------------------------
1340 // wxWMP10MediaBackend::GetDownloadProgress()
1341 //---------------------------------------------------------------------------
1342 wxLongLong wxWMP10MediaBackend::GetDownloadProgress()
1343 {
1344 IWMPNetwork* pWMPNetwork;
1345 if( m_pWMPPlayer->get_network(&pWMPNetwork) == 0 )
1346 {
1347 long lPercentProg;
1348 if(pWMPNetwork->get_downloadProgress(&lPercentProg) == 0)
1349 {
1350 pWMPNetwork->Release();
1351 return (GetDownloadTotal() * lPercentProg) / 100;
1352 }
1353 pWMPNetwork->Release();
1354 }
1355 return 0;
1356 }
1357
1358 //---------------------------------------------------------------------------
1359 // wxWMP10MediaBackend::GetDownloadTotal()
1360 //---------------------------------------------------------------------------
1361 wxLongLong wxWMP10MediaBackend::GetDownloadTotal()
1362 {
1363 IWMPMedia* pWMPMedia;
1364 if(m_pWMPPlayer->get_currentMedia(&pWMPMedia) == 0)
1365 {
1366 BSTR bsOut;
1367 pWMPMedia->getItemInfo(wxBasicString(wxT("FileSize")).Get(),
1368 &bsOut);
1369
1370 wxString sFileSize = wxConvertStringFromOle(bsOut);
1371 long lFS;
1372 sFileSize.ToLong(&lFS);
1373 pWMPMedia->Release();
1374 return lFS;
1375 }
1376
1377 return 0;
1378 }
1379
1380
1381 //---------------------------------------------------------------------------
1382 // wxWMP10MediaBackend::OnActiveX
1383 //
1384 // Handle events sent from our activex control (_WMPOCXEvents actually).
1385 //
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
1388 // and wmp.IDL.
1389 //---------------------------------------------------------------------------
1390 #ifndef WXTEST_ATL
1391 void wxWMP10MediaEvtHandler::OnActiveX(wxActiveXEvent& event)
1392 {
1393 switch(event.GetDispatchId())
1394 {
1395 case 0x000013ed: // playstatechange
1396 if(event.ParamCount() >= 1)
1397 {
1398 switch (event[0].GetInteger())
1399 {
1400 case wmppsMediaEnded: // media ended
1401 if ( m_amb->SendStopEvent() )
1402 {
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...
1407
1408 // send the event to our child
1409 m_amb->QueueFinishEvent();
1410 }
1411 break;
1412
1413 case wmppsStopped: // stopping
1414 m_amb->QueueStopEvent();
1415 break;
1416 case wmppsPaused: // pause
1417 m_amb->QueuePauseEvent();
1418 break;
1419 case wmppsPlaying: // play
1420 m_amb->QueuePlayEvent();
1421 break;
1422 default:
1423 break;
1424 }
1425 }
1426 else
1427 event.Skip();
1428 break;
1429
1430 case 0x00001389: // openstatechange
1431 if(event.ParamCount() >= 1)
1432 {
1433 int nState = event[0].GetInteger();
1434 if(nState == wmposMediaOpen)
1435 {
1436 // See the "introduction"
1437 m_amb->m_bWasStateChanged = false;
1438 m_amb->FinishLoad();
1439 if(!m_amb->m_bWasStateChanged)
1440 m_amb->Stop();
1441 }
1442 }
1443 else
1444 event.Skip();
1445 break;
1446
1447 case 0x0000196e: // mousedown
1448 m_amb->m_ctrl->SetFocus();
1449 break;
1450
1451 default:
1452 event.Skip();
1453 return;
1454 }
1455 }
1456
1457 #endif
1458
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)
1463
1464 #if 0 // Windows Media Player Mobile 9 hacks
1465
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.
1472 //
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")
1477 //
1478 // How do you play a certain file? Simply calling "start [file]" or
1479 // wxWinCEExecute([file]) should do the trick
1480
1481 bool wxWinCEExecute(const wxString& path, int nShowStyle = SW_SHOWNORMAL)
1482 {
1483 WinStruct<SHELLEXECUTEINFO> sei;
1484 sei.lpFile = path.c_str();
1485 sei.lpVerb = wxT("open");
1486 sei.nShow = nShowStyle;
1487
1488 ::ShellExecuteEx(&sei);
1489
1490 return ((int) sei.hInstApp) > 32;
1491 }
1492
1493 bool MyApp::OnInit()
1494 {
1495 HWND hwnd = ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1496 if(!hwnd)
1497 {
1498 if( wxWinCEExecute(wxT("\\Windows\\wmplayer.exe"), SW_MINIMIZE) )
1499 {
1500 hwnd = ::FindWindow(TEXT("WMP for Mobile Devices"), TEXT("Windows Media"));
1501 }
1502 }
1503
1504 if(hwnd)
1505 {
1506 // hide wmp window
1507 ::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,
1508 SWP_NOMOVE|SWP_NOSIZE|SWP_HIDEWINDOW);
1509
1510 // Stop == 32970
1511 // Prev Track == 32971
1512 // Next Track == 32972
1513 // Shuffle == 32973
1514 // Repeat == 32974
1515 // Vol Up == 32975
1516 // Vol Down == 32976
1517 // Play == 32978
1518 ::SendMessage(hwnd, 32978, NULL, 0);
1519 }
1520 }
1521
1522 #endif // WMP mobile 9 hacks
1523
1524 #endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX