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