]> git.saurik.com Git - wxWidgets.git/blame - src/msw/mediactrl_wmp10.cpp
Correct erasing of background behind controls in a toolbar in wxMSW.
[wxWidgets.git] / src / msw / mediactrl_wmp10.cpp
CommitLineData
557002cf
VZ
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
557002cf
VZ
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//
070d6391 30// The ActiveX control itself is particularly stubborn, calling
557002cf
VZ
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
e38b61ed 52#if wxUSE_MEDIACTRL && wxUSE_ACTIVEX
e4db172a 53
557002cf
VZ
54#include "wx/mediactrl.h"
55
e4db172a
WS
56#ifndef WX_PRECOMP
57 #include "wx/log.h"
58#endif
557002cf 59
557002cf
VZ
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
99const CLSID CLSID_WMP10 = {0x6BF52A50,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
100const CLSID CLSID_WMP10ALT = {0x6BF52A52,0x394A,0x11D3,{0xB1,0x53,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
101
102const IID IID_IWMPSettings = {0x9104D1AB,0x80C9,0x4FED,{0xAB,0xF0,0x2E,0x64,0x17,0xA6,0xDF,0x14}};
103const 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
108const IID IID_IWMPMedia = {0x94D55E95,0x3FAC,0x11D3,{0xB1,0x55,0x00,0xC0,0x4F,0x79,0xFA,0xA6}};
109const IID IID_IWMPControls = {0x74C09E02,0xF828,0x11D2,{0xA7,0x4B,0x00,0xA0,0xC9,0x05,0xF3,0x6E}};
110const IID IID_IWMPPlayer2 = {0x0E6B01D1,0xD407,0x4C85,{0xBF,0x5F,0x1C,0x01,0xF6,0x15,0x02,0x80}};
111const IID IID_IWMPCore2 = {0xBC17E5B7,0x7561,0x4C18,{0xBB,0x90,0x17,0xD4,0x85,0x77,0x56,0x59}};
112const IID IID_IWMPCore3 = {0x7587C667,0x628F,0x499F,{0x88,0xE7,0x6A,0x6F,0x4E,0x88,0x84,0x64}};
113const IID IID_IWMPNetwork = {0xEC21B779,0xEDEF,0x462D,{0xBB,0xA4,0xAD,0x9D,0xDE,0x2B,0x29,0xA7}};
114
115enum 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
141enum 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
159struct IWMPMedia : public IDispatch
160{
161public:
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
227struct IWMPControls : public IDispatch
228{
229public:
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
275struct IWMPSettings : public IDispatch
276{
277public:
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
352struct IWMPNetwork : public IDispatch
353{
354public:
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
451struct IWMPCore : public IDispatch
452{
453public:
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
518struct IWMPCore2 : public IWMPCore
519{
520public:
521 virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_dvd(
522 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppDVD) = 0;
523
524};
525
526struct IWMPCore3 : public IWMPCore2
527{
528public:
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
545IWMPPlayer : public IWMPCore
546{
547public:
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
573struct IWMPPlayer2 : public IWMPCore
574{
575public:
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
620class WXDLLIMPEXP_MEDIA wxWMP10MediaBackend : public wxMediaBackendCommonBase
621{
622public:
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"
0fa5ce0c 677 wxEvtHandler* m_evthandler;
557002cf
VZ
678
679 friend class wxWMP10MediaEvtHandler;
680 DECLARE_DYNAMIC_CLASS(wxWMP10MediaBackend)
681};
682
683#ifndef WXTEST_ATL
684class WXDLLIMPEXP_MEDIA wxWMP10MediaEvtHandler : public wxEvtHandler
685{
686public:
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
699private:
700 wxWMP10MediaBackend *m_amb;
701
c0c133e1 702 wxDECLARE_NO_COPY_CLASS(wxWMP10MediaEvtHandler);
557002cf
VZ
703};
704#endif
705
706//===========================================================================
707// IMPLEMENTATION
708//===========================================================================
709
710//---------------------------------------------------------------------------
711//
712// wxWMP10MediaBackend
713//
714//---------------------------------------------------------------------------
715
716IMPLEMENT_DYNAMIC_CLASS(wxWMP10MediaBackend, wxMediaBackend)
717
718//---------------------------------------------------------------------------
719// wxWMP10MediaBackend Constructor
720//---------------------------------------------------------------------------
721wxWMP10MediaBackend::wxWMP10MediaBackend()
722 :
723#ifndef WXTEST_ATL
724 m_pAX(NULL),
725#endif
2631773e
JS
726 m_pWMPPlayer(NULL),
727 m_pWMPSettings(NULL),
728 m_pWMPControls(NULL)
557002cf
VZ
729
730{
0fa5ce0c 731 m_evthandler = NULL;
557002cf
VZ
732}
733
734//---------------------------------------------------------------------------
735// wxWMP10MediaBackend Destructor
736//---------------------------------------------------------------------------
737wxWMP10MediaBackend::~wxWMP10MediaBackend()
738{
739 if(m_pWMPPlayer)
740 {
741#ifndef WXTEST_ATL
742 m_pAX->DissociateHandle();
743 delete m_pAX;
744
0fa5ce0c
VZ
745 if (m_evthandler)
746 {
747 m_ctrl->RemoveEventHandler(m_evthandler);
748 delete m_evthandler;
749 }
557002cf
VZ
750#else
751 AtlAxWinTerm();
752 _Module.Term();
753#endif
754
755 m_pWMPPlayer->Release();
2631773e
JS
756 if (m_pWMPSettings)
757 m_pWMPSettings->Release();
758 if (m_pWMPControls)
759 m_pWMPControls->Release();
557002cf
VZ
760 }
761}
762
763//---------------------------------------------------------------------------
764// wxWMP10MediaBackend::CreateControl
765//---------------------------------------------------------------------------
766bool 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
0fa5ce0c
VZ
824 m_evthandler = new wxWMP10MediaEvtHandler(this);
825 m_ctrl->PushEventHandler(m_evthandler);
557002cf
VZ
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);
9a83f860 836 hr = spHost->CreateControl(CComBSTR(wxT("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
557002cf
VZ
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 {
070d6391 863 // We don't check errors here as these arn't particularly important
557002cf
VZ
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//---------------------------------------------------------------------------
888bool wxWMP10MediaBackend::Load(const wxString& fileName)
889{
890 return DoLoad(fileName);
891}
892
893//---------------------------------------------------------------------------
894// wxWMP10MediaBackend::Load (URL Version)
895//---------------------------------------------------------------------------
896bool wxWMP10MediaBackend::Load(const wxURI& location)
897{
898 return DoLoad(location.BuildURI());
899}
900
901//---------------------------------------------------------------------------
902// wxWMP10MediaBackend::Load (URL Version with Proxy)
903//---------------------------------------------------------------------------
904bool 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//---------------------------------------------------------------------------
989bool 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//---------------------------------------------------------------------------
1038void 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//---------------------------------------------------------------------------
1065bool 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//---------------------------------------------------------------------------
1090bool 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//---------------------------------------------------------------------------
1108bool 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//---------------------------------------------------------------------------
1125bool 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//---------------------------------------------------------------------------
1145bool 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//---------------------------------------------------------------------------
1165wxLongLong 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//---------------------------------------------------------------------------
1188double 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//---------------------------------------------------------------------------
1206bool 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//---------------------------------------------------------------------------
1227wxLongLong 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//---------------------------------------------------------------------------
1255wxMediaState 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//---------------------------------------------------------------------------
1281double 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//---------------------------------------------------------------------------
1299bool 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//---------------------------------------------------------------------------
1316wxSize 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//---------------------------------------------------------------------------
1326void 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//---------------------------------------------------------------------------
1342wxLongLong 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//---------------------------------------------------------------------------
1361wxLongLong 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
1391void 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
6161dd2d
VZ
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"
1462wxFORCE_LINK_THIS_MODULE(wxmediabackend_wmp10)
557002cf
VZ
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
070d6391 1474// SendMessage with one of those myterious values laid out in
557002cf
VZ
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
1481bool wxWinCEExecute(const wxString& path, int nShowStyle = SW_SHOWNORMAL)
1482{
1483 WinStruct<SHELLEXECUTEINFO> sei;
1484 sei.lpFile = path.c_str();
9a83f860 1485 sei.lpVerb = wxT("open");
557002cf
VZ
1486 sei.nShow = nShowStyle;
1487
1488 ::ShellExecuteEx(&sei);
1489
1490 return ((int) sei.hInstApp) > 32;
1491}
1492
1493bool 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
e38b61ed 1524#endif // wxUSE_MEDIACTRL && wxUSE_ACTIVEX