]> git.saurik.com Git - wxWidgets.git/blame - src/msw/mediactrl.cpp
only link with 3rd party libs if they're needed
[wxWidgets.git] / src / msw / mediactrl.cpp
CommitLineData
1a680109
RN
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/mediactrl.cpp
ff4aedc5 3// Purpose: Built-in Media Backends for Windows
1a680109 4// Author: Ryan Norton <wxprojects@comcast.net>
72259e00 5// Modified by:
1a680109
RN
6// Created: 11/07/04
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
aa200e97
VZ
12/*
13 FIXME FIXME FIXME:
14 - extract different backends in different files (better yet, make backends
15 dynamically loadable...), they have nothing to do with each other and
16 this file is huge and also separate the standard contents from our code
17 itself
18 - extract ~1000 lines of wxActiveX code in its own file, why does it have
19 to be here??
20 */
21
ff4aedc5
RN
22//===========================================================================
23// DECLARATIONS
24//===========================================================================
25
1a680109 26//---------------------------------------------------------------------------
ff4aedc5 27// Pre-compiled header stuff
1a680109
RN
28//---------------------------------------------------------------------------
29
ff4aedc5
RN
30#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
31#pragma implementation "mediactrl.h"
32#endif
1a680109
RN
33
34// For compilers that support precompilation, includes "wx.h".
35#include "wx/wxprec.h"
36
37#ifdef __BORLANDC__
38#pragma hdrstop
39#endif
40
ff4aedc5 41//---------------------------------------------------------------------------
c5191fbd 42// MediaCtrl include
ff4aedc5 43//---------------------------------------------------------------------------
1a680109
RN
44#include "wx/mediactrl.h"
45
ff4aedc5
RN
46//---------------------------------------------------------------------------
47// Compilation guard
48//---------------------------------------------------------------------------
1a680109
RN
49#if wxUSE_MEDIACTRL
50
c5191fbd
VZ
51//---------------------------------------------------------------------------
52// WX Includes
53//---------------------------------------------------------------------------
54#include "wx/log.h" //wxLogDebug
55#include "wx/math.h" //log10 & pow
56#include "wx/msw/private.h" //user info and wndproc setting/getting
3832f946
WS
57#include "wx/dcclient.h"
58#include "wx/timer.h"
b195b4fa 59
1a680109 60//---------------------------------------------------------------------------
c5191fbd 61// Externals (somewhere in src/msw/app.cpp and src/msw/window.cpp)
1a680109 62//---------------------------------------------------------------------------
ff4aedc5
RN
63extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance(void);
64#ifdef __WXWINCE__
7a4d2469 65extern WXDLLIMPEXP_CORE wxChar *wxCanvasClassName;
ff4aedc5 66#else
316d19ac 67extern WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName;
ff4aedc5 68#endif
1a680109 69
c5191fbd
VZ
70LRESULT WXDLLIMPEXP_CORE APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
71 WPARAM wParam, LPARAM lParam);
72
ff4aedc5
RN
73//===========================================================================
74// BACKEND DECLARATIONS
75//===========================================================================
1a680109 76
7e41b689
VZ
77// ----------------------------------------------------------------------------
78// common backend base class used by all other backends
79// ----------------------------------------------------------------------------
80
81class wxMediaBackendCommonBase : public wxMediaBackend
82{
83public:
84 // add a pending wxMediaEvent of the given type
85 void QueueEvent(wxEventType evtType);
86
87 // notify that the movie playback is finished
88 void QueueFinishEvent() { QueueEvent(wxEVT_MEDIA_FINISHED); }
89
90 // send the stop event and return true if it hasn't been vetoed
91 bool SendStopEvent();
92
93protected:
94 // call this when the movie size has changed but not because it has just
95 // been loaded (in this case, call NotifyMovieLoaded() below)
96 void NotifyMovieSizeChanged();
97
98 // call this when the movie is fully loaded
99 void NotifyMovieLoaded();
100
101
102 wxControl *m_ctrl; // parent control
103};
104
1a680109 105//---------------------------------------------------------------------------
ff4aedc5
RN
106//
107// wxAMMediaBackend
108//
1a680109
RN
109//---------------------------------------------------------------------------
110
ff4aedc5 111//---------------------------------------------------------------------------
a2a444e3
RN
112// COM includes
113//---------------------------------------------------------------------------
114#include "wx/msw/ole/oleutils.h" //wxBasicString, IID etc.
115#include "wx/msw/ole/uuid.h" //IID etc..
c5191fbd
VZ
116#include <oleidl.h>
117#include <olectl.h>
118#include <exdisp.h>
119#include <docobj.h>
120
121//
122// These defines are from another ole header - but its not in the
123// latest sdk. Also the ifndef DISPID_READYSTATE is here because at
124// least on my machine with the latest sdk olectl.h defines these 3
125//
126#ifndef DISPID_READYSTATE
127 #define DISPID_READYSTATE -525
128 #define DISPID_READYSTATECHANGE -609
129 #define DISPID_AMBIENT_TRANSFERPRIORITY -728
130#endif
131
132#define DISPID_AMBIENT_OFFLINEIFNOTCONNECTED -5501
133#define DISPID_AMBIENT_SILENT -5502
134
135#ifndef DISPID_AMBIENT_CODEPAGE
136# define DISPID_AMBIENT_CODEPAGE -725
137# define DISPID_AMBIENT_CHARSET -727
138#endif
a2a444e3 139
920a7c15
JS
140//---------------------------------------------------------------------------
141// COM compatability definitions
142//---------------------------------------------------------------------------
143#ifndef STDMETHODCALLTYPE
144#define STDMETHODCALLTYPE __stdcall
145#endif
146#ifndef STDMETHOD
147#define STDMETHOD(funcname) virtual HRESULT STDMETHODCALLTYPE funcname
148#endif
149#ifndef PURE
150#define PURE = 0
151#endif
c5191fbd
VZ
152#ifndef __RPC_FAR
153#define __RPC_FAR FAR
154#endif
155
a2a444e3
RN
156//---------------------------------------------------------------------------
157// IIDS - used by CoCreateInstance and IUnknown::QueryInterface
c5191fbd
VZ
158//
159// [idl name] [idl decription]
160// amcompat.idl Microsoft Active Movie Control (Ver 2.0)
161// nscompat.idl Microsoft NetShow Player (Ver 1.0)
162// msdxm.idl Windows Media Player (Ver 1.0)
163// quartz.idl
164//
165// First, when I say I "from XXX.idl", I mean I go into the COM Browser
166// ($Microsoft Visual Studio$/Common/Tools/OLEVIEW.EXE), open
167// "type libraries", open a specific type library (for quartz for example its
168// "ActiveMovie control type library (V1.0)"), save it as an .idl, compile the
169// idl using the midl compiler that comes with visual studio
170// ($Microsoft Visual Studio$/VC98/bin/midl.exe on VC6) with the /h argument
171// to make it generate stubs (a .h & .c file), then clean up the generated
172// interfaces I want with the STDMETHOD wrappers and then put them into
173// mediactrl.cpp.
174//
175// According to the MSDN docs, IMediaPlayer requires Windows 98 SE
176// or greater. NetShow is available on Windows 3.1 and I'm guessing
177// IActiveMovie is too. IMediaPlayer is essentially the Windows Media
178// Player 6.4 SDK.
920a7c15
JS
179//
180// Some of these are not used but are kept here for future reference anyway
a2a444e3 181//---------------------------------------------------------------------------
c5191fbd
VZ
182const IID IID_IActiveMovie = {0x05589FA2,0xC356,0x11CE,{0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A}};
183const IID IID_IActiveMovie2 = {0xB6CD6554,0xE9CB,0x11D0,{0x82,0x1F,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
184const IID IID_IActiveMovie3 = {0x265EC140,0xAE62,0x11D1,{0x85,0x00,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
920a7c15 185
c5191fbd
VZ
186const IID IID_INSOPlay = {0x2179C5D1,0xEBFF,0x11CF,{0xB6,0xFD,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
187const IID IID_INSPlay = {0xE7C4BE80,0x7960,0x11D0,{0xB7,0x27,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
188const IID IID_INSPlay1 = {0x265EC141,0xAE62,0x11D1,{0x85,0x00,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
189
190const IID IID_IMediaPlayer = {0x22D6F311,0xB0F6,0x11D0,{0x94,0xAB,0x00,0x80,0xC7,0x4C,0x7E,0x95}};
191const IID IID_IMediaPlayer2 = {0x20D4F5E0,0x5475,0x11D2,{0x97,0x74,0x00,0x00,0xF8,0x08,0x55,0xE6}};
a2a444e3 192
c5191fbd
VZ
193const CLSID CLSID_ActiveMovie = {0x05589FA1,0xC356,0x11CE,{0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A}};
194const CLSID CLSID_MediaPlayer = {0x22D6F312,0xB0F6,0x11D0,{0x94,0xAB,0x00,0x80,0xC7,0x4C,0x7E,0x95}};
195const CLSID CLSID_NSPlay = {0x2179C5D3,0xEBFF,0x11CF,{0xB6,0xFD,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
920a7c15 196
c5191fbd
VZ
197const IID IID_IAMOpenProgress = {0x8E1C39A1, 0xDE53, 0x11CF,{0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};
198
199// QUARTZ
200const CLSID CLSID_FilgraphManager = {0xE436EBB3,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
201const IID IID_IMediaEvent = {0x56A868B6,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
920a7c15
JS
202
203//?? QUARTZ Also?
c5191fbd
VZ
204const CLSID CLSID_VideoMixingRenderer9 ={0x51B4ABF3, 0x748F, 0x4E3B,{0xA2, 0x76, 0xC8, 0x28, 0x33, 0x0E, 0x92, 0x6A}};
205const IID IID_IVMRWindowlessControl9 = {0x8F537D09, 0xF85E, 0x4414,{0xB2, 0x3B, 0x50, 0x2E, 0x54, 0xC7, 0x99, 0x27}};
920a7c15
JS
206const IID IID_IFilterGraph = {0x56A8689F, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
207const IID IID_IGraphBuilder = {0x56A868A9, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
c5191fbd 208const IID IID_IVMRFilterConfig9 = {0x5A804648, 0x4F66, 0x4867,{0x9C, 0x43, 0x4F, 0x5C, 0x82, 0x2C, 0xF1, 0xB8}};
920a7c15
JS
209const IID IID_IBaseFilter = {0x56A86895, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
210
211//---------------------------------------------------------------------------
c5191fbd 212// QUARTZ COM INTERFACES (dumped from quartz.idl from MSVC COM Browser)
920a7c15 213//---------------------------------------------------------------------------
920a7c15 214
c5191fbd
VZ
215struct IAMOpenProgress : public IUnknown
216{
217 STDMETHOD(QueryProgress)(LONGLONG *pllTotal, LONGLONG *pllCurrent) PURE;
218 STDMETHOD(AbortOperation)(void) PURE;
219};
920a7c15 220
c5191fbd 221struct IMediaEvent : public IDispatch
920a7c15 222{
c5191fbd
VZ
223 STDMETHOD(GetEventHandle)(LONG_PTR *) PURE;
224 STDMETHOD(GetEvent)(long *, LONG_PTR *, LONG_PTR *, long) PURE;
225 STDMETHOD(WaitForCompletion)(long, long *) PURE;
226 STDMETHOD(CancelDefaultHandling)(long) PURE;
227 STDMETHOD(RestoreDefaultHandling)(long) PURE;
228 STDMETHOD(FreeEventParams)(long, LONG_PTR, LONG_PTR) PURE;
a2a444e3
RN
229};
230
c5191fbd
VZ
231//---------------------------------------------------------------------------
232// ACTIVEMOVIE COM INTERFACES (dumped from amcompat.idl from MSVC COM Browser)
233//---------------------------------------------------------------------------
234
235enum ReadyStateConstants
a2a444e3 236{
c5191fbd
VZ
237 amvUninitialized = 0,
238 amvLoading = 1,
239 amvInteractive = 3,
240 amvComplete = 4
a2a444e3
RN
241};
242
c5191fbd
VZ
243enum StateConstants
244{
245 amvNotLoaded = -1,
246 amvStopped = 0,
247 amvPaused = 1,
248 amvRunning = 2
a2a444e3
RN
249};
250
c5191fbd
VZ
251enum DisplayModeConstants
252{
253 amvTime = 0,
254 amvFrames = 1
920a7c15 255};
32f65e50 256
c5191fbd 257enum WindowSizeConstants
a2a444e3 258{
c5191fbd
VZ
259 amvOriginalSize = 0,
260 amvDoubleOriginalSize = 1,
261 amvOneSixteenthScreen = 2,
262 amvOneFourthScreen = 3,
263 amvOneHalfScreen = 4
a2a444e3 264};
b11eba7e 265
c5191fbd 266enum AppearanceConstants
a2a444e3 267{
c5191fbd
VZ
268 amvFlat = 0,
269 amv3D = 1
a2a444e3
RN
270};
271
c5191fbd 272enum BorderStyleConstants
a2a444e3 273{
c5191fbd
VZ
274 amvNone = 0,
275 amvFixedSingle = 1
a2a444e3 276};
b11eba7e 277
c5191fbd 278struct IActiveMovie : public IDispatch
a2a444e3 279{
c5191fbd
VZ
280 STDMETHOD(AboutBox)( void) PURE;
281 STDMETHOD(Run)( void) PURE;
282 STDMETHOD(Pause)( void) PURE;
283 STDMETHOD(Stop)( void) PURE;
284 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
285 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
286 STDMETHOD(get_Author)(BSTR __RPC_FAR *pbstrAuthor) PURE;
287 STDMETHOD(get_Title)(BSTR __RPC_FAR *pbstrTitle) PURE;
288 STDMETHOD(get_Copyright)(BSTR __RPC_FAR *pbstrCopyright) PURE;
289 STDMETHOD(get_Description)(BSTR __RPC_FAR *pbstrDescription) PURE;
290 STDMETHOD(get_Rating)(BSTR __RPC_FAR *pbstrRating) PURE;
291 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
292 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
293 STDMETHOD(get_Duration)(double __RPC_FAR *pValue) PURE;
294 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pValue) PURE;
295 STDMETHOD(put_CurrentPosition)(double pValue) PURE;
296 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
297 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
298 STDMETHOD(get_SelectionStart)(double __RPC_FAR *pValue) PURE;
299 STDMETHOD(put_SelectionStart)(double pValue) PURE;
300 STDMETHOD(get_SelectionEnd)(double __RPC_FAR *pValue) PURE;
301 STDMETHOD(put_SelectionEnd)(double pValue) PURE;
302 STDMETHOD(get_CurrentState)(StateConstants __RPC_FAR *pState) PURE;
303 STDMETHOD(get_Rate)(double __RPC_FAR *pValue) PURE;
304 STDMETHOD(put_Rate)(double pValue) PURE;
305 STDMETHOD(get_Volume)(long __RPC_FAR *pValue) PURE;
306 STDMETHOD(put_Volume)(long pValue) PURE;
307 STDMETHOD(get_Balance)(long __RPC_FAR *pValue) PURE;
308 STDMETHOD(put_Balance)(long pValue) PURE;
309 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
310 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnable) PURE;
311 STDMETHOD(get_ShowDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
312 STDMETHOD(put_ShowDisplay)(VARIANT_BOOL Show) PURE;
313 STDMETHOD(get_ShowControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
314 STDMETHOD(put_ShowControls)(VARIANT_BOOL Show) PURE;
315 STDMETHOD(get_ShowPositionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
316 STDMETHOD(put_ShowPositionControls)(VARIANT_BOOL Show) PURE;
317 STDMETHOD(get_ShowSelectionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
318 STDMETHOD(put_ShowSelectionControls)(VARIANT_BOOL Show) PURE;
319 STDMETHOD(get_ShowTracker)(VARIANT_BOOL __RPC_FAR *Show) PURE;
320 STDMETHOD(put_ShowTracker)(VARIANT_BOOL Show) PURE;
321 STDMETHOD(get_EnablePositionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
322 STDMETHOD(put_EnablePositionControls)(VARIANT_BOOL Enable) PURE;
323 STDMETHOD(get_EnableSelectionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
324 STDMETHOD(put_EnableSelectionControls)(VARIANT_BOOL Enable) PURE;
325 STDMETHOD(get_EnableTracker)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
326 STDMETHOD(put_EnableTracker)(VARIANT_BOOL Enable) PURE;
327 STDMETHOD(get_AllowHideDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
328 STDMETHOD(put_AllowHideDisplay)(VARIANT_BOOL Show) PURE;
329 STDMETHOD(get_AllowHideControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
330 STDMETHOD(put_AllowHideControls)(VARIANT_BOOL Show) PURE;
331 STDMETHOD(get_DisplayMode)(DisplayModeConstants __RPC_FAR *pValue) PURE;
332 STDMETHOD(put_DisplayMode)(DisplayModeConstants pValue) PURE;
333 STDMETHOD(get_AllowChangeDisplayMode)(VARIANT_BOOL __RPC_FAR *fAllow) PURE;
334 STDMETHOD(put_AllowChangeDisplayMode)(VARIANT_BOOL fAllow) PURE;
335 STDMETHOD(get_FilterGraph)(IUnknown __RPC_FAR *__RPC_FAR *ppFilterGraph) PURE;
336 STDMETHOD(put_FilterGraph)(IUnknown __RPC_FAR *ppFilterGraph) PURE;
337 STDMETHOD(get_FilterGraphDispatch)(IDispatch __RPC_FAR *__RPC_FAR *pDispatch) PURE;
338 STDMETHOD(get_DisplayForeColor)(unsigned long __RPC_FAR *ForeColor) PURE;
339 STDMETHOD(put_DisplayForeColor)(unsigned long ForeColor) PURE;
340 STDMETHOD(get_DisplayBackColor)(unsigned long __RPC_FAR *BackColor) PURE;
341 STDMETHOD(put_DisplayBackColor)(unsigned long BackColor) PURE;
342 STDMETHOD(get_MovieWindowSize)(WindowSizeConstants __RPC_FAR *WindowSize) PURE;
343 STDMETHOD(put_MovieWindowSize)(WindowSizeConstants WindowSize) PURE;
344 STDMETHOD(get_FullScreenMode)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
345 STDMETHOD(put_FullScreenMode)(VARIANT_BOOL pEnable) PURE;
346 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
347 STDMETHOD(put_AutoStart)(VARIANT_BOOL pEnable) PURE;
348 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
349 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pEnable) PURE;
350 STDMETHOD(get_hWnd)(long __RPC_FAR *hWnd) PURE;
351 STDMETHOD(get_Appearance)(AppearanceConstants __RPC_FAR *pAppearance) PURE;
352 STDMETHOD(put_Appearance)(AppearanceConstants pAppearance) PURE;
353 STDMETHOD(get_BorderStyle)(BorderStyleConstants __RPC_FAR *pBorderStyle) PURE;
354 STDMETHOD(put_BorderStyle)(BorderStyleConstants pBorderStyle) PURE;
355 STDMETHOD(get_Enabled)(VARIANT_BOOL __RPC_FAR *pEnabled) PURE;
356 STDMETHOD(put_Enabled)(VARIANT_BOOL pEnabled) PURE;
357 STDMETHOD(get_Info)(long __RPC_FAR *ppInfo) PURE;
920a7c15 358};
b11eba7e 359
c5191fbd
VZ
360
361
362struct IActiveMovie2 : public IActiveMovie
363{
364 STDMETHOD(IsSoundCardEnabled)(VARIANT_BOOL __RPC_FAR *pbSoundCard) PURE;
365 STDMETHOD(get_ReadyState)(ReadyStateConstants __RPC_FAR *pValue) PURE;
a2a444e3 366};
1a680109 367
c5191fbd 368struct IActiveMovie3 : public IActiveMovie2
a2a444e3 369{
c5191fbd 370 STDMETHOD(get_MediaPlayer)(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) PURE;
a2a444e3 371};
b11eba7e 372
c5191fbd 373
920a7c15 374//---------------------------------------------------------------------------
c5191fbd 375// MEDIAPLAYER COM INTERFACES (dumped from msdxm.idl from MSVC COM Browser)
920a7c15 376//---------------------------------------------------------------------------
c5191fbd
VZ
377
378enum MPPlayStateConstants
a2a444e3 379{
c5191fbd
VZ
380 mpStopped = 0,
381 mpPaused = 1,
382 mpPlaying = 2,
383 mpWaiting = 3,
384 mpScanForward = 4,
385 mpScanReverse = 5,
386 mpClosed = 6
920a7c15 387};
b11eba7e 388
c5191fbd
VZ
389enum MPDisplaySizeConstants
390{
391 mpDefaultSize = 0,
392 mpHalfSize = 1,
393 mpDoubleSize = 2,
394 mpFullScreen = 3,
395 mpFitToSize = 4,
396 mpOneSixteenthScreen = 5,
397 mpOneFourthScreen = 6,
398 mpOneHalfScreen = 7
a2a444e3 399};
b11eba7e 400
c5191fbd 401enum MPReadyStateConstants
a2a444e3 402{
c5191fbd
VZ
403 mpReadyStateUninitialized = 0,
404 mpReadyStateLoading = 1,
405 mpReadyStateInteractive = 3,
406 mpReadyStateComplete = 4
a2a444e3
RN
407};
408
c5191fbd
VZ
409typedef unsigned long VB_OLE_COLOR;
410
411enum MPDisplayModeConstants
a2a444e3 412{
c5191fbd
VZ
413 mpTime = 0,
414 mpFrames = 1
920a7c15 415};
b11eba7e 416
c5191fbd
VZ
417enum MPMoreInfoType
418{
419 mpShowURL = 0,
420 mpClipURL = 1,
421 mpBannerURL = 2
a2a444e3 422};
b11eba7e 423
c5191fbd 424enum MPMediaInfoType
a2a444e3 425{
c5191fbd
VZ
426 mpShowFilename = 0,
427 mpShowTitle = 1,
428 mpShowAuthor = 2,
429 mpShowCopyright = 3,
430 mpShowRating = 4,
431 mpShowDescription = 5,
432 mpShowLogoIcon = 6,
433 mpClipFilename = 7,
434 mpClipTitle = 8,
435 mpClipAuthor = 9,
436 mpClipCopyright = 10,
437 mpClipRating = 11,
438 mpClipDescription = 12,
439 mpClipLogoIcon = 13,
440 mpBannerImage = 14,
441 mpBannerMoreInfo = 15,
442 mpWatermark = 16
443};
444
445enum DVDMenuIDConstants
446{
447 dvdMenu_Title = 2,
448 dvdMenu_Root = 3,
449 dvdMenu_Subpicture = 4,
450 dvdMenu_Audio = 5,
451 dvdMenu_Angle = 6,
452 dvdMenu_Chapter = 7
453};
454
455enum MPShowDialogConstants
456{
457 mpShowDialogHelp = 0,
458 mpShowDialogStatistics = 1,
459 mpShowDialogOptions = 2,
460 mpShowDialogContextMenu = 3
461};
462
463
464struct IMediaPlayer : public IDispatch
465{
466 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pCurrentPosition) PURE;
467 STDMETHOD(put_CurrentPosition)(double pCurrentPosition) PURE;
468 STDMETHOD(get_Duration)(double __RPC_FAR *pDuration) PURE;
469 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
470 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
471 STDMETHOD(get_MarkerCount)(long __RPC_FAR *pMarkerCount) PURE;
472 STDMETHOD(get_CanScan)(VARIANT_BOOL __RPC_FAR *pCanScan) PURE;
473 STDMETHOD(get_CanSeek)(VARIANT_BOOL __RPC_FAR *pCanSeek) PURE;
474 STDMETHOD(get_CanSeekToMarkers)(VARIANT_BOOL __RPC_FAR *pCanSeekToMarkers) PURE;
475 STDMETHOD(get_CurrentMarker)(long __RPC_FAR *pCurrentMarker) PURE;
476 STDMETHOD(put_CurrentMarker)(long pCurrentMarker) PURE;
477 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
478 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
479 STDMETHOD(get_SourceLink)(BSTR __RPC_FAR *pbstrSourceLink) PURE;
480 STDMETHOD(get_CreationDate)(DATE __RPC_FAR *pCreationDate) PURE;
481 STDMETHOD(get_ErrorCorrection)(BSTR __RPC_FAR *pbstrErrorCorrection) PURE;
482 STDMETHOD(get_Bandwidth)(long __RPC_FAR *pBandwidth) PURE;
483 STDMETHOD(get_SourceProtocol)(long __RPC_FAR *pSourceProtocol) PURE;
484 STDMETHOD(get_ReceivedPackets)(long __RPC_FAR *pReceivedPackets) PURE;
485 STDMETHOD(get_RecoveredPackets)(long __RPC_FAR *pRecoveredPackets) PURE;
486 STDMETHOD(get_LostPackets)(long __RPC_FAR *pLostPackets) PURE;
487 STDMETHOD(get_ReceptionQuality)(long __RPC_FAR *pReceptionQuality) PURE;
488 STDMETHOD(get_BufferingCount)(long __RPC_FAR *pBufferingCount) PURE;
489 STDMETHOD(get_IsBroadcast)(VARIANT_BOOL __RPC_FAR *pIsBroadcast) PURE;
490 STDMETHOD(get_BufferingProgress)(long __RPC_FAR *pBufferingProgress) PURE;
491 STDMETHOD(get_ChannelName)(BSTR __RPC_FAR *pbstrChannelName) PURE;
492 STDMETHOD(get_ChannelDescription)(BSTR __RPC_FAR *pbstrChannelDescription) PURE;
493 STDMETHOD(get_ChannelURL)(BSTR __RPC_FAR *pbstrChannelURL) PURE;
494 STDMETHOD(get_ContactAddress)(BSTR __RPC_FAR *pbstrContactAddress) PURE;
495 STDMETHOD(get_ContactPhone)(BSTR __RPC_FAR *pbstrContactPhone) PURE;
496 STDMETHOD(get_ContactEmail)(BSTR __RPC_FAR *pbstrContactEmail) PURE;
497 STDMETHOD(get_BufferingTime)(double __RPC_FAR *pBufferingTime) PURE;
498 STDMETHOD(put_BufferingTime)(double pBufferingTime) PURE;
499 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pAutoStart) PURE;
500 STDMETHOD(put_AutoStart)(VARIANT_BOOL pAutoStart) PURE;
501 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pAutoRewind) PURE;
502 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pAutoRewind) PURE;
503 STDMETHOD(get_Rate)(double __RPC_FAR *pRate) PURE;
504 STDMETHOD(put_Rate)(double pRate) PURE;
505 STDMETHOD(get_SendKeyboardEvents)(VARIANT_BOOL __RPC_FAR *pSendKeyboardEvents) PURE;
506 STDMETHOD(put_SendKeyboardEvents)(VARIANT_BOOL pSendKeyboardEvents) PURE;
507 STDMETHOD(get_SendMouseClickEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseClickEvents) PURE;
508 STDMETHOD(put_SendMouseClickEvents)(VARIANT_BOOL pSendMouseClickEvents) PURE;
509 STDMETHOD(get_SendMouseMoveEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseMoveEvents) PURE;
510 STDMETHOD(put_SendMouseMoveEvents)(VARIANT_BOOL pSendMouseMoveEvents) PURE;
511 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
512 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
513 STDMETHOD(get_ClickToPlay)(VARIANT_BOOL __RPC_FAR *pClickToPlay) PURE;
514 STDMETHOD(put_ClickToPlay)(VARIANT_BOOL pClickToPlay) PURE;
515 STDMETHOD(get_AllowScan)(VARIANT_BOOL __RPC_FAR *pAllowScan) PURE;
516 STDMETHOD(put_AllowScan)(VARIANT_BOOL pAllowScan) PURE;
517 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnableContextMenu) PURE;
518 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnableContextMenu) PURE;
519 STDMETHOD(get_CursorType)(long __RPC_FAR *pCursorType) PURE;
520 STDMETHOD(put_CursorType)(long pCursorType) PURE;
521 STDMETHOD(get_CodecCount)(long __RPC_FAR *pCodecCount) PURE;
522 STDMETHOD(get_AllowChangeDisplaySize)(VARIANT_BOOL __RPC_FAR *pAllowChangeDisplaySize) PURE;
523 STDMETHOD(put_AllowChangeDisplaySize)( VARIANT_BOOL pAllowChangeDisplaySize) PURE;
524 STDMETHOD(get_IsDurationValid)(VARIANT_BOOL __RPC_FAR *pIsDurationValid) PURE;
525 STDMETHOD(get_OpenState)(long __RPC_FAR *pOpenState) PURE;
526 STDMETHOD(get_SendOpenStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendOpenStateChangeEvents) PURE;
527 STDMETHOD(put_SendOpenStateChangeEvents)(VARIANT_BOOL pSendOpenStateChangeEvents) PURE;
528 STDMETHOD(get_SendWarningEvents)( VARIANT_BOOL __RPC_FAR *pSendWarningEvents) PURE;
529 STDMETHOD(put_SendWarningEvents)(VARIANT_BOOL pSendWarningEvents) PURE;
530 STDMETHOD(get_SendErrorEvents)(VARIANT_BOOL __RPC_FAR *pSendErrorEvents) PURE;
531 STDMETHOD(put_SendErrorEvents)(VARIANT_BOOL pSendErrorEvents) PURE;
532 STDMETHOD(get_PlayState)(MPPlayStateConstants __RPC_FAR *pPlayState) PURE;
533 STDMETHOD(get_SendPlayStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendPlayStateChangeEvents) PURE;
534 STDMETHOD(put_SendPlayStateChangeEvents)(VARIANT_BOOL pSendPlayStateChangeEvents) PURE;
535 STDMETHOD(get_DisplaySize)(MPDisplaySizeConstants __RPC_FAR *pDisplaySize) PURE;
536 STDMETHOD(put_DisplaySize)(MPDisplaySizeConstants pDisplaySize) PURE;
537 STDMETHOD(get_InvokeURLs)(VARIANT_BOOL __RPC_FAR *pInvokeURLs) PURE;
538 STDMETHOD(put_InvokeURLs)(VARIANT_BOOL pInvokeURLs) PURE;
539 STDMETHOD(get_BaseURL)(BSTR __RPC_FAR *pbstrBaseURL) PURE;
540 STDMETHOD(put_BaseURL)(BSTR pbstrBaseURL) PURE;
541 STDMETHOD(get_DefaultFrame)(BSTR __RPC_FAR *pbstrDefaultFrame) PURE;
542 STDMETHOD(put_DefaultFrame)(BSTR pbstrDefaultFrame) PURE;
543 STDMETHOD(get_HasError)(VARIANT_BOOL __RPC_FAR *pHasError) PURE;
544 STDMETHOD(get_ErrorDescription)(BSTR __RPC_FAR *pbstrErrorDescription) PURE;
545 STDMETHOD(get_ErrorCode)(long __RPC_FAR *pErrorCode) PURE;
546 STDMETHOD(get_AnimationAtStart)(VARIANT_BOOL __RPC_FAR *pAnimationAtStart) PURE;
547 STDMETHOD(put_AnimationAtStart)(VARIANT_BOOL pAnimationAtStart) PURE;
548 STDMETHOD(get_TransparentAtStart)( VARIANT_BOOL __RPC_FAR *pTransparentAtStart) PURE;
549 STDMETHOD(put_TransparentAtStart)(VARIANT_BOOL pTransparentAtStart) PURE;
550 STDMETHOD(get_Volume)(long __RPC_FAR *pVolume) PURE;
551 STDMETHOD(put_Volume)(long pVolume) PURE;
552 STDMETHOD(get_Balance)(long __RPC_FAR *pBalance) PURE;
553 STDMETHOD(put_Balance)(long pBalance) PURE;
554 STDMETHOD(get_ReadyState)(MPReadyStateConstants __RPC_FAR *pValue) PURE;
555 STDMETHOD(get_SelectionStart)(double __RPC_FAR *pValue) PURE;
556 STDMETHOD(put_SelectionStart)(double pValue) PURE;
557 STDMETHOD(get_SelectionEnd)(double __RPC_FAR *pValue) PURE;
558 STDMETHOD(put_SelectionEnd)(double pValue) PURE;
559 STDMETHOD(get_ShowDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
560 STDMETHOD(put_ShowDisplay)(VARIANT_BOOL Show) PURE;
561 STDMETHOD(get_ShowControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
562 STDMETHOD(put_ShowControls)(VARIANT_BOOL Show) PURE;
563 STDMETHOD(get_ShowPositionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
564 STDMETHOD(put_ShowPositionControls)(VARIANT_BOOL Show) PURE;
565 STDMETHOD(get_ShowTracker)(VARIANT_BOOL __RPC_FAR *Show) PURE;
566 STDMETHOD(put_ShowTracker)(VARIANT_BOOL Show) PURE;
567 STDMETHOD(get_EnablePositionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
568 STDMETHOD(put_EnablePositionControls)(VARIANT_BOOL Enable) PURE;
569 STDMETHOD(get_EnableTracker)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
570 STDMETHOD(put_EnableTracker)(VARIANT_BOOL Enable) PURE;
571 STDMETHOD(get_Enabled)(VARIANT_BOOL __RPC_FAR *pEnabled) PURE;
572 STDMETHOD(put_Enabled)(VARIANT_BOOL pEnabled) PURE;
573 STDMETHOD(get_DisplayForeColor)(VB_OLE_COLOR __RPC_FAR *ForeColor) PURE;
574 STDMETHOD(put_DisplayForeColor)(VB_OLE_COLOR ForeColor) PURE;
575 STDMETHOD(get_DisplayBackColor)(VB_OLE_COLOR __RPC_FAR *BackColor) PURE;
576 STDMETHOD(put_DisplayBackColor)(VB_OLE_COLOR BackColor) PURE;
577 STDMETHOD(get_DisplayMode)(MPDisplayModeConstants __RPC_FAR *pValue) PURE;
578 STDMETHOD(put_DisplayMode)(MPDisplayModeConstants pValue) PURE;
579 STDMETHOD(get_VideoBorder3D)(VARIANT_BOOL __RPC_FAR *pVideoBorderWidth) PURE;
580 STDMETHOD(put_VideoBorder3D)(VARIANT_BOOL pVideoBorderWidth) PURE;
581 STDMETHOD(get_VideoBorderWidth)(long __RPC_FAR *pVideoBorderWidth) PURE;
582 STDMETHOD(put_VideoBorderWidth)(long pVideoBorderWidth) PURE;
583 STDMETHOD(get_VideoBorderColor)(VB_OLE_COLOR __RPC_FAR *pVideoBorderWidth) PURE;
584 STDMETHOD(put_VideoBorderColor)(VB_OLE_COLOR pVideoBorderWidth) PURE;
585 STDMETHOD(get_ShowGotoBar)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
586 STDMETHOD(put_ShowGotoBar)(VARIANT_BOOL pbool) PURE;
587 STDMETHOD(get_ShowStatusBar)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
588 STDMETHOD(put_ShowStatusBar)(VARIANT_BOOL pbool) PURE;
589 STDMETHOD(get_ShowCaptioning)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
590 STDMETHOD(put_ShowCaptioning)(VARIANT_BOOL pbool) PURE;
591 STDMETHOD(get_ShowAudioControls)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
592 STDMETHOD(put_ShowAudioControls)(VARIANT_BOOL pbool) PURE;
593 STDMETHOD(get_CaptioningID)( BSTR __RPC_FAR *pstrText) PURE;
594 STDMETHOD(put_CaptioningID)(BSTR pstrText) PURE;
595 STDMETHOD(get_Mute)(VARIANT_BOOL __RPC_FAR *vbool) PURE;
596 STDMETHOD(put_Mute)(VARIANT_BOOL vbool) PURE;
597 STDMETHOD(get_CanPreview)(VARIANT_BOOL __RPC_FAR *pCanPreview) PURE;
598 STDMETHOD(get_PreviewMode)(VARIANT_BOOL __RPC_FAR *pPreviewMode) PURE;
599 STDMETHOD(put_PreviewMode)(VARIANT_BOOL pPreviewMode) PURE;
600 STDMETHOD(get_HasMultipleItems)(VARIANT_BOOL __RPC_FAR *pHasMuliItems) PURE;
601 STDMETHOD(get_Language)(long __RPC_FAR *pLanguage) PURE;
602 STDMETHOD(put_Language)(long pLanguage) PURE;
603 STDMETHOD(get_AudioStream)(long __RPC_FAR *pStream) PURE;
604 STDMETHOD(put_AudioStream)(long pStream) PURE;
605 STDMETHOD(get_SAMIStyle)(BSTR __RPC_FAR *pbstrStyle) PURE;
606 STDMETHOD(put_SAMIStyle)(BSTR pbstrStyle) PURE;
607 STDMETHOD(get_SAMILang)(BSTR __RPC_FAR *pbstrLang) PURE;
608 STDMETHOD(put_SAMILang)(BSTR pbstrLang) PURE;
609 STDMETHOD(get_SAMIFileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
610 STDMETHOD(put_SAMIFileName)(BSTR pbstrFileName) PURE;
611 STDMETHOD(get_StreamCount)( long __RPC_FAR *pStreamCount) PURE;
612 STDMETHOD(get_ClientId)(BSTR __RPC_FAR *pbstrClientId) PURE;
613 STDMETHOD(get_ConnectionSpeed)(long __RPC_FAR *plConnectionSpeed) PURE;
614 STDMETHOD(get_AutoSize)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
615 STDMETHOD(put_AutoSize)(VARIANT_BOOL pbool) PURE;
616 STDMETHOD(get_EnableFullScreenControls)(VARIANT_BOOL __RPC_FAR *pbVal) PURE;
617 STDMETHOD(put_EnableFullScreenControls)(VARIANT_BOOL pbVal) PURE;
618 STDMETHOD(get_ActiveMovie)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
619 STDMETHOD(get_NSPlay)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
620 STDMETHOD(get_WindowlessVideo)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
621 STDMETHOD(put_WindowlessVideo)(VARIANT_BOOL pbool) PURE;
622 STDMETHOD(Play)(void) PURE;
623 STDMETHOD(Stop)(void) PURE;
624 STDMETHOD(Pause)(void) PURE;
625 STDMETHOD(GetMarkerTime)(long MarkerNum,
626 double __RPC_FAR *pMarkerTime) PURE;
627 STDMETHOD(GetMarkerName)(long MarkerNum,
628 BSTR __RPC_FAR *pbstrMarkerName) PURE;
629 STDMETHOD(AboutBox)(void) PURE;
630 STDMETHOD(GetCodecInstalled)(long CodecNum,
631 VARIANT_BOOL __RPC_FAR *pCodecInstalled) PURE;
632 STDMETHOD(GetCodecDescription)(long CodecNum,
633 BSTR __RPC_FAR *pbstrCodecDescription) PURE;
634 STDMETHOD(GetCodecURL)(long CodecNum,
635 BSTR __RPC_FAR *pbstrCodecURL) PURE;
636 STDMETHOD(GetMoreInfoURL)(MPMoreInfoType MoreInfoType,
637 BSTR __RPC_FAR *pbstrMoreInfoURL) PURE;
638 STDMETHOD(GetMediaInfoString)(MPMediaInfoType MediaInfoType,
639 BSTR __RPC_FAR *pbstrMediaInfo) PURE;
640 STDMETHOD(Cancel)(void) PURE;
641 STDMETHOD(Open)(BSTR bstrFileName) PURE;
642 STDMETHOD(IsSoundCardEnabled)(VARIANT_BOOL __RPC_FAR *pbSoundCard) PURE;
643 STDMETHOD(Next)(void) PURE;
644 STDMETHOD(Previous)(void) PURE;
645 STDMETHOD(StreamSelect)(long StreamNum) PURE;
646 STDMETHOD(FastForward)(void) PURE;
647 STDMETHOD(FastReverse)(void) PURE;
648 STDMETHOD(GetStreamName)(long StreamNum,
649 BSTR __RPC_FAR *pbstrStreamName) PURE;
650 STDMETHOD(GetStreamGroup)(long StreamNum,
651 long __RPC_FAR *pStreamGroup) PURE;
652 STDMETHOD(GetStreamSelected)(long StreamNum, VARIANT_BOOL __RPC_FAR *pStreamSelected) PURE;
653};
654
655struct IMediaPlayer2 : public IMediaPlayer
656{
657 STDMETHOD(get_DVD)(struct IMediaPlayerDvd __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
658 STDMETHOD(GetMediaParameter)(long EntryNum, BSTR bstrParameterName, BSTR __RPC_FAR *pbstrParameterValue) PURE;
659 STDMETHOD(GetMediaParameterName(long EntryNum, long Index, BSTR __RPC_FAR *pbstrParameterName) PURE;
660 STDMETHOD(get_EntryCount)(long __RPC_FAR *pNumberEntries) PURE;
661 STDMETHOD(GetCurrentEntry)(long __RPC_FAR *pEntryNumber) PURE;
662 STDMETHOD(SetCurrentEntry)(long EntryNumber) PURE;
663 STDMETHOD(ShowDialog)(MPShowDialogConstants mpDialogIndex) PURE;
a2a444e3 664};
b11eba7e 665
920a7c15 666//---------------------------------------------------------------------------
c5191fbd 667// NETSHOW COM INTERFACES (dumped from nscompat.idl from MSVC COM Browser)
920a7c15 668//---------------------------------------------------------------------------
c5191fbd
VZ
669
670struct INSOPlay : public IDispatch
671{
672 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
673 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
674 STDMETHOD(get_Duration)(double __RPC_FAR *pDuration) PURE;
675 STDMETHOD(get_Author)(BSTR __RPC_FAR *pbstrAuthor) PURE;
676 STDMETHOD(get_Copyright)(BSTR __RPC_FAR *pbstrCopyright) PURE;
677 STDMETHOD(get_Description)(BSTR __RPC_FAR *pbstrDescription) PURE;
678 STDMETHOD(get_Rating)(BSTR __RPC_FAR *pbstrRating) PURE;
679 STDMETHOD(get_Title)(BSTR __RPC_FAR *pbstrTitle) PURE;
680 STDMETHOD(get_SourceLink)(BSTR __RPC_FAR *pbstrSourceLink) PURE;
681 STDMETHOD(get_MarkerCount)(long __RPC_FAR *pMarkerCount) PURE;
682 STDMETHOD(get_CanScan)(VARIANT_BOOL __RPC_FAR *pCanScan) PURE;
683 STDMETHOD(get_CanSeek)(VARIANT_BOOL __RPC_FAR *pCanSeek) PURE;
684 STDMETHOD(get_CanSeekToMarkers)(VARIANT_BOOL __RPC_FAR *pCanSeekToMarkers) PURE;
685 STDMETHOD(get_CreationDate)(DATE __RPC_FAR *pCreationDate) PURE;
686 STDMETHOD(get_Bandwidth)(long __RPC_FAR *pBandwidth) PURE;
687 STDMETHOD(get_ErrorCorrection)(BSTR __RPC_FAR *pbstrErrorCorrection) PURE;
688 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pAutoStart) PURE;
689 STDMETHOD(put_AutoStart)(VARIANT_BOOL pAutoStart) PURE;
690 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pAutoRewind) PURE;
691 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pAutoRewind) PURE;
692 STDMETHOD(get_AllowChangeControlType)(VARIANT_BOOL __RPC_FAR *pAllowChangeControlType) PURE;
693 STDMETHOD(put_AllowChangeControlType)(VARIANT_BOOL pAllowChangeControlType) PURE;
694 STDMETHOD(get_InvokeURLs)(VARIANT_BOOL __RPC_FAR *pInvokeURLs) PURE;
695 STDMETHOD(put_InvokeURLs)(VARIANT_BOOL pInvokeURLs) PURE;
696 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnableContextMenu) PURE;
697 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnableContextMenu) PURE;
698 STDMETHOD(get_TransparentAtStart)(VARIANT_BOOL __RPC_FAR *pTransparentAtStart) PURE;
699 STDMETHOD(put_TransparentAtStart)(VARIANT_BOOL pTransparentAtStart) PURE;
700 STDMETHOD(get_TransparentOnStop)(VARIANT_BOOL __RPC_FAR *pTransparentOnStop) PURE;
701 STDMETHOD(put_TransparentOnStop)(VARIANT_BOOL pTransparentOnStop) PURE;
702 STDMETHOD(get_ClickToPlay)(VARIANT_BOOL __RPC_FAR *pClickToPlay) PURE;
703 STDMETHOD(put_ClickToPlay)(VARIANT_BOOL pClickToPlay) PURE;
704 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
705 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
706 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pCurrentPosition) PURE;
707 STDMETHOD(put_CurrentPosition)(double pCurrentPosition) PURE;
708 STDMETHOD(get_Rate)(double __RPC_FAR *pRate) PURE;
709 STDMETHOD(put_Rate)(double pRate) PURE;
710 STDMETHOD(get_CurrentMarker)(long __RPC_FAR *pCurrentMarker) PURE;
711 STDMETHOD(put_CurrentMarker)(long pCurrentMarker) PURE;
712 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
713 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
714 STDMETHOD(get_CurrentState)(long __RPC_FAR *pCurrentState) PURE;
715 STDMETHOD(get_DisplaySize)(long __RPC_FAR *pDisplaySize) PURE;
716 STDMETHOD(put_DisplaySize)(long pDisplaySize) PURE;
717 STDMETHOD(get_MainWindow)(long __RPC_FAR *pMainWindow) PURE;
718 STDMETHOD(get_ControlType)(long __RPC_FAR *pControlType) PURE;
719 STDMETHOD(put_ControlType)(long pControlType) PURE;
720 STDMETHOD(get_AllowScan)(VARIANT_BOOL __RPC_FAR *pAllowScan) PURE;
721 STDMETHOD(put_AllowScan)(VARIANT_BOOL pAllowScan) PURE;
722 STDMETHOD(get_SendKeyboardEvents)(VARIANT_BOOL __RPC_FAR *pSendKeyboardEvents) PURE;
723 STDMETHOD(put_SendKeyboardEvents)(VARIANT_BOOL pSendKeyboardEvents) PURE;
724 STDMETHOD(get_SendMouseClickEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseClickEvents) PURE;
725 STDMETHOD(put_SendMouseClickEvents)(VARIANT_BOOL pSendMouseClickEvents) PURE;
726 STDMETHOD(get_SendMouseMoveEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseMoveEvents) PURE;
727 STDMETHOD(put_SendMouseMoveEvents)(VARIANT_BOOL pSendMouseMoveEvents) PURE;
728 STDMETHOD(get_SendStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendStateChangeEvents) PURE;
729 STDMETHOD(put_SendStateChangeEvents)(VARIANT_BOOL pSendStateChangeEvents) PURE;
730 STDMETHOD(get_ReceivedPackets)(long __RPC_FAR *pReceivedPackets) PURE;
731 STDMETHOD(get_RecoveredPackets)(long __RPC_FAR *pRecoveredPackets) PURE;
732 STDMETHOD(get_LostPackets)(long __RPC_FAR *pLostPackets) PURE;
733 STDMETHOD(get_ReceptionQuality)(long __RPC_FAR *pReceptionQuality) PURE;
734 STDMETHOD(get_BufferingCount)(long __RPC_FAR *pBufferingCount) PURE;
735 STDMETHOD(get_CursorType)(long __RPC_FAR *pCursorType) PURE;
736 STDMETHOD(put_CursorType)(long pCursorType) PURE;
737 STDMETHOD(get_AnimationAtStart)(VARIANT_BOOL __RPC_FAR *pAnimationAtStart) PURE;
738 STDMETHOD(put_AnimationAtStart)(VARIANT_BOOL pAnimationAtStart) PURE;
739 STDMETHOD(get_AnimationOnStop)(VARIANT_BOOL __RPC_FAR *pAnimationOnStop) PURE;
740 STDMETHOD(put_AnimationOnStop)(VARIANT_BOOL pAnimationOnStop) PURE;
741 STDMETHOD(Play)(void) PURE;
742 STDMETHOD(Pause)(void) PURE;
743 STDMETHOD(Stop)(void) PURE;
744 STDMETHOD(GetMarkerTime)(long MarkerNum, double __RPC_FAR *pMarkerTime) PURE;
745 STDMETHOD(GetMarkerName)(long MarkerNum, BSTR __RPC_FAR *pbstrMarkerName) PURE;
920a7c15 746};
b11eba7e 747
c5191fbd
VZ
748struct INSPlay : public INSOPlay
749{
750 STDMETHOD(get_ChannelName)(BSTR __RPC_FAR *pbstrChannelName) PURE;
751 STDMETHOD(get_ChannelDescription)(BSTR __RPC_FAR *pbstrChannelDescription) PURE;
752 STDMETHOD(get_ChannelURL)(BSTR __RPC_FAR *pbstrChannelURL) PURE;
753 STDMETHOD(get_ContactAddress)(BSTR __RPC_FAR *pbstrContactAddress) PURE;
754 STDMETHOD(get_ContactPhone)(BSTR __RPC_FAR *pbstrContactPhone) PURE;
755 STDMETHOD(get_ContactEmail)(BSTR __RPC_FAR *pbstrContactEmail) PURE;
756 STDMETHOD(get_AllowChangeDisplaySize)(VARIANT_BOOL __RPC_FAR *pAllowChangeDisplaySize) PURE;
757 STDMETHOD(put_AllowChangeDisplaySize)(VARIANT_BOOL pAllowChangeDisplaySize) PURE;
758 STDMETHOD(get_CodecCount)(long __RPC_FAR *pCodecCount) PURE;
759 STDMETHOD(get_IsBroadcast)(VARIANT_BOOL __RPC_FAR *pIsBroadcast) PURE;
760 STDMETHOD(get_IsDurationValid)(VARIANT_BOOL __RPC_FAR *pIsDurationValid) PURE;
761 STDMETHOD(get_SourceProtocol)(long __RPC_FAR *pSourceProtocol) PURE;
762 STDMETHOD(get_OpenState)(long __RPC_FAR *pOpenState) PURE;
763 STDMETHOD(get_SendOpenStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendOpenStateChangeEvents) PURE;
764 STDMETHOD(put_SendOpenStateChangeEvents)(VARIANT_BOOL pSendOpenStateChangeEvents) PURE;
765 STDMETHOD(get_SendWarningEvents)(VARIANT_BOOL __RPC_FAR *pSendWarningEvents) PURE;
766 STDMETHOD(put_SendWarningEvents)(VARIANT_BOOL pSendWarningEvents) PURE;
767 STDMETHOD(get_SendErrorEvents)(VARIANT_BOOL __RPC_FAR *pSendErrorEvents) PURE;
768 STDMETHOD(put_SendErrorEvents)(VARIANT_BOOL pSendErrorEvents) PURE;
769 STDMETHOD(get_HasError)(VARIANT_BOOL __RPC_FAR *pHasError) PURE;
770 STDMETHOD(get_ErrorDescription)(BSTR __RPC_FAR *pbstrErrorDescription) PURE;
771 STDMETHOD(get_ErrorCode)(long __RPC_FAR *pErrorCode) PURE;
772 STDMETHOD(get_PlayState)(long __RPC_FAR *pPlayState) PURE;
773 STDMETHOD(get_SendPlayStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendPlayStateChangeEvents) PURE;
774 STDMETHOD(put_SendPlayStateChangeEvents)(VARIANT_BOOL pSendPlayStateChangeEvents) PURE;
775 STDMETHOD(get_BufferingTime)(double __RPC_FAR *pBufferingTime) PURE;
776 STDMETHOD(put_BufferingTime)(double pBufferingTime) PURE;
777 STDMETHOD(get_UseFixedUDPPort)(VARIANT_BOOL __RPC_FAR *pUseFixedUDPPort) PURE;
778 STDMETHOD(put_UseFixedUDPPort)(VARIANT_BOOL pUseFixedUDPPort) PURE;
779 STDMETHOD(get_FixedUDPPort)(long __RPC_FAR *pFixedUDPPort) PURE;
780 STDMETHOD(put_FixedUDPPort)(long pFixedUDPPort) PURE;
781 STDMETHOD(get_UseHTTPProxy)(VARIANT_BOOL __RPC_FAR *pUseHTTPProxy) PURE;
782 STDMETHOD(put_UseHTTPProxy)(VARIANT_BOOL pUseHTTPProxy) PURE;
783 STDMETHOD(get_EnableAutoProxy)(VARIANT_BOOL __RPC_FAR *pEnableAutoProxy) PURE;
784 STDMETHOD(put_EnableAutoProxy)(VARIANT_BOOL pEnableAutoProxy) PURE;
785 STDMETHOD(get_HTTPProxyHost)(BSTR __RPC_FAR *pbstrHTTPProxyHost) PURE;
786 STDMETHOD(put_HTTPProxyHost)(BSTR pbstrHTTPProxyHost) PURE;
787 STDMETHOD(get_HTTPProxyPort)(long __RPC_FAR *pHTTPProxyPort) PURE;
788 STDMETHOD(put_HTTPProxyPort)(long pHTTPProxyPort) PURE;
789 STDMETHOD(get_EnableMulticast)(VARIANT_BOOL __RPC_FAR *pEnableMulticast) PURE;
790 STDMETHOD(put_EnableMulticast)(VARIANT_BOOL pEnableMulticast) PURE;
791 STDMETHOD(get_EnableUDP)(VARIANT_BOOL __RPC_FAR *pEnableUDP) PURE;
792 STDMETHOD(put_EnableUDP)(VARIANT_BOOL pEnableUDP) PURE;
793 STDMETHOD(get_EnableTCP)(VARIANT_BOOL __RPC_FAR *pEnableTCP) PURE;
794 STDMETHOD(put_EnableTCP)(VARIANT_BOOL pEnableTCP) PURE;
795 STDMETHOD(get_EnableHTTP)(VARIANT_BOOL __RPC_FAR *pEnableHTTP) PURE;
796 STDMETHOD(put_EnableHTTP)(VARIANT_BOOL pEnableHTTP) PURE;
797 STDMETHOD(get_BufferingProgress)(long __RPC_FAR *pBufferingProgress) PURE;
798 STDMETHOD(get_BaseURL)(BSTR __RPC_FAR *pbstrBaseURL) PURE;
799 STDMETHOD(put_BaseURL)(BSTR pbstrBaseURL) PURE;
800 STDMETHOD(get_DefaultFrame)(BSTR __RPC_FAR *pbstrDefaultFrame) PURE;
801 STDMETHOD(put_DefaultFrame)(BSTR pbstrDefaultFrame) PURE;
802 STDMETHOD(AboutBox))(void) PURE;
803 STDMETHOD(Cancel)(void) PURE;
804 STDMETHOD(GetCodecInstalled)(long CodecNum, VARIANT_BOOL __RPC_FAR *pCodecInstalled) PURE;
805 STDMETHOD(GetCodecDescription)(long CodecNum, BSTR __RPC_FAR *pbstrCodecDescription) PURE;
806 STDMETHOD(GetCodecURL)(long CodecNum, BSTR __RPC_FAR *pbstrCodecURL) PURE;
807 STDMETHOD(Open)(BSTR bstrFileName) PURE;
808};
b11eba7e 809
c5191fbd
VZ
810
811struct INSPlay1 : public INSPlay
920a7c15 812{
c5191fbd 813 STDMETHOD(get_MediaPlayer)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
920a7c15 814};
32f65e50 815
c5191fbd
VZ
816//---------------------------------------------------------------------------
817// MISC COM INTERFACES
818//---------------------------------------------------------------------------
819typedef enum _FilterState
820{
821 State_Stopped,
822 State_Paused,
823 State_Running
824} FILTER_STATE;
825typedef enum _PinDirection {
826 PINDIR_INPUT,
827 PINDIR_OUTPUT
828} PIN_DIRECTION;
829
830typedef struct _FilterInfo {
831 WCHAR achName[128];
832 struct IFilterGraph *pGraph;
833} FILTER_INFO;
834
835typedef struct _PinInfo {
836 struct IBaseFilter *pFilter;
837 PIN_DIRECTION dir;
838 WCHAR achName[128];
839} PIN_INFO;
840
841struct IBaseFilter;
842struct IPin;
843struct IEnumFilters;
844typedef struct _MediaType {
845 GUID majortype;
846 GUID subtype;
847 BOOL bFixedSizeSamples;
848 BOOL bTemporalCompression;
849 ULONG lSampleSize;
850 GUID formattype;
851 IUnknown *pUnk;
852 ULONG cbFormat;
853 BYTE *pbFormat;
854} AM_MEDIA_TYPE;
920a7c15
JS
855
856struct IFilterGraph : public IUnknown
857{
858 STDMETHOD(AddFilter)(IBaseFilter *, LPCWSTR) PURE;
859 STDMETHOD(RemoveFilter)(IBaseFilter *) PURE;
860 STDMETHOD(EnumFilters)(IEnumFilters **) PURE;
861 STDMETHOD(FindFilterByName)(LPCWSTR, IBaseFilter **) PURE;
862 STDMETHOD(ConnectDirect)(IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
863 STDMETHOD(Reconnect)(IPin *) PURE;
864 STDMETHOD(Disconnect)(IPin *) PURE;
865 STDMETHOD(SetDefaultSyncSource)() PURE;
a2a444e3 866};
b11eba7e 867
920a7c15 868struct IGraphBuilder : public IFilterGraph
a2a444e3 869{
920a7c15
JS
870 STDMETHOD(Connect)(IPin *, IPin *) PURE;
871 STDMETHOD(Render)(IPin *) PURE;
872 STDMETHOD(RenderFile)(LPCWSTR, LPCWSTR) PURE;
873 STDMETHOD(AddSourceFilter)(LPCWSTR, LPCWSTR, IBaseFilter **) PURE;
874 STDMETHOD(SetLogFile)(DWORD_PTR) PURE;
875 STDMETHOD(Abort)() PURE;
876 STDMETHOD(ShouldOperationContinue)() PURE;
a2a444e3 877};
b11eba7e 878
c5191fbd
VZ
879struct IReferenceClock;
880struct IEnumPins;
881#define REFERENCE_TIME LONGLONG
882struct IMediaFilter : public IPersist
883{
884 STDMETHOD(Stop)( void) PURE;
885 STDMETHOD(Pause)( void) PURE;
886 STDMETHOD(Run)(REFERENCE_TIME tStart) PURE;
887 STDMETHOD(GetState)(DWORD dwMilliSecsTimeout,
888 FILTER_STATE *State) PURE;
889 STDMETHOD(SetSyncSource)(IReferenceClock *pClock) PURE;
890 STDMETHOD(GetSyncSource)(IReferenceClock **pClock) PURE;
891};
892
893struct IBaseFilter : public IMediaFilter
a2a444e3 894{
c5191fbd
VZ
895 STDMETHOD(EnumPins)(IEnumPins **ppEnum) PURE;
896 STDMETHOD(FindPin)(LPCWSTR Id, IPin **ppPin) PURE;
897 STDMETHOD(QueryFilterInfo)(FILTER_INFO *pInfo) PURE;
898 STDMETHOD(JoinFilterGraph)(IFilterGraph *pGraph, LPCWSTR pName) PURE;
899 STDMETHOD(QueryVendorInfo)(LPWSTR *pVendorInfo) PURE;
900};
901
902//---------------------------------------------------------------------------
903//
904// wxActiveX (Ryan Norton's version :))
905// wxActiveX is (C) 2003 Lindsay Mathieson
906//
907//---------------------------------------------------------------------------
908#define WX_DECLARE_AUTOOLE(wxAutoOleInterface, I) \
909class wxAutoOleInterface \
910{ \
911 protected: \
912 I *m_interface; \
913\
914 public: \
915 explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {} \
916 wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL) \
917 { QueryInterface(riid, pUnk); } \
918 wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL) \
919 { QueryInterface(riid, pDispatch); } \
920 wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)\
921 { CreateInstance(clsid, riid); }\
922 wxAutoOleInterface(const wxAutoOleInterface& ti) : m_interface(NULL)\
923 { operator = (ti); }\
924\
925 wxAutoOleInterface& operator = (const wxAutoOleInterface& ti)\
926 {\
927 if (ti.m_interface)\
928 ti.m_interface->AddRef();\
929 Free();\
930 m_interface = ti.m_interface;\
931 return *this;\
932 }\
933\
934 wxAutoOleInterface& operator = (I *&ti)\
935 {\
936 Free();\
937 m_interface = ti;\
938 return *this;\
939 }\
940\
941 ~wxAutoOleInterface() { Free(); }\
942\
943 inline void Free()\
944 {\
945 if (m_interface)\
946 m_interface->Release();\
947 m_interface = NULL;\
948 }\
949\
950 HRESULT QueryInterface(REFIID riid, IUnknown *pUnk)\
951 {\
952 Free();\
953 wxASSERT(pUnk != NULL);\
954 return pUnk->QueryInterface(riid, (void **) &m_interface);\
955 }\
956\
957 HRESULT CreateInstance(REFCLSID clsid, REFIID riid)\
958 {\
959 Free();\
960 return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface);\
961 }\
962\
963 inline operator I *() const {return m_interface;}\
964 inline I* operator ->() {return m_interface;}\
965 inline I** GetRef() {return &m_interface;}\
966 inline bool Ok() const {return m_interface != NULL;}\
967};
968
969WX_DECLARE_AUTOOLE(wxAutoIDispatch, IDispatch)
970WX_DECLARE_AUTOOLE(wxAutoIOleClientSite, IOleClientSite)
971WX_DECLARE_AUTOOLE(wxAutoIUnknown, IUnknown)
972WX_DECLARE_AUTOOLE(wxAutoIOleObject, IOleObject)
973WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceObject, IOleInPlaceObject)
974WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceActiveObject, IOleInPlaceActiveObject)
975WX_DECLARE_AUTOOLE(wxAutoIOleDocumentView, IOleDocumentView)
976WX_DECLARE_AUTOOLE(wxAutoIViewObject, IViewObject)
977WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
978WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
979WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
980WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
981
982class wxActiveX : public wxWindow
983{
984public:
985 wxActiveX(wxWindow * parent, REFIID iid, IUnknown* pUnk);
986 virtual ~wxActiveX();
987
988 void OnSize(wxSizeEvent&);
989 void OnPaint(wxPaintEvent&);
990 void OnSetFocus(wxFocusEvent&);
991 void OnKillFocus(wxFocusEvent&);
992
993protected:
994 friend class FrameSite;
995
996 wxAutoIDispatch m_Dispatch;
997 wxAutoIOleClientSite m_clientSite;
998 wxAutoIUnknown m_ActiveX;
999 wxAutoIOleObject m_oleObject;
1000 wxAutoIOleInPlaceObject m_oleInPlaceObject;
1001 wxAutoIOleInPlaceActiveObject m_oleInPlaceActiveObject;
1002 wxAutoIOleDocumentView m_docView;
1003 wxAutoIViewObject m_viewObject;
1004 HWND m_oleObjectHWND;
1005 bool m_bAmbientUserMode;
1006 DWORD m_docAdviseCookie;
1007 wxWindow* m_realparent;
1008
1009 void CreateActiveX(REFIID, IUnknown*);
1010};
1011
1012#define DECLARE_OLE_UNKNOWN(cls)\
1013 private:\
1014 class TAutoInitInt\
1015 {\
1016 public:\
1017 LONG l;\
1018 TAutoInitInt() : l(0) {}\
1019 };\
1020 TAutoInitInt refCount, lockCount;\
1021 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
1022 public:\
1023 LONG GetRefCount();\
1024 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
1025 ULONG STDMETHODCALLTYPE AddRef();\
1026 ULONG STDMETHODCALLTYPE Release();\
1027 ULONG STDMETHODCALLTYPE AddLock();\
1028 ULONG STDMETHODCALLTYPE ReleaseLock()
1029
1030#define DEFINE_OLE_TABLE(cls)\
1031 LONG cls::GetRefCount() {return refCount.l;}\
1032 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
1033 {\
1034 if (! ppvObject)\
1035 {\
1036 return E_FAIL;\
1037 };\
1038 const char *desc = NULL;\
1039 cls::_GetInterface(this, iid, ppvObject, desc);\
1040 if (! *ppvObject)\
1041 {\
1042 return E_NOINTERFACE;\
1043 };\
1044 ((IUnknown * )(*ppvObject))->AddRef();\
1045 return S_OK;\
1046 };\
1047 ULONG STDMETHODCALLTYPE cls::AddRef()\
1048 {\
1049 InterlockedIncrement(&refCount.l);\
1050 return refCount.l;\
1051 };\
1052 ULONG STDMETHODCALLTYPE cls::Release()\
1053 {\
1054 if (refCount.l > 0)\
1055 {\
1056 InterlockedDecrement(&refCount.l);\
1057 if (refCount.l == 0)\
1058 {\
1059 delete this;\
1060 return 0;\
1061 };\
1062 return refCount.l;\
1063 }\
1064 else\
1065 return 0;\
1066 }\
1067 ULONG STDMETHODCALLTYPE cls::AddLock()\
1068 {\
1069 InterlockedIncrement(&lockCount.l);\
1070 return lockCount.l;\
1071 };\
1072 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
1073 {\
1074 if (lockCount.l > 0)\
1075 {\
1076 InterlockedDecrement(&lockCount.l);\
1077 return lockCount.l;\
1078 }\
1079 else\
1080 return 0;\
1081 }\
1082 DEFINE_OLE_BASE(cls)
1083
1084#define DEFINE_OLE_BASE(cls)\
1085 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
1086 {\
1087 *_interface = NULL;\
1088 desc = NULL;
1089
1090#define OLE_INTERFACE(_iid, _type)\
1091 if (IsEqualIID(iid, _iid))\
1092 {\
1093 *_interface = (IUnknown *) (_type *) self;\
1094 desc = # _iid;\
1095 return;\
1096 }
1097
1098#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
1099
1100#define OLE_INTERFACE_CUSTOM(func)\
1101 if (func(self, iid, _interface, desc))\
1102 {\
1103 return;\
1104 }
1105
1106#define END_OLE_TABLE\
1107 }
1108
1109
1110class FrameSite :
1111 public IOleClientSite,
1112 public IOleInPlaceSiteEx,
1113 public IOleInPlaceFrame,
1114 public IOleItemContainer,
1115 public IDispatch,
1116 public IOleCommandTarget,
1117 public IOleDocumentSite,
1118 public IAdviseSink,
1119 public IOleControlSite
1120{
1121private:
1122 DECLARE_OLE_UNKNOWN(FrameSite);
1123
a2a444e3 1124public:
c5191fbd
VZ
1125 FrameSite(wxWindow * win, wxActiveX * win2)
1126 {
1127 m_window = win2;
1128 m_bSupportsWindowlessActivation = true;
1129 m_bInPlaceLocked = false;
1130 m_bUIActive = false;
1131 m_bInPlaceActive = false;
1132 m_bWindowless = false;
1133
1134 m_nAmbientLocale = 0;
1135 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
1136 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
1137 m_bAmbientShowHatching = true;
1138 m_bAmbientShowGrabHandles = true;
1139 m_bAmbientAppearance = true;
1140
1141 m_hDCBuffer = NULL;
1142 m_hWndParent = (HWND)win->GetHWND();
1143 }
1144 virtual ~FrameSite(){}
1145 //***************************IDispatch*****************************
1146 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
1147 unsigned int , LCID ,
1148 DISPID * )
1149 { return E_NOTIMPL; }
1150 STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
1151 { return E_NOTIMPL; }
1152 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
1153 { return E_NOTIMPL; }
1154 HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID,
1155 WORD wFlags, DISPPARAMS *,
1156 VARIANT * pVarResult, EXCEPINFO *,
1157 unsigned int *)
1158 {
1159 if (!(wFlags & DISPATCH_PROPERTYGET))
1160 return S_OK;
1161
1162 if (pVarResult == NULL)
1163 return E_INVALIDARG;
b11eba7e 1164
c5191fbd
VZ
1165 //The most common case is boolean, use as an initial type
1166 V_VT(pVarResult) = VT_BOOL;
1167
1168 switch (dispIdMember)
1169 {
1170 case DISPID_AMBIENT_MESSAGEREFLECT:
1171 V_BOOL(pVarResult)= FALSE;
1172 return S_OK;
1173
1174 case DISPID_AMBIENT_DISPLAYASDEFAULT:
1175 V_BOOL(pVarResult)= TRUE;
1176 return S_OK;
1177
1178 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1179 V_BOOL(pVarResult) = TRUE;
1180 return S_OK;
1181
1182 case DISPID_AMBIENT_SILENT:
1183 V_BOOL(pVarResult)= TRUE;
1184 return S_OK;
1185
1186 case DISPID_AMBIENT_APPEARANCE:
1187 pVarResult->vt = VT_BOOL;
1188 pVarResult->boolVal = m_bAmbientAppearance;
1189 break;
1190
1191 case DISPID_AMBIENT_FORECOLOR:
1192 pVarResult->vt = VT_I4;
1193 pVarResult->lVal = (long) m_clrAmbientForeColor;
1194 break;
1195
1196 case DISPID_AMBIENT_BACKCOLOR:
1197 pVarResult->vt = VT_I4;
1198 pVarResult->lVal = (long) m_clrAmbientBackColor;
1199 break;
1200
1201 case DISPID_AMBIENT_LOCALEID:
1202 pVarResult->vt = VT_I4;
1203 pVarResult->lVal = (long) m_nAmbientLocale;
1204 break;
1205
1206 case DISPID_AMBIENT_USERMODE:
1207 pVarResult->vt = VT_BOOL;
1208 pVarResult->boolVal = m_window->m_bAmbientUserMode;
1209 break;
1210
1211 case DISPID_AMBIENT_SHOWGRABHANDLES:
1212 pVarResult->vt = VT_BOOL;
1213 pVarResult->boolVal = m_bAmbientShowGrabHandles;
1214 break;
1215
1216 case DISPID_AMBIENT_SHOWHATCHING:
1217 pVarResult->vt = VT_BOOL;
1218 pVarResult->boolVal = m_bAmbientShowHatching;
1219 break;
1220
1221 default:
1222 return DISP_E_MEMBERNOTFOUND;
1223 }
1224
1225 return S_OK;
1226 }
1227
1228 //**************************IOleWindow***************************
1229 HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
1230 {
1231 if (phwnd == NULL)
1232 return E_INVALIDARG;
1233 (*phwnd) = m_hWndParent;
1234 return S_OK;
1235 }
1236 HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
1237 {return S_OK;}
1238 //**************************IOleInPlaceUIWindow*****************
1239 HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
1240 {
1241 if (lprectBorder == NULL)
1242 return E_INVALIDARG;
1243 return INPLACE_E_NOTOOLSPACE;
1244 }
1245 HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
1246 {
1247 if (pborderwidths == NULL)
1248 return E_INVALIDARG;
1249 return INPLACE_E_NOTOOLSPACE;
1250 }
1251 HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
1252 {return S_OK;}
1253 HRESULT STDMETHODCALLTYPE SetActiveObject(
1254 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR)
1255 {
1256 if (pActiveObject)
1257 pActiveObject->AddRef();
1258
1259 m_window->m_oleInPlaceActiveObject = pActiveObject;
1260 return S_OK;
1261 }
1262
1263 //********************IOleInPlaceFrame************************
1264
1265 STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
1266 STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;}
1267 STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
1268 STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
1269 HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
1270 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
1271 {
1272 // TODO: send an event with this id
1273 if (m_window->m_oleInPlaceActiveObject.Ok())
1274 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
1275 return S_FALSE;
1276 }
1277
1278 //*******************IOleInPlaceSite**************************
1279 HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
1280 HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
1281 { m_bInPlaceActive = true; return S_OK; }
1282 HRESULT STDMETHODCALLTYPE OnUIActivate()
1283 { m_bUIActive = true; return S_OK; }
1284 HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame,
1285 IOleInPlaceUIWindow **ppDoc,
1286 LPRECT lprcPosRect,
1287 LPRECT lprcClipRect,
1288 LPOLEINPLACEFRAMEINFO lpFrameInfo)
1289 {
1290 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
1291 lprcClipRect == NULL || lpFrameInfo == NULL)
1292 {
1293 if (ppFrame != NULL)
1294 (*ppFrame) = NULL;
1295 if (ppDoc != NULL)
1296 (*ppDoc) = NULL;
1297 return E_INVALIDARG;
1298 }
1299
1300 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
1301 if (! SUCCEEDED(hr))
1302 {
1303 return E_UNEXPECTED;
1304 };
1305
1306 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
1307 if (! SUCCEEDED(hr))
1308 {
1309 (*ppFrame)->Release();
1310 *ppFrame = NULL;
1311 return E_UNEXPECTED;
1312 };
1313
1314 RECT rect;
1315 ::GetClientRect(m_hWndParent, &rect);
1316 if (lprcPosRect)
1317 {
1318 lprcPosRect->left = lprcPosRect->top = 0;
1319 lprcPosRect->right = rect.right;
1320 lprcPosRect->bottom = rect.bottom;
1321 };
1322 if (lprcClipRect)
1323 {
1324 lprcClipRect->left = lprcClipRect->top = 0;
1325 lprcClipRect->right = rect.right;
1326 lprcClipRect->bottom = rect.bottom;
1327 };
1328
1329 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
1330 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
1331 lpFrameInfo->hwndFrame = m_hWndParent;
1332
1333 return S_OK;
1334 }
1335 HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;}
1336 HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL)
1337 { m_bUIActive = false; return S_OK; }
1338 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate()
1339 { m_bInPlaceActive = false; return S_OK; }
1340 HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;}
1341 HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
1342 HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
1343 {
1344 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
1345 {
1346 m_window->m_oleInPlaceObject->SetObjectRects(
1347 lprcPosRect, lprcPosRect);
1348 }
1349 return S_OK;
1350 }
1351 //*************************IOleInPlaceSiteEx***********************
1352 HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
1353 {
1354 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
1355 if (pfNoRedraw)
1356 (*pfNoRedraw) = FALSE;
1357 return S_OK;
1358 }
1359
1360 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
1361 {
1362 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
1363 return S_OK;
1364 }
1365 STDMETHOD(RequestUIActivate)(){ return S_OK;}
1366 //*************************IOleClientSite**************************
1367 HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
1368 const char *OleGetMonikerToStr(DWORD dwAssign)
1369 {
1370 switch (dwAssign)
1371 {
1372 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
1373 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
1374 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
1375 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
1376 default : return "Bad Enum";
1377 };
1378 };
1379
1380 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
1381 {
1382 switch(dwWhichMoniker)
1383 {
1384 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
1385 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
1386 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
1387 default : return "Bad Enum";
1388 };
1389 };
1390 STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
1391 HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
1392 {
1393 if (ppContainer == NULL)
1394 return E_INVALIDARG;
1395 HRESULT hr = QueryInterface(
1396 IID_IOleContainer, (void**)(ppContainer));
1397 wxASSERT(SUCCEEDED(hr));
1398 return hr;
1399 }
1400 HRESULT STDMETHODCALLTYPE ShowObject()
1401 {
1402 if (m_window->m_oleObjectHWND)
1403 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
1404 return S_OK;
1405 }
1406 STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
1407 STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
1408 //********************IParseDisplayName***************************
1409 HRESULT STDMETHODCALLTYPE ParseDisplayName(
1410 IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
1411 //********************IOleContainer*******************************
1412 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
1413 HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
1414 //********************IOleItemContainer***************************
1415 HRESULT STDMETHODCALLTYPE
1416 #ifdef _UNICODE
1417 GetObjectW
1418 #else
1419 GetObjectA
1420 #endif
1421 (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
1422 {
1423 if (pszItem == NULL || ppvObject == NULL)
1424 return E_INVALIDARG;
1425 *ppvObject = NULL;
1426 return MK_E_NOOBJECT;
1427 }
1428 HRESULT STDMETHODCALLTYPE GetObjectStorage(
1429 LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
1430 {
1431 if (pszItem == NULL || ppvStorage == NULL)
1432 return E_INVALIDARG;
1433 *ppvStorage = NULL;
1434 return MK_E_NOOBJECT;
1435 }
1436 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
1437 {
1438 if (pszItem == NULL)
1439 return E_INVALIDARG;
1440 return MK_E_NOOBJECT;
1441 }
1442 //***********************IOleControlSite*****************************
1443 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
1444 {return S_OK;}
1445 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
1446 {
1447 m_bInPlaceLocked = (fLock) ? true : false;
1448 return S_OK;
1449 }
1450 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
1451 {return E_NOTIMPL;}
1452 HRESULT STDMETHODCALLTYPE TransformCoords(
1453 POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
1454 {
1455 if (pPtlHimetric == NULL || pPtfContainer == NULL)
1456 return E_INVALIDARG;
1457 return E_NOTIMPL;
1458 }
1459 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
1460 {return E_NOTIMPL;}
1461 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
1462 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
1463 //**************************IOleCommandTarget***********************
1464 HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
c9e4ece6 1465 OLECMD prgCmds[], OLECMDTEXT *)
c5191fbd
VZ
1466 {
1467 if (prgCmds == NULL) return E_INVALIDARG;
1468 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
1469 {
1470 // unsupported by default
1471 prgCmds[nCmd].cmdf = 0;
1472 }
1473 return OLECMDERR_E_UNKNOWNGROUP;
1474 }
1475
1476 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
1477 DWORD, VARIANTARG *, VARIANTARG *)
1478 {return OLECMDERR_E_NOTSUPPORTED;}
1479
1480 //**********************IAdviseSink************************************
1481 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
1482 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
1483 void STDMETHODCALLTYPE OnRename(IMoniker *){}
1484 void STDMETHODCALLTYPE OnSave(){}
1485 void STDMETHODCALLTYPE OnClose(){}
1486
1487 //**********************IOleDocumentSite***************************
1488 HRESULT STDMETHODCALLTYPE ActivateMe(
1489 IOleDocumentView __RPC_FAR *pViewToActivate)
1490 {
1491 wxAutoIOleInPlaceSite inPlaceSite(
1492 IID_IOleInPlaceSite, (IDispatch *) this);
1493 if (!inPlaceSite.Ok())
1494 return E_FAIL;
1495
1496 if (pViewToActivate)
1497 {
1498 m_window->m_docView = pViewToActivate;
1499 m_window->m_docView->SetInPlaceSite(inPlaceSite);
1500 }
1501 else
1502 {
1503 wxAutoIOleDocument oleDoc(
1504 IID_IOleDocument, m_window->m_oleObject);
1505 if (! oleDoc.Ok())
1506 return E_FAIL;
1507
1508 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
1509 0, m_window->m_docView.GetRef());
1510 if (hr != S_OK)
1511 return E_FAIL;
1512
1513 m_window->m_docView->SetInPlaceSite(inPlaceSite);
1514 };
1515
1516 m_window->m_docView->UIActivate(TRUE);
1517 return S_OK;
1518 };
1519
1520
1521protected:
1522 wxActiveX * m_window;
1523
1524 HDC m_hDCBuffer;
1525 HWND m_hWndParent;
1526
1527 bool m_bSupportsWindowlessActivation;
1528 bool m_bInPlaceLocked;
1529 bool m_bInPlaceActive;
1530 bool m_bUIActive;
1531 bool m_bWindowless;
1532
1533 LCID m_nAmbientLocale;
1534 COLORREF m_clrAmbientForeColor;
1535 COLORREF m_clrAmbientBackColor;
1536 bool m_bAmbientShowHatching;
1537 bool m_bAmbientShowGrabHandles;
1538 bool m_bAmbientAppearance;
a2a444e3
RN
1539};
1540
c5191fbd
VZ
1541DEFINE_OLE_TABLE(FrameSite)
1542 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
1543 OLE_IINTERFACE(IOleClientSite)
1544 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
1545 OLE_IINTERFACE(IOleInPlaceSite)
1546 OLE_IINTERFACE(IOleInPlaceSiteEx)
1547 OLE_IINTERFACE(IOleInPlaceUIWindow)
1548 OLE_IINTERFACE(IOleInPlaceFrame)
1549 OLE_IINTERFACE(IParseDisplayName)
1550 OLE_IINTERFACE(IOleContainer)
1551 OLE_IINTERFACE(IOleItemContainer)
1552 OLE_IINTERFACE(IDispatch)
1553 OLE_IINTERFACE(IOleCommandTarget)
1554 OLE_IINTERFACE(IOleDocumentSite)
1555 OLE_IINTERFACE(IAdviseSink)
1556 OLE_IINTERFACE(IOleControlSite)
1557END_OLE_TABLE;
1558
1559
1560wxActiveX::wxActiveX(wxWindow * parent, REFIID iid, IUnknown* pUnk)
1561 : m_realparent(parent)
1562{
1563 m_bAmbientUserMode = true;
1564 m_docAdviseCookie = 0;
1565 CreateActiveX(iid, pUnk);
1566}
1567
1568wxActiveX::~wxActiveX()
1569{
1570 // disconnect connection points
1571 if (m_oleInPlaceObject.Ok())
1572 {
1573 m_oleInPlaceObject->InPlaceDeactivate();
1574 m_oleInPlaceObject->UIDeactivate();
1575 }
1576
1577 if (m_oleObject.Ok())
1578 {
1579 if (m_docAdviseCookie != 0)
1580 m_oleObject->Unadvise(m_docAdviseCookie);
1581
1582 m_oleObject->DoVerb(
1583 OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
1584 m_oleObject->Close(OLECLOSE_NOSAVE);
1585 m_oleObject->SetClientSite(NULL);
1586 }
1587}
1588
1589void wxActiveX::CreateActiveX(REFIID iid, IUnknown* pUnk)
1590{
1591 HRESULT hret;
1592 hret = m_ActiveX.QueryInterface(iid, pUnk);
1593 wxASSERT(SUCCEEDED(hret));
1594
1595 // FrameSite
1596 FrameSite *frame = new FrameSite(m_realparent, this);
1597 // oleClientSite
1598 hret = m_clientSite.QueryInterface(
1599 IID_IOleClientSite, (IDispatch *) frame);
1600 wxASSERT(SUCCEEDED(hret));
1601 // adviseSink
1602 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
1603 wxASSERT(adviseSink.Ok());
1604
1605 // Get Dispatch interface
1606 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
1607
1608 // Get IOleObject interface
1609 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
1610 wxASSERT(SUCCEEDED(hret));
1611
1612 // get IViewObject Interface
1613 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
1614 wxASSERT(SUCCEEDED(hret));
1615
1616 // document advise
1617 m_docAdviseCookie = 0;
1618 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
1619 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
1620 OleSetContainedObject(m_oleObject, TRUE);
1621 OleRun(m_oleObject);
1622
1623
1624 // Get IOleInPlaceObject interface
1625 hret = m_oleInPlaceObject.QueryInterface(
1626 IID_IOleInPlaceObject, m_ActiveX);
1627 wxASSERT(SUCCEEDED(hret));
1628
1629 // status
1630 DWORD dwMiscStatus;
1631 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
1632 wxASSERT(SUCCEEDED(hret));
1633
1634 // set client site first ?
1635 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
1636 m_oleObject->SetClientSite(m_clientSite);
1637
1638
1639 // stream init
1640 wxAutoIPersistStreamInit
1641 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
1642
1643 if (pPersistStreamInit.Ok())
1644 {
1645 hret = pPersistStreamInit->InitNew();
1646 }
1647
1648 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
1649 m_oleObject->SetClientSite(m_clientSite);
1650
1651
1652 RECT posRect;
1653 ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
1654
1655 m_oleObjectHWND = 0;
1656
1657 if (m_oleInPlaceObject.Ok())
1658 {
1659 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1660 if (SUCCEEDED(hret))
1661 ::SetActiveWindow(m_oleObjectHWND);
1662 }
1663
1664
1665 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
1666 {
1667 if (posRect.right > 0 && posRect.bottom > 0 &&
1668 m_oleInPlaceObject.Ok())
1669 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1670
1671 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
1672 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
1673 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
1674 (HWND)m_realparent->GetHWND(), &posRect);
1675 }
1676
1677 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
1678 {
1679 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1680 }
1681
1682 if (m_oleObjectHWND)
1683 {
1684 ::SetActiveWindow(m_oleObjectHWND);
1685 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
1686
1687 this->AssociateHandle(m_oleObjectHWND);
1688 this->Reparent(m_realparent);
1689
1690 wxWindow* pWnd = m_realparent;
1691 int id = m_realparent->GetId();
1692
1693 pWnd->Connect(id, wxEVT_SIZE,
1694 wxSizeEventHandler(wxActiveX::OnSize), 0, this);
1695 pWnd->Connect(id, wxEVT_SET_FOCUS,
1696 wxFocusEventHandler(wxActiveX::OnSetFocus), 0, this);
1697 pWnd->Connect(id, wxEVT_KILL_FOCUS,
1698 wxFocusEventHandler(wxActiveX::OnKillFocus), 0, this);
1699 }
1700}
1701
1702#define HIMETRIC_PER_INCH 2540
1703#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
1704
1705static void PixelsToHimetric(SIZEL &sz)
1706{
1707 static int logX = 0;
1708 static int logY = 0;
1709
1710 if (logY == 0)
1711 {
1712 // initaliase
1713 HDC dc = GetDC(NULL);
1714 logX = GetDeviceCaps(dc, LOGPIXELSX);
1715 logY = GetDeviceCaps(dc, LOGPIXELSY);
1716 ReleaseDC(NULL, dc);
1717 };
1718
1719#define HIMETRIC_INCH 2540
1720#define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
1721
1722 sz.cx = CONVERT(sz.cx, logX);
1723 sz.cy = CONVERT(sz.cy, logY);
1724
1725#undef CONVERT
1726#undef HIMETRIC_INCH
1727}
1728
1729
1730void wxActiveX::OnSize(wxSizeEvent& event)
1731{
1732 int w, h;
1733 GetParent()->GetClientSize(&w, &h);
1734
1735 RECT posRect;
1736 posRect.left = 0;
1737 posRect.top = 0;
1738 posRect.right = w;
1739 posRect.bottom = h;
1740
1741 if (w <= 0 && h <= 0)
1742 return;
1743
1744 // extents are in HIMETRIC units
1745 if (m_oleObject.Ok())
1746 {
1747 SIZEL sz = {w, h};
1748 PixelsToHimetric(sz);
1749
1750 SIZEL sz2;
1751
1752 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1753 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
1754 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
1755 };
1756
1757 if (m_oleInPlaceObject.Ok())
1758 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1759
1760 event.Skip();
1761}
1762
1763void wxActiveX::OnPaint(wxPaintEvent& WXUNUSED(event))
1764{
1765 wxPaintDC dc(this);
1766 // Draw only when control is windowless or deactivated
1767 if (m_viewObject)
1768 {
1769 dc.BeginDrawing();
1770 int w, h;
1771 GetParent()->GetSize(&w, &h);
1772 RECT posRect;
1773 posRect.left = 0;
1774 posRect.top = 0;
1775 posRect.right = w;
1776 posRect.bottom = h;
1777
1778 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
1779 RECTL *prcBounds = (RECTL *) &posRect;
1780 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1781 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
1782
1783 dc.EndDrawing();
1784 }
1785
1786// We've got this one I think
1787// event.Skip();
1788}
1789
1790void wxActiveX::OnSetFocus(wxFocusEvent& event)
1791{
1792 if (m_oleInPlaceActiveObject.Ok())
1793 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1794
1795 event.Skip();
1796}
1797
1798void wxActiveX::OnKillFocus(wxFocusEvent& event)
1799{
1800 if (m_oleInPlaceActiveObject.Ok())
1801 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1802
1803 event.Skip();
1804}
1805
1806//###########################################################################
1807//
1808//
1809// wxAMMediaBackend
1810//
1811//
1812//###########################################################################
1813
1814typedef BOOL (WINAPI* LPAMGETERRORTEXT)(HRESULT, wxChar *, DWORD);
1815
7e41b689 1816class WXDLLIMPEXP_MEDIA wxAMMediaBackend : public wxMediaBackendCommonBase
1a680109
RN
1817{
1818public:
ff4aedc5 1819 wxAMMediaBackend();
ff4aedc5 1820 virtual ~wxAMMediaBackend();
c5191fbd 1821 void Clear();
1a680109 1822
226ec5a7 1823 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 1824 wxWindowID id,
226ec5a7 1825 const wxPoint& pos,
ff4aedc5 1826 const wxSize& size,
226ec5a7 1827 long style,
ff4aedc5
RN
1828 const wxValidator& validator,
1829 const wxString& name);
1a680109
RN
1830
1831 virtual bool Play();
1832 virtual bool Pause();
1833 virtual bool Stop();
1834
1835 virtual bool Load(const wxString& fileName);
1836 virtual bool Load(const wxURI& location);
c5191fbd
VZ
1837 virtual bool Load(const wxURI& location, const wxURI& proxy);
1838
1839 bool DoLoad(const wxString& location);
1840 void FinishLoad();
1a680109
RN
1841
1842 virtual wxMediaState GetState();
1843
ff4aedc5
RN
1844 virtual bool SetPosition(wxLongLong where);
1845 virtual wxLongLong GetPosition();
1846 virtual wxLongLong GetDuration();
1a680109 1847
ff4aedc5
RN
1848 virtual void Move(int x, int y, int w, int h);
1849 wxSize GetVideoSize() const;
1a680109
RN
1850
1851 virtual double GetPlaybackRate();
1852 virtual bool SetPlaybackRate(double);
1853
6f8c67e7
JS
1854 virtual double GetVolume();
1855 virtual bool SetVolume(double);
1856
c5191fbd 1857 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
1a680109 1858 void Cleanup();
920a7c15 1859
c5191fbd
VZ
1860 void DoGetDownloadProgress(wxLongLong*, wxLongLong*);
1861 virtual wxLongLong GetDownloadProgress()
1862 {
1863 wxLongLong progress, total;
1864 DoGetDownloadProgress(&progress, &total);
1865 return progress;
1866 }
1867 virtual wxLongLong GetDownloadTotal()
1868 {
1869 wxLongLong progress, total;
1870 DoGetDownloadProgress(&progress, &total);
1871 return total;
1872 }
1a680109 1873
c5191fbd
VZ
1874 wxActiveX* m_pAX;
1875 IActiveMovie* m_pAM;
1876 IMediaPlayer* m_pMP;
1877 wxTimer* m_pTimer;
1a680109 1878 wxSize m_bestSize;
aa200e97 1879
920a7c15 1880#ifdef __WXDEBUG__
aa200e97 1881 wxDynamicLibrary m_dllQuartz;
920a7c15 1882 LPAMGETERRORTEXT m_lpAMGetErrorText;
a3c1ce50 1883 wxString GetErrorString(HRESULT hrdsv);
aa200e97 1884#endif // __WXDEBUG__
920a7c15 1885
19b6f122 1886 DECLARE_DYNAMIC_CLASS(wxAMMediaBackend)
1a680109
RN
1887};
1888
1a680109 1889//---------------------------------------------------------------------------
ff4aedc5
RN
1890//
1891// wxMCIMediaBackend
1892//
1a680109
RN
1893//---------------------------------------------------------------------------
1894
ff4aedc5
RN
1895//---------------------------------------------------------------------------
1896// MCI Includes
1897//---------------------------------------------------------------------------
1a680109 1898#include <mmsystem.h>
1a680109 1899
7e41b689 1900class WXDLLIMPEXP_MEDIA wxMCIMediaBackend : public wxMediaBackendCommonBase
1a680109
RN
1901{
1902public:
3f9a3bf9 1903
ff4aedc5
RN
1904 wxMCIMediaBackend();
1905 ~wxMCIMediaBackend();
1a680109 1906
226ec5a7 1907 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 1908 wxWindowID id,
226ec5a7 1909 const wxPoint& pos,
ff4aedc5 1910 const wxSize& size,
226ec5a7 1911 long style,
ff4aedc5
RN
1912 const wxValidator& validator,
1913 const wxString& name);
1a680109
RN
1914
1915 virtual bool Play();
1916 virtual bool Pause();
1917 virtual bool Stop();
1918
3832f946
WS
1919 virtual bool Load(const wxURI& location,
1920 const wxURI& proxy)
1921 { return wxMediaBackend::Load(location, proxy); }
1922
1a680109
RN
1923 virtual bool Load(const wxString& fileName);
1924 virtual bool Load(const wxURI& location);
1925
1926 virtual wxMediaState GetState();
1927
ff4aedc5
RN
1928 virtual bool SetPosition(wxLongLong where);
1929 virtual wxLongLong GetPosition();
1930 virtual wxLongLong GetDuration();
1a680109 1931
ff4aedc5
RN
1932 virtual void Move(int x, int y, int w, int h);
1933 wxSize GetVideoSize() const;
1a680109
RN
1934
1935 virtual double GetPlaybackRate();
ff4aedc5 1936 virtual bool SetPlaybackRate(double dRate);
3f9a3bf9 1937
6f8c67e7
JS
1938 virtual double GetVolume();
1939 virtual bool SetVolume(double);
1940
226ec5a7 1941 static LRESULT CALLBACK NotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 1942 WPARAM wParam, LPARAM lParam);
5987f174 1943
226ec5a7 1944 LRESULT CALLBACK OnNotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 1945 WPARAM wParam, LPARAM lParam);
1a680109 1946
ff4aedc5 1947 MCIDEVICEID m_hDev; //Our MCI Device ID/Handler
ff4aedc5
RN
1948 HWND m_hNotifyWnd; //Window to use for MCI events
1949 bool m_bVideo; //Whether or not we have video
1950
3839f37e 1951 DECLARE_DYNAMIC_CLASS(wxMCIMediaBackend)
ff4aedc5 1952};
1a680109
RN
1953
1954//---------------------------------------------------------------------------
1955//
ff4aedc5 1956// wxQTMediaBackend
1a680109 1957//
c5191fbd
VZ
1958// We don't include Quicktime headers here and define all the types
1959// ourselves because looking for the quicktime libaries etc. would
1960// be tricky to do and making this a dependency for the MSVC projects
1961// would be unrealistic.
1962//
1963// Thanks to Robert Roebling for the wxDL macro/library idea
1a680109
RN
1964//---------------------------------------------------------------------------
1965
ff4aedc5
RN
1966//---------------------------------------------------------------------------
1967// QT Includes
1968//---------------------------------------------------------------------------
d7a9c895
RN
1969//#include <qtml.h> //Windoze QT include
1970//#include <QuickTimeComponents.h> //Standard QT stuff
1971#include "wx/dynlib.h"
1972
1973//---------------------------------------------------------------------------
1974// QT Types
1975//---------------------------------------------------------------------------
1976typedef struct MovieRecord* Movie;
1977typedef wxInt16 OSErr;
1978typedef wxInt32 OSStatus;
1979#define noErr 0
1980#define fsRdPerm 1
1981typedef unsigned char Str255[256];
1982#define StringPtr unsigned char*
1983#define newMovieActive 1
c5191fbd 1984#define newMovieAsyncOK (1 << 8)
b11eba7e 1985#define Ptr char*
d7a9c895
RN
1986#define Handle Ptr*
1987#define Fixed long
1988#define OSType unsigned long
b11eba7e 1989#define CGrafPtr struct GrafPort *
d7a9c895 1990#define TimeScale long
b11eba7e 1991#define TimeBase struct TimeBaseRecord *
c5191fbd
VZ
1992typedef struct ComponentInstanceRecord * ComponentInstance;
1993#define kMovieLoadStatePlayable 10000
1994#define Boolean int
1995#define MovieController ComponentInstance
d7a9c895 1996
19b6f122
WS
1997#ifndef URLDataHandlerSubType
1998#if defined(__WATCOMC__) || defined(__MINGW32__)
1999// use magic numbers for compilers which complain about multicharacter integers
2000const OSType URLDataHandlerSubType = 1970433056;
2001const OSType VisualMediaCharacteristic = 1702454643;
2002#else
2003const OSType URLDataHandlerSubType = 'url ';
2004const OSType VisualMediaCharacteristic = 'eyes';
2005#endif
2006#endif
2007
d7a9c895 2008struct FSSpec {
600ffb32
WS
2009 short vRefNum;
2010 long parID;
2011 Str255 name; /*Str63 on mac, Str255 on msw */
d7a9c895
RN
2012};
2013
2014struct Rect {
600ffb32
WS
2015 short top;
2016 short left;
2017 short bottom;
2018 short right;
d7a9c895
RN
2019};
2020
2021struct wide {
600ffb32
WS
2022 wxInt32 hi;
2023 wxUint32 lo;
d7a9c895
RN
2024};
2025
2026struct TimeRecord {
600ffb32
WS
2027 wide value; /* units */
2028 TimeScale scale; /* units per second */
2029 TimeBase base;
d7a9c895
RN
2030};
2031
c5191fbd
VZ
2032struct Point {
2033 short v;
2034 short h;
2035};
2036
2037struct EventRecord {
2038 wxUint16 what;
2039 wxUint32 message;
2040 wxUint32 when;
2041 Point where;
2042 wxUint16 modifiers;
2043};
2044
2045enum {
2046 mcTopLeftMovie = 1,
2047 mcScaleMovieToFit = 2,
2048 mcWithBadge = 4,
2049 mcNotVisible = 8,
2050 mcWithFrame = 16
2051};
2052
d7a9c895
RN
2053//---------------------------------------------------------------------------
2054// QT Library
2055//---------------------------------------------------------------------------
2056#define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
2057 typedef rettype (* name ## Type) args ; \
2058 name ## Type pfn_ ## name; \
2059 rettype name args \
2060 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
b11eba7e 2061
d7a9c895
RN
2062#define wxDL_VOIDMETHOD_DEFINE( name, args, shortargs ) \
2063 typedef void (* name ## Type) args ; \
2064 name ## Type pfn_ ## name; \
2065 void name args \
2066 { if (m_ok) pfn_ ## name shortargs ; }
2067
2068#define wxDL_METHOD_LOAD( lib, name, success ) \
2069 pfn_ ## name = (name ## Type) lib.GetSymbol( wxT(#name), &success ); \
3131207f 2070 if (!success) { wxLog::EnableLogging(bWasLoggingEnabled); return false; }
32f65e50 2071
d7a9c895 2072
b11eba7e 2073class WXDLLIMPEXP_MEDIA wxQuickTimeLibrary
d7a9c895
RN
2074{
2075public:
2076 ~wxQuickTimeLibrary()
b11eba7e 2077 {
d7a9c895
RN
2078 if(m_dll.IsLoaded())
2079 m_dll.Unload();
2080 }
2081
2082 bool Initialize();
2083 bool IsOk() const {return m_ok;}
2084
2085protected:
2086 wxDynamicLibrary m_dll;
2087 bool m_ok;
2088
2089public:
2090 wxDL_VOIDMETHOD_DEFINE( StartMovie, (Movie m), (m) );
2091 wxDL_VOIDMETHOD_DEFINE( StopMovie, (Movie m), (m) );
2092 wxDL_METHOD_DEFINE( bool, IsMovieDone, (Movie m), (m), false);
2093 wxDL_VOIDMETHOD_DEFINE( GoToBeginningOfMovie, (Movie m), (m) );
2094 wxDL_METHOD_DEFINE( OSErr, GetMoviesError, (), (), -1);
2095 wxDL_METHOD_DEFINE( OSErr, EnterMovies, (), (), -1);
2096 wxDL_VOIDMETHOD_DEFINE( ExitMovies, (), () );
2097 wxDL_METHOD_DEFINE( OSErr, InitializeQTML, (long flags), (flags), -1);
2098 wxDL_VOIDMETHOD_DEFINE( TerminateQTML, (), () );
2099
b11eba7e
WS
2100 wxDL_METHOD_DEFINE( OSErr, NativePathNameToFSSpec,
2101 (char* inName, FSSpec* outFile, long flags),
d7a9c895
RN
2102 (inName, outFile, flags), -1);
2103
b11eba7e 2104 wxDL_METHOD_DEFINE( OSErr, OpenMovieFile,
d7a9c895
RN
2105 (const FSSpec * fileSpec, short * resRefNum, wxInt8 permission),
2106 (fileSpec, resRefNum, permission), -1 );
2107
2108 wxDL_METHOD_DEFINE( OSErr, CloseMovieFile,
2109 (short resRefNum), (resRefNum), -1);
2110
2111 wxDL_METHOD_DEFINE( OSErr, NewMovieFromFile,
2112 (Movie * theMovie, short resRefNum, short * resId,
2113 StringPtr resName, short newMovieFlags,
b11eba7e 2114 bool * dataRefWasChanged),
d7a9c895
RN
2115 (theMovie, resRefNum, resId, resName, newMovieFlags,
2116 dataRefWasChanged), -1);
2117
2118 wxDL_VOIDMETHOD_DEFINE( SetMovieRate, (Movie m, Fixed rate), (m, rate) );
2119 wxDL_METHOD_DEFINE( Fixed, GetMovieRate, (Movie m), (m), 0);
2120 wxDL_VOIDMETHOD_DEFINE( MoviesTask, (Movie m, long maxms), (m, maxms) );
b11eba7e 2121 wxDL_VOIDMETHOD_DEFINE( BlockMove,
d7a9c895
RN
2122 (const char* p1, const char* p2, long s), (p1,p2,s) );
2123 wxDL_METHOD_DEFINE( Handle, NewHandleClear, (long s), (s), NULL );
2124
b11eba7e 2125 wxDL_METHOD_DEFINE( OSErr, NewMovieFromDataRef,
d7a9c895
RN
2126 (Movie * m, short flags, short * id,
2127 Handle dataRef, OSType dataRefType),
2128 (m,flags,id,dataRef,dataRefType), -1 );
2129
2130 wxDL_VOIDMETHOD_DEFINE( DisposeHandle, (Handle h), (h) );
2131 wxDL_VOIDMETHOD_DEFINE( GetMovieNaturalBoundsRect, (Movie m, Rect* r), (m,r) );
b11eba7e
WS
2132 wxDL_METHOD_DEFINE( void*, GetMovieIndTrackType,
2133 (Movie m, long index, OSType type, long flags),
d7a9c895 2134 (m,index,type,flags), NULL );
b11eba7e 2135 wxDL_VOIDMETHOD_DEFINE( CreatePortAssociation,
d7a9c895
RN
2136 (void* hWnd, void* junk, long morejunk), (hWnd, junk, morejunk) );
2137 wxDL_METHOD_DEFINE(void*, GetNativeWindowPort, (void* hWnd), (hWnd), NULL);
2138 wxDL_VOIDMETHOD_DEFINE(SetMovieGWorld, (Movie m, CGrafPtr port, void* whatever),
2139 (m, port, whatever) );
2140 wxDL_VOIDMETHOD_DEFINE(DisposeMovie, (Movie m), (m) );
2141 wxDL_VOIDMETHOD_DEFINE(SetMovieBox, (Movie m, Rect* r), (m,r));
2142 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeScale, (Movie m, long s), (m,s));
2143 wxDL_METHOD_DEFINE(long, GetMovieDuration, (Movie m), (m), 0);
2144 wxDL_METHOD_DEFINE(TimeBase, GetMovieTimeBase, (Movie m), (m), 0);
2145 wxDL_METHOD_DEFINE(TimeScale, GetMovieTimeScale, (Movie m), (m), 0);
2146 wxDL_METHOD_DEFINE(long, GetMovieTime, (Movie m, void* cruft), (m,cruft), 0);
2147 wxDL_VOIDMETHOD_DEFINE(SetMovieTime, (Movie m, TimeRecord* tr), (m,tr) );
6f8c67e7
JS
2148 wxDL_METHOD_DEFINE(short, GetMovieVolume, (Movie m), (m), 0);
2149 wxDL_VOIDMETHOD_DEFINE(SetMovieVolume, (Movie m, short sVolume), (m,sVolume) );
c5191fbd
VZ
2150 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeValue, (Movie m, long s), (m,s));
2151 wxDL_METHOD_DEFINE(ComponentInstance, NewMovieController, (Movie m, const Rect* mr, long fl), (m,mr,fl), 0);
2152 wxDL_VOIDMETHOD_DEFINE(DisposeMovieController, (ComponentInstance ci), (ci));
2153 wxDL_METHOD_DEFINE(int, MCSetVisible, (ComponentInstance m, int b), (m, b), 0);
2154
2155
2156 wxDL_VOIDMETHOD_DEFINE(PrePrerollMovie, (Movie m, long t, Fixed r, WXFARPROC p1, void* p2), (m,t,r,p1,p2) );
2157 wxDL_VOIDMETHOD_DEFINE(PrerollMovie, (Movie m, long t, Fixed r), (m,t,r) );
2158 wxDL_METHOD_DEFINE(Fixed, GetMoviePreferredRate, (Movie m), (m), 0);
2159 wxDL_METHOD_DEFINE(long, GetMovieLoadState, (Movie m), (m), 0);
2160 wxDL_METHOD_DEFINE(void*, NewRoutineDescriptor, (WXFARPROC f, int l, void* junk), (f, l, junk), 0);
2161 wxDL_VOIDMETHOD_DEFINE(DisposeRoutineDescriptor, (void* f), (f));
2162 wxDL_METHOD_DEFINE(void*, GetCurrentArchitecture, (), (), 0);
2163 wxDL_METHOD_DEFINE(int, MCDoAction, (ComponentInstance ci, long f, void* p), (ci,f,p), 0);
2164 wxDL_VOIDMETHOD_DEFINE(MCSetControllerBoundsRect, (ComponentInstance ci, Rect* r), (ci,r));
2165 wxDL_VOIDMETHOD_DEFINE(DestroyPortAssociation, (CGrafPtr g), (g));
2166 wxDL_VOIDMETHOD_DEFINE(NativeEventToMacEvent, (MSG* p1, EventRecord* p2), (p1,p2));
2167 wxDL_VOIDMETHOD_DEFINE(MCIsPlayerEvent, (ComponentInstance ci, EventRecord* p2), (ci, p2));
2168 wxDL_METHOD_DEFINE(int, MCSetMovie, (ComponentInstance ci, Movie m, void* p1, Point w),
2169 (ci,m,p1,w),0);
2170 wxDL_VOIDMETHOD_DEFINE(MCPositionController,
2171 (ComponentInstance ci, Rect* r, void* junk, void* morejunk), (ci,r,junk,morejunk));
2172 wxDL_VOIDMETHOD_DEFINE(MCSetActionFilterWithRefCon,
2173 (ComponentInstance ci, WXFARPROC cb, void* ref), (ci,cb,ref));
2174 wxDL_VOIDMETHOD_DEFINE(MCGetControllerInfo, (MovieController mc, long* flags), (mc,flags));
2175 wxDL_VOIDMETHOD_DEFINE(BeginUpdate, (CGrafPtr port), (port));
2176 wxDL_VOIDMETHOD_DEFINE(UpdateMovie, (Movie m), (m));
2177 wxDL_VOIDMETHOD_DEFINE(EndUpdate, (CGrafPtr port), (port));
2178 wxDL_METHOD_DEFINE( OSErr, GetMoviesStickyError, (), (), -1);
d7a9c895
RN
2179};
2180
2181bool wxQuickTimeLibrary::Initialize()
2182{
2183 m_ok = false;
2184
3131207f 2185 bool bWasLoggingEnabled = wxLog::EnableLogging(false); //Turn off the wxDynamicLibrary logging
32f65e50 2186
d7a9c895 2187 if(!m_dll.Load(wxT("qtmlClient.dll")))
32f65e50 2188 {
3131207f 2189 wxLog::EnableLogging(bWasLoggingEnabled);
d7a9c895 2190 return false;
32f65e50 2191 }
d7a9c895 2192
c5191fbd
VZ
2193 wxDL_METHOD_LOAD( m_dll, StartMovie, m_ok );
2194 wxDL_METHOD_LOAD( m_dll, StopMovie, m_ok );
2195 wxDL_METHOD_LOAD( m_dll, IsMovieDone, m_ok );
2196 wxDL_METHOD_LOAD( m_dll, GoToBeginningOfMovie, m_ok );
2197 wxDL_METHOD_LOAD( m_dll, GetMoviesError, m_ok );
2198 wxDL_METHOD_LOAD( m_dll, EnterMovies, m_ok );
2199 wxDL_METHOD_LOAD( m_dll, ExitMovies, m_ok );
2200 wxDL_METHOD_LOAD( m_dll, InitializeQTML, m_ok );
2201 wxDL_METHOD_LOAD( m_dll, TerminateQTML, m_ok );
2202 wxDL_METHOD_LOAD( m_dll, NativePathNameToFSSpec, m_ok );
2203 wxDL_METHOD_LOAD( m_dll, OpenMovieFile, m_ok );
2204 wxDL_METHOD_LOAD( m_dll, CloseMovieFile, m_ok );
2205 wxDL_METHOD_LOAD( m_dll, NewMovieFromFile, m_ok );
2206 wxDL_METHOD_LOAD( m_dll, GetMovieRate, m_ok );
2207 wxDL_METHOD_LOAD( m_dll, SetMovieRate, m_ok );
2208 wxDL_METHOD_LOAD( m_dll, MoviesTask, m_ok );
2209 wxDL_METHOD_LOAD( m_dll, BlockMove, m_ok );
2210 wxDL_METHOD_LOAD( m_dll, NewHandleClear, m_ok );
2211 wxDL_METHOD_LOAD( m_dll, NewMovieFromDataRef, m_ok );
2212 wxDL_METHOD_LOAD( m_dll, DisposeHandle, m_ok );
2213 wxDL_METHOD_LOAD( m_dll, GetMovieNaturalBoundsRect, m_ok );
2214 wxDL_METHOD_LOAD( m_dll, GetMovieIndTrackType, m_ok );
2215 wxDL_METHOD_LOAD( m_dll, CreatePortAssociation, m_ok );
2216 wxDL_METHOD_LOAD( m_dll, DestroyPortAssociation, m_ok );
2217 wxDL_METHOD_LOAD( m_dll, GetNativeWindowPort, m_ok );
2218 wxDL_METHOD_LOAD( m_dll, SetMovieGWorld, m_ok );
2219 wxDL_METHOD_LOAD( m_dll, DisposeMovie, m_ok );
2220 wxDL_METHOD_LOAD( m_dll, SetMovieBox, m_ok );
2221 wxDL_METHOD_LOAD( m_dll, SetMovieTimeScale, m_ok );
2222 wxDL_METHOD_LOAD( m_dll, GetMovieDuration, m_ok );
2223 wxDL_METHOD_LOAD( m_dll, GetMovieTimeBase, m_ok );
2224 wxDL_METHOD_LOAD( m_dll, GetMovieTimeScale, m_ok );
2225 wxDL_METHOD_LOAD( m_dll, GetMovieTime, m_ok );
2226 wxDL_METHOD_LOAD( m_dll, SetMovieTime, m_ok );
2227 wxDL_METHOD_LOAD( m_dll, GetMovieVolume, m_ok );
2228 wxDL_METHOD_LOAD( m_dll, SetMovieVolume, m_ok );
2229 wxDL_METHOD_LOAD( m_dll, SetMovieTimeValue, m_ok );
2230 wxDL_METHOD_LOAD( m_dll, NewMovieController, m_ok );
2231 wxDL_METHOD_LOAD( m_dll, DisposeMovieController, m_ok );
2232 wxDL_METHOD_LOAD( m_dll, MCSetVisible, m_ok );
2233 wxDL_METHOD_LOAD( m_dll, PrePrerollMovie, m_ok );
2234 wxDL_METHOD_LOAD( m_dll, PrerollMovie, m_ok );
2235 wxDL_METHOD_LOAD( m_dll, GetMoviePreferredRate, m_ok );
2236 wxDL_METHOD_LOAD( m_dll, GetMovieLoadState, m_ok );
2237 wxDL_METHOD_LOAD( m_dll, MCDoAction, m_ok );
2238 wxDL_METHOD_LOAD( m_dll, MCSetControllerBoundsRect, m_ok );
2239 wxDL_METHOD_LOAD( m_dll, NativeEventToMacEvent, m_ok );
2240 wxDL_METHOD_LOAD( m_dll, MCIsPlayerEvent, m_ok );
2241 wxDL_METHOD_LOAD( m_dll, MCSetMovie, m_ok );
2242 wxDL_METHOD_LOAD( m_dll, MCSetActionFilterWithRefCon, m_ok );
2243 wxDL_METHOD_LOAD( m_dll, MCGetControllerInfo, m_ok );
2244 wxDL_METHOD_LOAD( m_dll, BeginUpdate, m_ok );
2245 wxDL_METHOD_LOAD( m_dll, UpdateMovie, m_ok );
2246 wxDL_METHOD_LOAD( m_dll, EndUpdate, m_ok );
2247 wxDL_METHOD_LOAD( m_dll, GetMoviesStickyError, m_ok );
b11eba7e 2248
3131207f 2249 wxLog::EnableLogging(bWasLoggingEnabled);
d7a9c895
RN
2250 m_ok = true;
2251
2252 return true;
2253}
1a680109 2254
7e41b689 2255class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackendCommonBase
ff4aedc5
RN
2256{
2257public:
ff4aedc5
RN
2258 wxQTMediaBackend();
2259 ~wxQTMediaBackend();
1a680109 2260
226ec5a7 2261 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 2262 wxWindowID id,
226ec5a7 2263 const wxPoint& pos,
ff4aedc5 2264 const wxSize& size,
226ec5a7 2265 long style,
ff4aedc5
RN
2266 const wxValidator& validator,
2267 const wxString& name);
1a680109 2268
ff4aedc5
RN
2269 virtual bool Play();
2270 virtual bool Pause();
2271 virtual bool Stop();
1a680109 2272
3832f946
WS
2273 virtual bool Load(const wxURI& location,
2274 const wxURI& proxy)
2275 { return wxMediaBackend::Load(location, proxy); }
2276
ff4aedc5
RN
2277 virtual bool Load(const wxString& fileName);
2278 virtual bool Load(const wxURI& location);
1a680109 2279
ff4aedc5 2280 virtual wxMediaState GetState();
1a680109 2281
ff4aedc5
RN
2282 virtual bool SetPosition(wxLongLong where);
2283 virtual wxLongLong GetPosition();
2284 virtual wxLongLong GetDuration();
1a680109 2285
ff4aedc5
RN
2286 virtual void Move(int x, int y, int w, int h);
2287 wxSize GetVideoSize() const;
1a680109 2288
ff4aedc5
RN
2289 virtual double GetPlaybackRate();
2290 virtual bool SetPlaybackRate(double dRate);
1a680109 2291
6f8c67e7
JS
2292 virtual double GetVolume();
2293 virtual bool SetVolume(double);
2294
ff4aedc5
RN
2295 void Cleanup();
2296 void FinishLoad();
1a680109 2297
c5191fbd
VZ
2298 static void PPRMProc (Movie theMovie, OSErr theErr, void* theRefCon);
2299 //TODO: Last param actually long - does this work on 64bit machines?
2300 static Boolean MCFilterProc (MovieController theController,
2301 short action, void *params, LONG_PTR refCon);
2302
2303 static LRESULT CALLBACK QTWndProc(HWND, UINT, WPARAM, LPARAM);
2304
2305 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
2306
ff4aedc5 2307 wxSize m_bestSize; //Original movie size
d7a9c895 2308 Movie m_movie; //QT Movie handle/instance
ff4aedc5 2309 bool m_bVideo; //Whether or not we have video
c5191fbd
VZ
2310 bool m_bPlaying; //Whether or not movie is playing
2311 wxTimer* m_timer; //Load or Play timer
2312 wxQuickTimeLibrary m_lib; //DLL to load functions from
2313 ComponentInstance m_pMC; //Movie Controller
d7a9c895 2314
19b6f122 2315 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend)
ff4aedc5 2316};
1a680109 2317
6ab9bf57
VZ
2318// helper to hijack background erasing for the QT window
2319class WXDLLIMPEXP_MEDIA wxQTMediaEvtHandler : public wxEvtHandler
2320{
2321public:
7e41b689
VZ
2322 wxQTMediaEvtHandler(wxQTMediaBackend *qtb, WXHWND hwnd)
2323 {
2324 m_qtb = qtb;
2325 m_hwnd = hwnd;
2326 }
6ab9bf57
VZ
2327
2328 void OnEraseBackground(wxEraseEvent& event);
2329
2330private:
2331 wxQTMediaBackend *m_qtb;
7e41b689 2332 WXHWND m_hwnd;
6ab9bf57
VZ
2333
2334 DECLARE_NO_COPY_CLASS(wxQTMediaEvtHandler)
2335};
2336
1a680109 2337
ff4aedc5
RN
2338//===========================================================================
2339// IMPLEMENTATION
2340//===========================================================================
1a680109 2341
7e41b689
VZ
2342// ----------------------------------------------------------------------------
2343// wxMediaBackendCommonBase
2344// ----------------------------------------------------------------------------
2345
2346void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
2347{
2348 // our best size changed after opening a new file
2349 m_ctrl->InvalidateBestSize();
2350 m_ctrl->SetSize(m_ctrl->GetSize());
2351
2352 // if the parent of the control has a sizer ask it to refresh our size
2353 wxWindow * const parent = m_ctrl->GetParent();
2354 if ( parent->GetSizer() )
2355 {
2356 m_ctrl->GetParent()->Layout();
2357 m_ctrl->GetParent()->Refresh();
2358 m_ctrl->GetParent()->Update();
2359 }
2360}
2361
2362void wxMediaBackendCommonBase::NotifyMovieLoaded()
2363{
2364 NotifyMovieSizeChanged();
2365
2366 // notify about movie being fully loaded
2367 QueueEvent(wxEVT_MEDIA_LOADED);
2368}
2369
2370bool wxMediaBackendCommonBase::SendStopEvent()
2371{
2372 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
2373
2374 return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed();
2375}
2376
2377void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
2378{
2379 wxMediaEvent theEvent(evtType, m_ctrl->GetId());
2380 m_ctrl->AddPendingEvent(theEvent);
2381}
2382
ff4aedc5
RN
2383//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2384//
2385// wxAMMediaBackend
2386//
2387//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1a680109 2388
ff4aedc5 2389IMPLEMENT_DYNAMIC_CLASS(wxAMMediaBackend, wxMediaBackend);
1a680109 2390
ff4aedc5
RN
2391//---------------------------------------------------------------------------
2392// Usual debugging macros
2393//---------------------------------------------------------------------------
2394#ifdef __WXDEBUG__
920a7c15 2395#define MAX_ERROR_TEXT_LEN 160
a3c1ce50
JS
2396
2397//Get the error string for Active Movie
2398wxString wxAMMediaBackend::GetErrorString(HRESULT hrdsv)
2399{
32f65e50
WS
2400 wxChar szError[MAX_ERROR_TEXT_LEN];
2401 if( m_lpAMGetErrorText != NULL &&
2402 (*m_lpAMGetErrorText)(hrdsv, szError, MAX_ERROR_TEXT_LEN) == 0)
2403 {
a3c1ce50 2404 return wxString::Format(wxT("DirectShow error \"%s\" \n")
c5191fbd
VZ
2405 wxT("(numeric %X)\n")
2406 wxT("occured"),
2407 szError, (int)hrdsv);
32f65e50
WS
2408 }
2409 else
2410 {
c5191fbd
VZ
2411 return wxString::Format(wxT("Unknown error \n")
2412 wxT("(numeric %X)\n")
2413 wxT("occured"),
2414 (int)hrdsv);
32f65e50 2415 }
1a680109 2416}
a3c1ce50 2417
c5191fbd
VZ
2418#define wxAMFAIL(x) wxFAIL_MSG(GetErrorString(x));
2419#define wxVERIFY(x) wxASSERT((x))
2420#define wxAMLOG(x) wxLogDebug(GetErrorString(x))
2421#else
2422#define wxAMVERIFY(x) (x)
2423#define wxVERIFY(x) (x)
2424#define wxAMLOG(x)
2425#define wxAMFAIL(x)
2426#endif
2427
2428//---------------------------------------------------------------------------
2429// Standard macros for ease of use
2430//---------------------------------------------------------------------------
2431#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
2432
2433//---------------------------------------------------------------------------
2434// wxAMLoadTimer
2435//
2436// Queries the control periodically to see if it has reached the point
2437// in its loading cycle where we can begin playing the media - if so
2438// then we finish up some things like getting the original size of the video
2439// and then sending the loaded event to our handler
2440//---------------------------------------------------------------------------
2441class wxAMLoadTimer : public wxTimer
2442{
2443public:
2444 wxAMLoadTimer(wxAMMediaBackend* parent) :
2445 m_parent(parent) {}
2446
2447 void Notify()
2448 {
2449 if(m_parent->m_pMP)
2450 {
2451 MPReadyStateConstants nState;
2452 m_parent->m_pMP->get_ReadyState(&nState);
2453 if(nState != mpReadyStateLoading)
2454 {
2455 Stop();
2456 m_parent->FinishLoad();
2457 delete this;
2458 }
2459 }
2460 else
2461 {
2462 IActiveMovie2* pAM2 = NULL;
2463 ReadyStateConstants nState;
2464 if(m_parent->m_pAM->QueryInterface(IID_IActiveMovie2,
2465 (void**)&pAM2) == 0 &&
2466 pAM2->get_ReadyState(&nState) == 0)
2467 {
2468 pAM2->Release();
2469 if(nState != amvLoading)
2470 {
2471 Stop();
2472 m_parent->FinishLoad();
2473 delete this;
2474 }
2475 }
2476 else
2477 {
2478 if(pAM2)
2479 pAM2->Release();
2480
2481 Stop();
2482 m_parent->FinishLoad();
2483 delete this;
2484 }
2485 }
2486
2487 }
2488
2489protected:
2490 wxAMMediaBackend* m_parent; //Backend pointer
2491};
2492
2493//---------------------------------------------------------------------------
2494// wxAMPlayTimer
2495//
2496// Sets m_hNotifyWnd to NULL to signify that we haven't loaded anything yet
2497// Queries the control periodically to see if it has stopped -
2498// if it has it sends the stop event
2499//---------------------------------------------------------------------------
2500class wxAMPlayTimer : public wxTimer
2501{
2502public:
2503 wxAMPlayTimer(wxAMMediaBackend* parent) :
2504 m_parent(parent) {}
2505
2506 void Notify()
2507 {
2508 if(m_parent->GetState() == wxMEDIASTATE_STOPPED &&
2509 //NB: Stop events could get triggered by the interface
2510 //if ShowPlayerControls is enabled,
2511 //so we need this hack here to make an attempt
2512 //at it not getting sent - but its far from ideal -
2513 //they can still get sent in some cases
2514 m_parent->GetPosition() == m_parent->GetDuration())
2515 {
7e41b689 2516 if ( m_parent->SendStopEvent() )
c5191fbd
VZ
2517 {
2518 //Seek to beginning of movie
2519 m_parent->wxAMMediaBackend::SetPosition(0);
2520 Stop();
2521
2522 //send the event to our child
7e41b689 2523 m_parent->QueueFinishEvent();
c5191fbd
VZ
2524 }
2525 }
2526 }
2527
2528protected:
2529 wxAMMediaBackend* m_parent; //Backend pointer
2530};
2531
2532
2533/*
2534// The following is an alternative way - but it doesn't seem
2535// to work with the IActiveMovie control - it probably processes
2536// its own events
2537//---------------------------------------------------------------------------
2538// wxAMPlayTimer
2539//
2540// Query the IMediaEvent interface from the embedded WMP's
2541// filtergraph, then process the events from it - sending
2542// EC_COMPLETE events as stop events to the media control.
2543//---------------------------------------------------------------------------
2544class wxAMPlayTimer : public wxTimer
2545{
2546public:
2547 wxAMPlayTimer(wxAMMediaBackend* pBE) : m_pBE(pBE), m_pME(NULL)
2548 {
2549 HRESULT hr;
2550 IUnknown* pGB;
2551 hr = m_pBE->m_pAM->get_FilterGraph(&pGB);
2552 wxASSERT(SUCCEEDED(hr));
2553 hr = pGB->QueryInterface(IID_IMediaEvent, (void**)&m_pME);
2554 wxASSERT(SUCCEEDED(hr));
2555 pGB->Release();
2556 }
2557
2558 ~wxAMPlayTimer()
2559 {
2560 SAFE_RELEASE(m_pME);
2561 }
2562
2563 void Notify()
2564 {
2565 LONG evCode;
2566 LONG_PTR evParam1,
2567 evParam2;
2568
2569 //
2570 // DirectShow keeps a list of queued events, and we need
2571 // to go through them one by one, stopping at (Hopefully only one)
2572 // EC_COMPLETE message
2573 //
2574 while( m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0) == 0 )
2575 {
2576 // Cleanup memory that GetEvent allocated
2577 HRESULT hr = m_pME->FreeEventParams(evCode,
2578 evParam1, evParam2);
2579 if(hr != 0)
2580 {
2581 //Even though this makes a messagebox this
2582 //is windows where we can do gui stuff in seperate
2583 //threads :)
2584 wxFAIL_MSG(m_pBE->GetErrorString(hr));
2585 }
2586 // If this is the end of the clip, notify handler
2587 else if(1 == evCode) //EC_COMPLETE
2588 {
7e41b689 2589 if ( m_pBE->SendStopEvent() )
c5191fbd
VZ
2590 {
2591 Stop();
2592
7e41b689 2593 m_pBE->QueueFinishEvent();
c5191fbd
VZ
2594 }
2595 }
2596 }
2597 }
1a680109 2598
c5191fbd
VZ
2599protected:
2600 wxAMMediaBackend* m_pBE; //Backend pointer
2601 IMediaEvent* m_pME; //To determine when to send stop event
2602};
2603*/
1a680109 2604
ff4aedc5
RN
2605//---------------------------------------------------------------------------
2606// wxAMMediaBackend Constructor
226ec5a7 2607//---------------------------------------------------------------------------
32f65e50 2608wxAMMediaBackend::wxAMMediaBackend()
c5191fbd
VZ
2609 :m_pAX(NULL),
2610 m_pAM(NULL),
2611 m_pMP(NULL),
2612 m_pTimer(NULL)
1a680109 2613{
1a680109
RN
2614}
2615
ff4aedc5
RN
2616//---------------------------------------------------------------------------
2617// wxAMMediaBackend Destructor
226ec5a7 2618//---------------------------------------------------------------------------
ff4aedc5 2619wxAMMediaBackend::~wxAMMediaBackend()
1a680109 2620{
c5191fbd
VZ
2621 Clear(); //Free memory from Load()
2622
2623 if(m_pAX)
2624 {
2625 m_pAX->DissociateHandle();
2626 delete m_pAX;
2627 m_pAM->Release();
2628
2629 if(m_pMP)
2630 m_pMP->Release();
2631 }
1a680109
RN
2632}
2633
1a680109 2634//---------------------------------------------------------------------------
c5191fbd 2635// wxAMMediaBackend::Clear
1a680109 2636//
c5191fbd
VZ
2637// Free up interfaces and memory allocated by LoadXXX
2638//---------------------------------------------------------------------------
2639void wxAMMediaBackend::Clear()
2640{
2641 if(m_pTimer)
2642 delete m_pTimer;
2643}
2644
2645//---------------------------------------------------------------------------
2646// wxAMMediaBackend::CreateControl
226ec5a7
WS
2647//---------------------------------------------------------------------------
2648bool wxAMMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 2649 wxWindowID id,
226ec5a7 2650 const wxPoint& pos,
ff4aedc5 2651 const wxSize& size,
226ec5a7 2652 long style,
ff4aedc5
RN
2653 const wxValidator& validator,
2654 const wxString& name)
226ec5a7 2655{
c5191fbd
VZ
2656 // First get the AMGetErrorText procedure in debug
2657 // mode for more meaningful messages
920a7c15 2658#ifdef __WXDEBUG__
aa200e97 2659 if ( m_dllQuartz.Load(_T("quartz.dll"), wxDL_VERBATIM) )
920a7c15 2660 {
aa200e97
VZ
2661 m_lpAMGetErrorText = (LPAMGETERRORTEXT)
2662 m_dllQuartz.GetSymbolAorW(wxT("AMGetErrorText"));
920a7c15 2663 }
aa200e97
VZ
2664#endif // __WXDEBUG__
2665
c5191fbd
VZ
2666 // Now determine which (if any) media player interface is
2667 // available - IMediaPlayer or IActiveMovie
2668 if( ::CoCreateInstance(CLSID_MediaPlayer, NULL,
920a7c15 2669 CLSCTX_INPROC_SERVER,
c5191fbd
VZ
2670 IID_IMediaPlayer, (void**)&m_pMP) != 0 )
2671 {
2672 if( ::CoCreateInstance(CLSID_ActiveMovie, NULL,
2673 CLSCTX_INPROC_SERVER,
2674 IID_IActiveMovie, (void**)&m_pAM) != 0 )
aa200e97 2675 return false;
c5191fbd
VZ
2676 m_pAM->QueryInterface(IID_IMediaPlayer, (void**)&m_pMP);
2677 }
2678 else
2679 {
2680 m_pMP->QueryInterface(IID_IActiveMovie, (void**)&m_pAM);
2681 }
ff4aedc5
RN
2682 //
2683 // Create window
2684 // By default wxWindow(s) is created with a border -
c5191fbd
VZ
2685 // so we need to get rid of those
2686 //
2687 // Since we don't have a child window like most other
2688 // backends, we don't need wxCLIP_CHILDREN
ff4aedc5
RN
2689 //
2690 if ( !ctrl->wxControl::Create(parent, id, pos, size,
c5191fbd 2691 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
ff4aedc5
RN
2692 validator, name) )
2693 return false;
1a680109 2694
920a7c15 2695 //
c5191fbd
VZ
2696 // Now create the ActiveX container along with the media player
2697 // interface and query them
920a7c15 2698 //
a3c1ce50 2699 m_ctrl = ctrl;
c5191fbd
VZ
2700 m_pAX = new wxActiveX(ctrl,
2701 m_pMP ? IID_IMediaPlayer : IID_IActiveMovie,
2702 m_pAM);
ff4aedc5 2703
ff4aedc5
RN
2704
2705 //
c5191fbd
VZ
2706 // Here we set up wx-specific stuff for the default
2707 // settings wxMediaCtrl says it will stay to
ff4aedc5 2708 //
c5191fbd 2709 if(m_pMP)
1a680109 2710 {
c5191fbd
VZ
2711 m_pMP->put_DisplaySize(mpFitToSize);
2712 // TODO: Unsure what actual effect this has
2713 m_pMP->put_WindowlessVideo(VARIANT_TRUE);
1a680109 2714 }
920a7c15 2715 else
c5191fbd
VZ
2716 m_pAM->put_MovieWindowSize(amvDoubleOriginalSize);
2717
2718 //by default true
2719 m_pAM->put_AutoStart(VARIANT_FALSE);
2720 //by default enabled
2721 wxAMMediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);
2722 //by default with AM only 0.5
2723 wxAMMediaBackend::SetVolume(1.0);
2724
6ab9bf57
VZ
2725 // don't erase the background of our control window so that resizing is a
2726 // bit smoother
2727 m_ctrl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
ff4aedc5 2728
c5191fbd 2729 // success
32f65e50 2730 return true;
920a7c15 2731}
1a680109 2732
920a7c15
JS
2733//---------------------------------------------------------------------------
2734// wxAMMediaBackend::Load (file version)
920a7c15
JS
2735//---------------------------------------------------------------------------
2736bool wxAMMediaBackend::Load(const wxString& fileName)
2737{
c5191fbd
VZ
2738 return DoLoad(fileName);
2739}
920a7c15 2740
c5191fbd
VZ
2741//---------------------------------------------------------------------------
2742// wxAMMediaBackend::Load (URL Version)
2743//---------------------------------------------------------------------------
2744bool wxAMMediaBackend::Load(const wxURI& location)
2745{
2746 // Turn off loading from a proxy as user
2747 // may have set it previously
2748 INSPlay* pPlay = NULL;
2749 m_pAM->QueryInterface(IID_INSPlay, (void**) &pPlay);
2750 if(pPlay)
2751 {
2752 pPlay->put_UseHTTPProxy(VARIANT_FALSE);
2753 pPlay->Release();
2754 }
920a7c15 2755
c5191fbd
VZ
2756 return DoLoad(location.BuildURI());
2757}
920a7c15 2758
c5191fbd
VZ
2759//---------------------------------------------------------------------------
2760// wxAMMediaBackend::Load (URL Version with Proxy)
2761//---------------------------------------------------------------------------
2762bool wxAMMediaBackend::Load(const wxURI& location, const wxURI& proxy)
2763{
2764 // Set the proxy of the NETSHOW interface
2765 INSPlay* pPlay = NULL;
2766 m_pAM->QueryInterface(IID_INSPlay, (void**) &pPlay);
a3c1ce50 2767
c5191fbd 2768 if(pPlay)
920a7c15 2769 {
c5191fbd
VZ
2770 pPlay->put_UseHTTPProxy(VARIANT_TRUE);
2771 pPlay->put_HTTPProxyHost(wxBasicString(proxy.GetServer()).Get());
2772 pPlay->put_HTTPProxyPort(wxAtoi(proxy.GetPort()));
2773 pPlay->Release();
ff4aedc5 2774 }
226ec5a7 2775
c5191fbd
VZ
2776 return DoLoad(location.BuildURI());
2777}
1a680109 2778
c5191fbd
VZ
2779//---------------------------------------------------------------------------
2780// wxAMMediaBackend::DoLoad
2781//
2782// Called by all functions - this actually renders
2783// the file and sets up the filter graph
2784//---------------------------------------------------------------------------
2785bool wxAMMediaBackend::DoLoad(const wxString& location)
2786{
2787 Clear(); //Clear up previously allocated memory
a3c1ce50 2788
c5191fbd
VZ
2789 HRESULT hr;
2790
2791 // Play the movie the normal way through the embedded
2792 // WMP. Supposively Open is better in theory because
2793 // the docs say its async and put_FileName is not -
2794 // but in practice they both seem to be async anyway
2795 if(m_pMP)
2796 hr = m_pMP->Open( wxBasicString(location).Get() );
2797 else
2798 hr = m_pAM->put_FileName( wxBasicString(location).Get() );
a3c1ce50 2799
a3c1ce50
JS
2800 if(FAILED(hr))
2801 {
2802 wxAMLOG(hr);
2803 return false;
2804 }
2805
c5191fbd
VZ
2806 // In AM playing will FAIL if
2807 // the user plays before the media is loaded
2808 m_pTimer = new wxAMLoadTimer(this);
2809 m_pTimer->Start(20);
2810 return true;
2811}
2812
2813//---------------------------------------------------------------------------
2814// wxAMMediaBackend::FinishLoad
2815//
2816// Called by our wxAMLoadTimer when the
2817// embedded WMP tells its the media is ready to play.
2818//
2819// Here we get the original size of the video and
2820// send the loaded event to our watcher :).
2821//---------------------------------------------------------------------------
2822void wxAMMediaBackend::FinishLoad()
2823{
2824 //Get the original video size
2825 m_pAM->get_ImageSourceWidth((long*)&m_bestSize.x);
2826 m_pAM->get_ImageSourceHeight((long*)&m_bestSize.y);
1a680109 2827
a3c1ce50 2828 //
c5191fbd
VZ
2829 //Start the play timer to catch stop events
2830 //Previous load timer cleans up itself
a3c1ce50 2831 //
c5191fbd 2832 m_pTimer = new wxAMPlayTimer(this);
96339a78 2833
7e41b689 2834 NotifyMovieLoaded();
1a680109
RN
2835}
2836
a3c1ce50 2837//---------------------------------------------------------------------------
c5191fbd 2838// wxAMMediaBackend::ShowPlayerControls
a3c1ce50 2839//---------------------------------------------------------------------------
c5191fbd 2840bool wxAMMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
a3c1ce50 2841{
c5191fbd
VZ
2842 // Note that IMediaPlayer doesn't have a statusbar by
2843 // default but IActiveMovie does - so lets try to keep
2844 // the interface consistant
2845 if(!flags)
2846 {
2847 m_pAM->put_Enabled(VARIANT_FALSE);
2848 m_pAM->put_ShowControls(VARIANT_FALSE);
2849 if(m_pMP)
2850 m_pMP->put_ShowStatusBar(VARIANT_FALSE);
2851 }
2852 else
a3c1ce50 2853 {
c5191fbd
VZ
2854 m_pAM->put_Enabled(VARIANT_TRUE);
2855 m_pAM->put_ShowControls(VARIANT_TRUE);
2856
2857 m_pAM->put_ShowPositionControls(
2858 (flags & wxMEDIACTRLPLAYERCONTROLS_STEP) ?
2859 VARIANT_TRUE : VARIANT_FALSE);
2860
2861 if(m_pMP)
2862 {
2863 m_pMP->put_ShowStatusBar(VARIANT_TRUE);
2864 m_pMP->put_ShowAudioControls(
2865 (flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME) ?
2866 VARIANT_TRUE : VARIANT_FALSE);
2867 }
a3c1ce50
JS
2868 }
2869
c5191fbd 2870 return true;
a3c1ce50
JS
2871}
2872
ff4aedc5
RN
2873//---------------------------------------------------------------------------
2874// wxAMMediaBackend::Play
2875//
920a7c15
JS
2876// Plays the stream. If it is non-seekable, it will restart it (implicit).
2877//
2878// Note that we use SUCCEEDED here because run/pause/stop tend to be overly
2879// picky and return warnings on pretty much every call
226ec5a7 2880//---------------------------------------------------------------------------
ff4aedc5 2881bool wxAMMediaBackend::Play()
1a680109 2882{
c5191fbd
VZ
2883 // if the movie isn't done loading yet
2884 // go into an sync getmessage loop until it is :)
2885 if(m_pMP)
2886 {
2887 MPReadyStateConstants nState;
2888 m_pMP->get_ReadyState(&nState);
2889 while(nState == mpReadyStateLoading && wxYieldIfNeeded())
2890 {
2891 m_pMP->get_ReadyState(&nState);
2892 }
2893 }
2894 else
2895 {
2896 IActiveMovie2* pAM2;
2897 ReadyStateConstants nState;
2898 if(m_pAM->QueryInterface(IID_IActiveMovie2, (void**)&pAM2) == 0 &&
2899 pAM2->get_ReadyState(&nState) == 0)
2900 {
2901 while(nState == amvLoading && wxYieldIfNeeded())
2902 {
2903 pAM2->get_ReadyState(&nState);
2904 }
2905 pAM2->Release();
2906 }
2907 }
920a7c15 2908
c5191fbd
VZ
2909 //Actually try to play the movie
2910 HRESULT hr = m_pAM->Run();
2911 if(SUCCEEDED(hr))
920a7c15 2912 {
c5191fbd 2913 m_pTimer->Start(20);
920a7c15
JS
2914 return true;
2915 }
c5191fbd 2916 wxAMLOG(hr);
920a7c15 2917 return false;
1a680109
RN
2918}
2919
ff4aedc5
RN
2920//---------------------------------------------------------------------------
2921// wxAMMediaBackend::Pause
2922//
2923// Pauses the stream.
226ec5a7 2924//---------------------------------------------------------------------------
ff4aedc5 2925bool wxAMMediaBackend::Pause()
1a680109 2926{
c5191fbd
VZ
2927 HRESULT hr = m_pAM->Pause();
2928 if(SUCCEEDED(hr))
920a7c15 2929 return true;
c5191fbd 2930 wxAMLOG(hr);
920a7c15 2931 return false;
1a680109
RN
2932}
2933
ff4aedc5
RN
2934//---------------------------------------------------------------------------
2935// wxAMMediaBackend::Stop
2936//
2937// Stops the stream.
226ec5a7 2938//---------------------------------------------------------------------------
ff4aedc5 2939bool wxAMMediaBackend::Stop()
1a680109 2940{
c5191fbd
VZ
2941 HRESULT hr = m_pAM->Stop();
2942 if(SUCCEEDED(hr))
920a7c15 2943 {
c5191fbd 2944 //Seek to beginning
920a7c15 2945 wxAMMediaBackend::SetPosition(0);
c5191fbd
VZ
2946 //Stop stop event timer
2947 m_pTimer->Stop();
920a7c15
JS
2948 return true;
2949 }
c5191fbd 2950 wxAMLOG(hr);
920a7c15 2951 return false;
1a680109
RN
2952}
2953
ff4aedc5
RN
2954//---------------------------------------------------------------------------
2955// wxAMMediaBackend::SetPosition
2956//
226ec5a7 2957// 1) Translates the current position's time to directshow time,
a2a444e3 2958// which is in a scale of 1 second (in a double)
ff4aedc5
RN
2959// 2) Sets the play position of the IMediaSeeking interface -
2960// passing NULL as the stop position means to keep the old
2961// stop position
226ec5a7 2962//---------------------------------------------------------------------------
ff4aedc5 2963bool wxAMMediaBackend::SetPosition(wxLongLong where)
1a680109 2964{
c5191fbd 2965 HRESULT hr = m_pAM->put_CurrentPosition(
920a7c15 2966 ((LONGLONG)where.GetValue()) / 1000.0
a3c1ce50
JS
2967 );
2968 if(FAILED(hr))
2969 {
2970 wxAMLOG(hr);
2971 return false;
2972 }
2973
2974 return true;
1a680109
RN
2975}
2976
ff4aedc5
RN
2977//---------------------------------------------------------------------------
2978// wxAMMediaBackend::GetPosition
2979//
2980// 1) Obtains the current play and stop positions from IMediaSeeking
2981// 2) Returns the play position translated to our time base
226ec5a7 2982//---------------------------------------------------------------------------
ff4aedc5 2983wxLongLong wxAMMediaBackend::GetPosition()
1a680109 2984{
a2a444e3 2985 double outCur;
c5191fbd 2986 HRESULT hr = m_pAM->get_CurrentPosition(&outCur);
a3c1ce50
JS
2987 if(FAILED(hr))
2988 {
2989 wxAMLOG(hr);
2990 return 0;
2991 }
1a680109 2992
a2a444e3 2993 //h,m,s,milli - outdur is in 1 second (double)
600ffb32
WS
2994 outCur *= 1000;
2995 wxLongLong ll;
2996 ll.Assign(outCur);
2997
2998 return ll;
1a680109
RN
2999}
3000
6f8c67e7 3001//---------------------------------------------------------------------------
a3c1ce50 3002// wxAMMediaBackend::GetVolume
6f8c67e7 3003//
a3c1ce50 3004// Gets the volume through the IBasicAudio interface -
6f8c67e7
JS
3005// value ranges from 0 (MAX volume) to -10000 (minimum volume).
3006// -100 per decibel.
3007//---------------------------------------------------------------------------
a3c1ce50 3008double wxAMMediaBackend::GetVolume()
b11eba7e 3009{
a3c1ce50 3010 long lVolume;
c5191fbd 3011 HRESULT hr = m_pAM->get_Volume(&lVolume);
a3c1ce50
JS
3012 if(FAILED(hr))
3013 {
3014 wxAMLOG(hr);
3015 return 0.0;
a3c1ce50 3016 }
c5191fbd 3017 return pow(10.0, lVolume/2000.0);
b11eba7e 3018}
6f8c67e7
JS
3019
3020//---------------------------------------------------------------------------
a3c1ce50 3021// wxAMMediaBackend::SetVolume
6f8c67e7 3022//
a3c1ce50 3023// Sets the volume through the IBasicAudio interface -
6f8c67e7
JS
3024// value ranges from 0 (MAX volume) to -10000 (minimum volume).
3025// -100 per decibel.
3026//---------------------------------------------------------------------------
a3c1ce50 3027bool wxAMMediaBackend::SetVolume(double dVolume)
6f8c67e7 3028{
c5191fbd 3029 //pow(10.0, -80.0) to correct 0 == -INF
3832f946 3030 long lVolume = (long)(2000.0 * log10(pow(10.0, -80.0)+dVolume));
c5191fbd 3031 HRESULT hr = m_pAM->put_Volume( lVolume );
a3c1ce50
JS
3032 if(FAILED(hr))
3033 {
3034 wxAMLOG(hr);
3035 return false;
3036 }
3037 return true;
6f8c67e7 3038}
b11eba7e 3039
ff4aedc5
RN
3040//---------------------------------------------------------------------------
3041// wxAMMediaBackend::GetDuration
3042//
920a7c15 3043// 1) Obtains the duration of the media from IAMMultiMediaStream
ff4aedc5 3044// 2) Converts that value to our time base, and returns it
920a7c15 3045//
32f65e50 3046// NB: With VBR MP3 files the default DirectShow MP3 render does not
920a7c15
JS
3047// read the Xing header correctly, resulting in skewed values for duration
3048// and seeking
226ec5a7 3049//---------------------------------------------------------------------------
ff4aedc5 3050wxLongLong wxAMMediaBackend::GetDuration()
1a680109 3051{
a2a444e3 3052 double outDuration;
c5191fbd 3053 HRESULT hr = m_pAM->get_Duration(&outDuration);
a3c1ce50
JS
3054 if(FAILED(hr))
3055 {
3056 wxAMLOG(hr);
3057 return 0;
3058 }
1a680109 3059
a2a444e3 3060 //h,m,s,milli - outdur is in 1 second (double)
600ffb32
WS
3061 outDuration *= 1000;
3062 wxLongLong ll;
3063 ll.Assign(outDuration);
3064
3065 return ll;
1a680109
RN
3066}
3067
ff4aedc5
RN
3068//---------------------------------------------------------------------------
3069// wxAMMediaBackend::GetState
3070//
920a7c15 3071// Returns the cached state
226ec5a7 3072//---------------------------------------------------------------------------
ff4aedc5 3073wxMediaState wxAMMediaBackend::GetState()
1a680109 3074{
c5191fbd
VZ
3075 StateConstants nState;
3076 HRESULT hr = m_pAM->get_CurrentState(&nState);
3077 if(FAILED(hr))
3078 {
3079 wxAMLOG(hr);
3080 return wxMEDIASTATE_STOPPED;
3081 }
3082
3083 return (wxMediaState)nState;
1a680109
RN
3084}
3085
ff4aedc5
RN
3086//---------------------------------------------------------------------------
3087// wxAMMediaBackend::GetPlaybackRate
3088//
3089// Pretty simple way of obtaining the playback rate from
3090// the IMediaSeeking interface
226ec5a7 3091//---------------------------------------------------------------------------
ff4aedc5 3092double wxAMMediaBackend::GetPlaybackRate()
1a680109
RN
3093{
3094 double dRate;
c5191fbd 3095 HRESULT hr = m_pAM->get_Rate(&dRate);
a3c1ce50
JS
3096 if(FAILED(hr))
3097 {
3098 wxAMLOG(hr);
3099 return 0.0;
3100 }
1a680109
RN
3101 return dRate;
3102}
3103
ff4aedc5
RN
3104//---------------------------------------------------------------------------
3105// wxAMMediaBackend::SetPlaybackRate
3106//
3107// Sets the playback rate of the media - DirectShow is pretty good
3108// about this, actually
226ec5a7 3109//---------------------------------------------------------------------------
ff4aedc5 3110bool wxAMMediaBackend::SetPlaybackRate(double dRate)
c5191fbd
VZ
3111{
3112 HRESULT hr = m_pAM->put_Rate(dRate);
3113 if(FAILED(hr))
3114 {
3115 wxAMLOG(hr);
3116 return false;
920a7c15 3117 }
c5191fbd
VZ
3118
3119 return true;
920a7c15
JS
3120}
3121
920a7c15 3122//---------------------------------------------------------------------------
c5191fbd 3123// wxAMMediaBackend::GetDownloadXXX
920a7c15 3124//
c5191fbd
VZ
3125// Queries for and gets the total size of the file and the current
3126// progress in downloading that file from the IAMOpenProgress
3127// interface from the media player interface's filter graph
920a7c15 3128//---------------------------------------------------------------------------
c5191fbd
VZ
3129void wxAMMediaBackend::DoGetDownloadProgress(wxLongLong* pLoadProgress,
3130 wxLongLong* pLoadTotal)
1a680109 3131{
c5191fbd
VZ
3132 LONGLONG loadTotal = 0, loadProgress = 0;
3133 IUnknown* pFG;
3134 IAMOpenProgress* pOP;
3135 HRESULT hr;
3136 hr = m_pAM->get_FilterGraph(&pFG);
3137 if(SUCCEEDED(hr))
1a680109 3138 {
c5191fbd
VZ
3139 hr = pFG->QueryInterface(IID_IAMOpenProgress, (void**)&pOP);
3140 if(SUCCEEDED(hr))
3141 {
3142 hr = pOP->QueryProgress(&loadTotal, &loadProgress);
3143 pOP->Release();
3144 }
3145 pFG->Release();
3146 }
3147
3148 if(SUCCEEDED(hr))
920a7c15 3149 {
c5191fbd
VZ
3150 *pLoadProgress = loadProgress;
3151 *pLoadTotal = loadTotal;
920a7c15 3152 }
c5191fbd 3153 else
1a680109 3154 {
c5191fbd
VZ
3155 //When not loading from a URL QueryProgress will return
3156 //E_NOINTERFACE or whatever
3157 //wxAMFAIL(hr);
3158 *pLoadProgress = 0;
3159 *pLoadTotal = 0;
920a7c15 3160 }
920a7c15
JS
3161}
3162
920a7c15 3163//---------------------------------------------------------------------------
c5191fbd 3164// wxAMMediaBackend::GetVideoSize
920a7c15 3165//
c5191fbd 3166// Obtains the cached original video size
920a7c15 3167//---------------------------------------------------------------------------
c5191fbd 3168wxSize wxAMMediaBackend::GetVideoSize() const
920a7c15 3169{
c5191fbd
VZ
3170 return m_bestSize;
3171}
b81383bb 3172
c5191fbd
VZ
3173//---------------------------------------------------------------------------
3174// wxAMMediaBackend::Move
3175//
3176// We take care of this in our redrawing
3177//---------------------------------------------------------------------------
3178void wxAMMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
3179 int WXUNUSED(w), int WXUNUSED(h))
3180{
1a680109
RN
3181}
3182
ff4aedc5
RN
3183//---------------------------------------------------------------------------
3184// End of wxAMMediaBackend
3185//---------------------------------------------------------------------------
1a680109 3186
ff4aedc5 3187//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1a680109 3188//
ff4aedc5 3189// wxMCIMediaBackend
226ec5a7 3190//
ff4aedc5
RN
3191//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3192
ff4aedc5
RN
3193IMPLEMENT_DYNAMIC_CLASS(wxMCIMediaBackend, wxMediaBackend);
3194
3195//---------------------------------------------------------------------------
3196// Usual debugging macros for MCI returns
1a680109
RN
3197//---------------------------------------------------------------------------
3198
ff4aedc5
RN
3199#ifdef __WXDEBUG__
3200#define wxMCIVERIFY(arg) \
3201{ \
3202 DWORD nRet; \
3203 if ( (nRet = (arg)) != 0) \
3204 { \
3205 TCHAR sz[5000]; \
3206 mciGetErrorString(nRet, sz, 5000); \
3207 wxFAIL_MSG(wxString::Format(_T("MCI Error:%s"), sz)); \
3208 } \
3209}
3210#else
3211#define wxMCIVERIFY(arg) (arg);
3212#endif
3213
3214//---------------------------------------------------------------------------
3215// Simulation for <digitalv.h>
33d8e2fc 3216//
ff4aedc5 3217// Mingw and possibly other compilers don't have the digitalv.h header
226ec5a7 3218// that is needed to have some essential features of mci work with
ff4aedc5
RN
3219// windows - so we provide the declarations for the types we use here
3220//---------------------------------------------------------------------------
33d8e2fc
RN
3221
3222typedef struct {
3223 DWORD_PTR dwCallback;
3224#ifdef MCI_USE_OFFEXT
3225 POINT ptOffset;
3226 POINT ptExtent;
226ec5a7 3227#else
33d8e2fc
RN
3228 RECT rc;
3229#endif
3230} MCI_DGV_RECT_PARMS;
3231
3232typedef struct {
3233 DWORD_PTR dwCallback;
3234 HWND hWnd;
3235#ifndef _WIN32
3236 WORD wReserved1;
3237#endif
3238 UINT nCmdShow;
3239#ifndef _WIN32
3240 WORD wReserved2;
3241#endif
ff4aedc5
RN
3242 wxChar* lpstrText;
3243} MCI_DGV_WINDOW_PARMS;
33d8e2fc
RN
3244
3245typedef struct {
226ec5a7
WS
3246 DWORD_PTR dwCallback;
3247 DWORD dwTimeFormat;
3248 DWORD dwAudio;
3249 DWORD dwFileFormat;
3250 DWORD dwSpeed;
3251} MCI_DGV_SET_PARMS;
33d8e2fc 3252
6f8c67e7
JS
3253typedef struct {
3254 DWORD_PTR dwCallback;
3255 DWORD dwItem;
3256 DWORD dwValue;
3257 DWORD dwOver;
3258 wxChar* lpstrAlgorithm;
3259 wxChar* lpstrQuality;
3260} MCI_DGV_SETAUDIO_PARMS;
3261
ff4aedc5
RN
3262//---------------------------------------------------------------------------
3263// wxMCIMediaBackend Constructor
3264//
3265// Here we don't need to do much except say we don't have any video :)
3266//---------------------------------------------------------------------------
3267wxMCIMediaBackend::wxMCIMediaBackend() : m_hNotifyWnd(NULL), m_bVideo(false)
3268{
3f9a3bf9
RN
3269}
3270
ff4aedc5
RN
3271//---------------------------------------------------------------------------
3272// wxMCIMediaBackend Destructor
3273//
3274// We close the mci device - note that there may not be an mci device here,
3275// or it may fail - but we don't really care, since we're destructing
3276//---------------------------------------------------------------------------
3277wxMCIMediaBackend::~wxMCIMediaBackend()
3f9a3bf9 3278{
ff4aedc5
RN
3279 if(m_hNotifyWnd)
3280 {
3281 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
3282 DestroyWindow(m_hNotifyWnd);
3283 m_hNotifyWnd = NULL;
3284 }
3f9a3bf9
RN
3285}
3286
ff4aedc5
RN
3287//---------------------------------------------------------------------------
3288// wxMCIMediaBackend::Create
3289//
3290// Here we just tell wxMediaCtrl that mci does exist (which it does, on all
3291// msw systems, at least in some form dating back to win16 days)
3292//---------------------------------------------------------------------------
226ec5a7 3293bool wxMCIMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 3294 wxWindowID id,
226ec5a7 3295 const wxPoint& pos,
ff4aedc5 3296 const wxSize& size,
226ec5a7 3297 long style,
ff4aedc5
RN
3298 const wxValidator& validator,
3299 const wxString& name)
72259e00 3300{
ff4aedc5
RN
3301 //
3302 // Create window
3303 // By default wxWindow(s) is created with a border -
3304 // so we need to get rid of those, and create with
3305 // wxCLIP_CHILDREN, so that if the driver/backend
3306 // is a child window, it refereshes properly
3307 //
3308 if ( !ctrl->wxControl::Create(parent, id, pos, size,
11085e4b 3309 (style & ~wxBORDER_MASK) | wxBORDER_NONE | wxCLIP_CHILDREN,
ff4aedc5
RN
3310 validator, name) )
3311 return false;
3312
3f9a3bf9
RN
3313 m_ctrl = ctrl;
3314 return true;
3315}
3316
ff4aedc5
RN
3317//---------------------------------------------------------------------------
3318// wxMCIMediaBackend::Load (file version)
3319//
3320// Here we have MCI load a file and device, set the time format to our
3321// default (milliseconds), and set the video (if any) to play in the control
3322//---------------------------------------------------------------------------
3323bool wxMCIMediaBackend::Load(const wxString& fileName)
3f9a3bf9 3324{
ff4aedc5
RN
3325 //
3326 //if the user already called load close the previous MCI device
3327 //
3328 if(m_hNotifyWnd)
3329 {
3f9a3bf9 3330 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
ff4aedc5
RN
3331 DestroyWindow(m_hNotifyWnd);
3332 m_hNotifyWnd = NULL;
3333 }
3f9a3bf9 3334
ff4aedc5
RN
3335 //
3336 //Opens a file and has MCI select a device. Normally you'd put
3337 //MCI_OPEN_TYPE in addition to MCI_OPEN_ELEMENT - however if you
226ec5a7 3338 //omit this it tells MCI to select the device instead. This is
ff4aedc5
RN
3339 //good because we have no reliable way of "enumerating" the devices
3340 //in MCI
3341 //
3f9a3bf9 3342 MCI_OPEN_PARMS openParms;
3f9a3bf9
RN
3343 openParms.lpstrElementName = (wxChar*) fileName.c_str();
3344
226ec5a7 3345 if ( mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT,
ff4aedc5
RN
3346 (DWORD)(LPVOID)&openParms) != 0)
3347 return false;
3f9a3bf9
RN
3348
3349 m_hDev = openParms.wDeviceID;
3350
ff4aedc5
RN
3351 //
3352 //Now set the time format for the device to milliseconds
3353 //
3354 MCI_SET_PARMS setParms;
3f9a3bf9
RN
3355 setParms.dwCallback = 0;
3356 setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
3357
3358 if (mciSendCommand(m_hDev, MCI_SET, MCI_SET_TIME_FORMAT,
3359 (DWORD)(LPVOID)&setParms) != 0)
3360 return false;
3361
ff4aedc5
RN
3362 //
3363 //Now tell the MCI device to display the video in our wxMediaCtrl
3364 //
3f9a3bf9 3365 MCI_DGV_WINDOW_PARMS windowParms;
5987f174 3366 windowParms.hWnd = (HWND)m_ctrl->GetHandle();
3f9a3bf9 3367
226ec5a7 3368 m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
ff4aedc5
RN
3369 0x00010000L, //MCI_DGV_WINDOW_HWND
3370 (DWORD)(LPVOID)&windowParms) == 0);
3371
3372 //
3373 // Create a hidden window and register to handle
3374 // MCI events
226ec5a7 3375 // Note that wxCanvasClassName is already registered
ff4aedc5 3376 // and used by all wxWindows and normal wxControls
226ec5a7 3377 //
ff4aedc5
RN
3378 m_hNotifyWnd = ::CreateWindow
3379 (
3380 wxCanvasClassName,
3381 NULL,
3382 0, 0, 0, 0,
3383 0,
3384 (HWND) NULL,
3385 (HMENU)NULL,
3386 wxGetInstance(),
3387 (LPVOID) NULL
3388 );
3389
3390 if(!m_hNotifyWnd)
3391 {
3392 wxLogSysError( wxT("Could not create hidden needed for ")
c5191fbd 3393 wxT("registering for MCI events!") );
ff4aedc5
RN
3394
3395 return false;
3396 }
226ec5a7 3397
1146983c 3398 wxSetWindowProc(m_hNotifyWnd, wxMCIMediaBackend::NotifyWndProc);
c5191fbd 3399 wxSetWindowUserData(m_hNotifyWnd, this);
ff4aedc5 3400
7e41b689 3401 NotifyMovieLoaded();
c5191fbd 3402
3f9a3bf9
RN
3403 return true;
3404}
3405
ff4aedc5
RN
3406//---------------------------------------------------------------------------
3407// wxMCIMediaBackend::Load (URL version)
3408//
3409// MCI doesn't support URLs directly (?)
3410//
3411// TODO: Use wxURL/wxFileSystem and mmioInstallProc
3412//---------------------------------------------------------------------------
3413bool wxMCIMediaBackend::Load(const wxURI& WXUNUSED(location))
3f9a3bf9
RN
3414{
3415 return false;
3416}
3417
ff4aedc5
RN
3418//---------------------------------------------------------------------------
3419// wxMCIMediaBackend::Play
3420//
3421// Plays/Resumes the MCI device... a couple notes:
3422// 1) Certain drivers will crash and burn if we don't pass them an
3423// MCI_PLAY_PARMS, despite the documentation that says otherwise...
3424// 2) There is a MCI_RESUME command, but MCI_PLAY does the same thing
226ec5a7 3425// and will resume from a stopped state also, so there's no need to
ff4aedc5
RN
3426// call both, for example
3427//---------------------------------------------------------------------------
3428bool wxMCIMediaBackend::Play()
5987f174 3429{
5987f174 3430 MCI_PLAY_PARMS playParms;
ff4aedc5
RN
3431 playParms.dwCallback = (DWORD)m_hNotifyWnd;
3432
11219c9e 3433 bool bOK = ( mciSendCommand(m_hDev, MCI_PLAY, MCI_NOTIFY,
ff4aedc5 3434 (DWORD)(LPVOID)&playParms) == 0 );
11219c9e
RN
3435
3436 if(bOK)
3437 m_ctrl->Show(m_bVideo);
3438
3439 return bOK;
5987f174
RN
3440}
3441
ff4aedc5
RN
3442//---------------------------------------------------------------------------
3443// wxMCIMediaBackend::Pause
3444//
3445// Pauses the MCI device - nothing special
226ec5a7 3446//---------------------------------------------------------------------------
ff4aedc5 3447bool wxMCIMediaBackend::Pause()
5987f174
RN
3448{
3449 return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
3450}
3451
ff4aedc5
RN
3452//---------------------------------------------------------------------------
3453// wxMCIMediaBackend::Stop
3454//
3455// Stops the MCI device & seeks to the beginning as wxMediaCtrl docs outline
226ec5a7 3456//---------------------------------------------------------------------------
ff4aedc5 3457bool wxMCIMediaBackend::Stop()
5987f174
RN
3458{
3459 return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0) &&
3460 (mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
3461}
3462
ff4aedc5
RN
3463//---------------------------------------------------------------------------
3464// wxMCIMediaBackend::GetState
3465//
3466// Here we get the state and convert it to a wxMediaState -
3467// since we use direct comparisons with MCI_MODE_PLAY and
3468// MCI_MODE_PAUSE, we don't care if the MCI_STATUS call
3469// fails or not
226ec5a7 3470//---------------------------------------------------------------------------
ff4aedc5 3471wxMediaState wxMCIMediaBackend::GetState()
3f9a3bf9
RN
3472{
3473 MCI_STATUS_PARMS statusParms;
3474 statusParms.dwItem = MCI_STATUS_MODE;
ff4aedc5 3475
3f9a3bf9
RN
3476 mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
3477 (DWORD)(LPVOID)&statusParms);
3478
3479 if(statusParms.dwReturn == MCI_MODE_PAUSE)
3480 return wxMEDIASTATE_PAUSED;
3481 else if(statusParms.dwReturn == MCI_MODE_PLAY)
3482 return wxMEDIASTATE_PLAYING;
3483 else
3484 return wxMEDIASTATE_STOPPED;
3485}
3486
ff4aedc5
RN
3487//---------------------------------------------------------------------------
3488// wxMCIMediaBackend::SetPosition
3489//
3490// Here we set the position of the device in the stream.
226ec5a7 3491// Note that MCI actually stops the device after you seek it if the
ff4aedc5 3492// device is playing/paused, so we need to play the file after
226ec5a7
WS
3493// MCI seeks like normal APIs would
3494//---------------------------------------------------------------------------
ff4aedc5 3495bool wxMCIMediaBackend::SetPosition(wxLongLong where)
3f9a3bf9
RN
3496{
3497 MCI_SEEK_PARMS seekParms;
3498 seekParms.dwCallback = 0;
e70fda0e 3499#if wxUSE_LONGLONG_NATIVE && !wxUSE_LONGLONG_WX
226ec5a7 3500 seekParms.dwTo = (DWORD)where.GetValue();
e70fda0e
WS
3501#else /* wxUSE_LONGLONG_WX */
3502 /* no way to return it in one piece */
3503 wxASSERT( where.GetHi()==0 );
3504 seekParms.dwTo = (DWORD)where.GetLo();
3505#endif /* wxUSE_LONGLONG_* */
3f9a3bf9 3506
ff4aedc5 3507 //device was playing?
3f9a3bf9
RN
3508 bool bReplay = GetState() == wxMEDIASTATE_PLAYING;
3509
226ec5a7 3510 if( mciSendCommand(m_hDev, MCI_SEEK, MCI_TO,
ff4aedc5 3511 (DWORD)(LPVOID)&seekParms) != 0)
3f9a3bf9 3512 return false;
3f9a3bf9 3513
ff4aedc5 3514 //If the device was playing, resume it
3f9a3bf9
RN
3515 if (bReplay)
3516 return Play();
3517 else
3518 return true;
3519}
3520
ff4aedc5
RN
3521//---------------------------------------------------------------------------
3522// wxMCIMediaBackend::GetPosition
3523//
3524// Gets the position of the device in the stream using the current
3525// time format... nothing special here...
226ec5a7 3526//---------------------------------------------------------------------------
ff4aedc5 3527wxLongLong wxMCIMediaBackend::GetPosition()
3f9a3bf9
RN
3528{
3529 MCI_STATUS_PARMS statusParms;
72259e00 3530 statusParms.dwItem = MCI_STATUS_POSITION;
ff4aedc5 3531
72259e00 3532 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
ff4aedc5 3533 (DWORD)(LPSTR)&statusParms) != 0)
3f9a3bf9
RN
3534 return 0;
3535
3536 return statusParms.dwReturn;
3537}
3538
6f8c67e7
JS
3539//---------------------------------------------------------------------------
3540// wxMCIMediaBackend::GetVolume
3541//
3542// Gets the volume of the current media via the MCI_DGV_STATUS_VOLUME
3543// message. Value ranges from 0 (minimum) to 1000 (maximum volume).
3544//---------------------------------------------------------------------------
3545double wxMCIMediaBackend::GetVolume()
3546{
3547 MCI_STATUS_PARMS statusParms;
600ffb32 3548 statusParms.dwCallback = 0;
6f8c67e7
JS
3549 statusParms.dwItem = 0x4019; //MCI_DGV_STATUS_VOLUME
3550
3551 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
3552 (DWORD)(LPSTR)&statusParms) != 0)
3553 return 0;
3554
3555 return ((double)statusParms.dwReturn) / 1000.0;
3556}
3557
3558//---------------------------------------------------------------------------
3559// wxMCIMediaBackend::SetVolume
3560//
3561// Sets the volume of the current media via the MCI_DGV_SETAUDIO_VOLUME
3562// message. Value ranges from 0 (minimum) to 1000 (maximum volume).
3563//---------------------------------------------------------------------------
3564bool wxMCIMediaBackend::SetVolume(double dVolume)
3565{
3566 MCI_DGV_SETAUDIO_PARMS audioParms;
600ffb32 3567 audioParms.dwCallback = 0;
6f8c67e7
JS
3568 audioParms.dwItem = 0x4002; //MCI_DGV_SETAUDIO_VOLUME
3569 audioParms.dwValue = (DWORD) (dVolume * 1000.0);
3570 audioParms.dwOver = 0;
3571 audioParms.lpstrAlgorithm = NULL;
3572 audioParms.lpstrQuality = NULL;
3573
b11eba7e 3574 if (mciSendCommand(m_hDev, 0x0873, //MCI_SETAUDIO
c5191fbd
VZ
3575 //MCI_DGV_SETAUDIO+(_ITEM | _VALUE)
3576 0x00800000L | 0x01000000L,
6f8c67e7
JS
3577 (DWORD)(LPSTR)&audioParms) != 0)
3578 return false;
3579 return true;
3580}
3581
ff4aedc5
RN
3582//---------------------------------------------------------------------------
3583// wxMCIMediaBackend::GetDuration
3584//
3585// Gets the duration of the stream... nothing special
226ec5a7 3586//---------------------------------------------------------------------------
ff4aedc5 3587wxLongLong wxMCIMediaBackend::GetDuration()
3f9a3bf9
RN
3588{
3589 MCI_STATUS_PARMS statusParms;
72259e00 3590 statusParms.dwItem = MCI_STATUS_LENGTH;
ff4aedc5 3591
72259e00 3592 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
ff4aedc5 3593 (DWORD)(LPSTR)&statusParms) != 0)
3f9a3bf9
RN
3594 return 0;
3595
3596 return statusParms.dwReturn;
3597}
3598
ff4aedc5
RN
3599//---------------------------------------------------------------------------
3600// wxMCIMediaBackend::Move
3601//
3602// Moves the window to a location
226ec5a7
WS
3603//---------------------------------------------------------------------------
3604void wxMCIMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
ff4aedc5 3605 int w, int h)
3f9a3bf9 3606{
ff4aedc5
RN
3607 if (m_hNotifyWnd && m_bVideo)
3608 {
3609 MCI_DGV_RECT_PARMS putParms; //ifdefed MCI_DGV_PUT_PARMS
b11eba7e 3610 memset(&putParms, 0, sizeof(MCI_DGV_RECT_PARMS));
ff4aedc5 3611 putParms.rc.bottom = h;
b11eba7e 3612 putParms.rc.right = w;
7c4a4505 3613
b11eba7e
WS
3614 //wxStackWalker will crash and burn here on assert
3615 //and mci doesn't like 0 and 0 for some reason (out of range )
3616 //so just don't it in that case
3617 if(w || h)
3618 {
7c4a4505 3619 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_PUT,
ff4aedc5
RN
3620 0x00040000L, //MCI_DGV_PUT_DESTINATION
3621 (DWORD)(LPSTR)&putParms) );
7c4a4505 3622 }
ff4aedc5 3623 }
3f9a3bf9
RN
3624}
3625
ff4aedc5
RN
3626//---------------------------------------------------------------------------
3627// wxMCIMediaBackend::GetVideoSize
3628//
3629// Gets the original size of the movie for sizers
226ec5a7 3630//---------------------------------------------------------------------------
ff4aedc5 3631wxSize wxMCIMediaBackend::GetVideoSize() const
3f9a3bf9
RN
3632{
3633 if(m_bVideo)
3634 {
ff4aedc5 3635 MCI_DGV_RECT_PARMS whereParms; //ifdefed MCI_DGV_WHERE_PARMS
3f9a3bf9 3636
226ec5a7 3637 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_WHERE,
ff4aedc5
RN
3638 0x00020000L, //MCI_DGV_WHERE_SOURCE
3639 (DWORD)(LPSTR)&whereParms) );
226ec5a7 3640
ff4aedc5 3641 return wxSize(whereParms.rc.right, whereParms.rc.bottom);
3f9a3bf9 3642 }
c47addef 3643 return wxSize(0,0);
3f9a3bf9
RN
3644}
3645
ff4aedc5
RN
3646//---------------------------------------------------------------------------
3647// wxMCIMediaBackend::GetPlaybackRate
3648//
3649// TODO
226ec5a7 3650//---------------------------------------------------------------------------
ff4aedc5 3651double wxMCIMediaBackend::GetPlaybackRate()
3f9a3bf9
RN
3652{
3653 return 1.0;
3654}
3655
ff4aedc5
RN
3656//---------------------------------------------------------------------------
3657// wxMCIMediaBackend::SetPlaybackRate
3658//
3659// TODO
226ec5a7 3660//---------------------------------------------------------------------------
ff4aedc5 3661bool wxMCIMediaBackend::SetPlaybackRate(double WXUNUSED(dRate))
3f9a3bf9 3662{
ff4aedc5
RN
3663/*
3664 MCI_WAVE_SET_SAMPLESPERSEC
3665 MCI_DGV_SET_PARMS setParms;
3666 setParms.dwSpeed = (DWORD) (dRate * 1000.0);
3667
226ec5a7 3668 return (mciSendCommand(m_hDev, MCI_SET,
ff4aedc5
RN
3669 0x00020000L, //MCI_DGV_SET_SPEED
3670 (DWORD)(LPSTR)&setParms) == 0);
3671*/
3f9a3bf9
RN
3672 return false;
3673}
3674
ff4aedc5
RN
3675//---------------------------------------------------------------------------
3676// [static] wxMCIMediaBackend::MSWWindowProc
3677//
226ec5a7 3678// Here we process a message when MCI reaches the stopping point
ff4aedc5 3679// in the stream
226ec5a7
WS
3680//---------------------------------------------------------------------------
3681LRESULT CALLBACK wxMCIMediaBackend::NotifyWndProc(HWND hWnd, UINT nMsg,
3682 WPARAM wParam,
ff4aedc5
RN
3683 LPARAM lParam)
3684{
c5191fbd
VZ
3685 wxMCIMediaBackend* backend =
3686 (wxMCIMediaBackend*)wxGetWindowUserData(hWnd);
ff4aedc5
RN
3687
3688 return backend->OnNotifyWndProc(hWnd, nMsg, wParam, lParam);
3689}
3690
226ec5a7
WS
3691LRESULT CALLBACK wxMCIMediaBackend::OnNotifyWndProc(HWND hWnd, UINT nMsg,
3692 WPARAM wParam,
ff4aedc5 3693 LPARAM lParam)
3f9a3bf9 3694{
5987f174
RN
3695 if(nMsg == MM_MCINOTIFY)
3696 {
ff4aedc5
RN
3697 wxASSERT(lParam == (LPARAM) m_hDev);
3698 if(wParam == MCI_NOTIFY_SUCCESSFUL && lParam == (LPARAM)m_hDev)
5987f174 3699 {
7e41b689 3700 if ( SendStopEvent() )
ff4aedc5 3701 {
226ec5a7 3702 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_SEEK,
ff4aedc5 3703 MCI_SEEK_TO_START, 0) );
3f9a3bf9 3704
7e41b689 3705 QueueFinishEvent();
ff4aedc5 3706 }
5987f174 3707 }
5987f174 3708 }
ff4aedc5 3709 return DefWindowProc(hWnd, nMsg, wParam, lParam);
3f9a3bf9 3710}
c5191fbd 3711
ff4aedc5
RN
3712//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3713//
3714// wxQTMediaBackend
226ec5a7 3715//
ff4aedc5 3716// TODO: Use a less cludgy way to pause/get state/set state
c5191fbd
VZ
3717// FIXME: Greg Hazel reports that sometimes files that cannot be played
3718// with this backend are treated as playable anyway - not verifyed though.
ff4aedc5
RN
3719//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3720
ff4aedc5
RN
3721IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
3722
c5191fbd
VZ
3723//Time between timer calls - this is the Apple recommondation to the TCL
3724//team I believe
3725#define MOVIE_DELAY 20
ff4aedc5
RN
3726
3727#include "wx/timer.h"
3728
c5191fbd
VZ
3729
3730//---------------------------------------------------------------------------
3731// wxQTLoadTimer
3732//
3733// QT, esp. QT for Windows is very picky about how you go about
3734// async loading. If you were to go through a Windows message loop
3735// or a MoviesTask or both and then check the movie load state
3736// it would still return 1000 (loading)... even (pre)prerolling doesn't
3737// help. However, making a load timer like this works
3738//---------------------------------------------------------------------------
3739class wxQTLoadTimer : public wxTimer
ff4aedc5
RN
3740{
3741public:
c5191fbd
VZ
3742 wxQTLoadTimer(Movie movie, wxQTMediaBackend* parent, wxQuickTimeLibrary* pLib) :
3743 m_movie(movie), m_parent(parent), m_pLib(pLib) {}
ff4aedc5 3744
c5191fbd 3745 void Notify()
ff4aedc5 3746 {
c5191fbd
VZ
3747 m_pLib->MoviesTask(m_movie, 0);
3748 //kMovieLoadStatePlayable
3749 if(m_pLib->GetMovieLoadState(m_movie) >= 10000)
3750 {
3751 m_parent->FinishLoad();
3752 delete this;
3753 }
ff4aedc5
RN
3754 }
3755
c5191fbd
VZ
3756protected:
3757 Movie m_movie; //Our movie instance
3758 wxQTMediaBackend* m_parent; //Backend pointer
3759 wxQuickTimeLibrary* m_pLib; //Interfaces
3760};
3761
3762
3763// --------------------------------------------------------------------------
3764// wxQTPlayTimer - Handle Asyncronous Playing
3765//
3766// 1) Checks to see if the movie is done, and if not continues
3767// streaming the movie
3768// 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
3769// the movie.
3770// --------------------------------------------------------------------------
3771class wxQTPlayTimer : public wxTimer
3772{
3773public:
3774 wxQTPlayTimer(Movie movie, wxQTMediaBackend* parent,
3775 wxQuickTimeLibrary* pLib) :
3776 m_movie(movie), m_parent(parent), m_pLib(pLib) {}
ff4aedc5 3777
ff4aedc5
RN
3778 void Notify()
3779 {
c5191fbd
VZ
3780 //
3781 // OK, a little explaining - basically originally
3782 // we only called MoviesTask if the movie was actually
3783 // playing (not paused or stopped)... this was before
3784 // we realized MoviesTask actually handles repainting
3785 // of the current frame - so if you were to resize
3786 // or something it would previously not redraw that
3787 // portion of the movie.
3788 //
3789 // So now we call MoviesTask always so that it repaints
3790 // correctly.
3791 //
3792 m_pLib->MoviesTask(m_movie, 0);
3793
3794 //
3795 // Handle the stop event - if the movie has reached
3796 // the end, notify our handler
3797 //
3798 // m_bPlaying == !(Stopped | Paused)
3799 //
3800 if (m_parent->m_bPlaying)
ff4aedc5 3801 {
c5191fbd 3802 if(m_pLib->IsMovieDone(m_movie))
ff4aedc5 3803 {
7e41b689 3804 if ( m_parent->SendStopEvent() )
ff4aedc5 3805 {
ff4aedc5 3806 m_parent->Stop();
d7a9c895 3807 wxASSERT(m_pLib->GetMoviesError() == noErr);
ff4aedc5 3808
7e41b689 3809 m_parent->QueueFinishEvent();
ff4aedc5
RN
3810 }
3811 }
3812 }
3813 }
3814
3815protected:
3816 Movie m_movie; //Our movie instance
ff4aedc5 3817 wxQTMediaBackend* m_parent; //Backend pointer
d7a9c895 3818 wxQuickTimeLibrary* m_pLib; //Interfaces
ff4aedc5
RN
3819};
3820
c5191fbd
VZ
3821
3822//---------------------------------------------------------------------------
3823// wxQTMediaBackend::QTWndProc
3824//
3825// Forwards events to the Movie Controller so that it can
3826// redraw itself/process messages etc..
3827//---------------------------------------------------------------------------
3828LRESULT CALLBACK wxQTMediaBackend::QTWndProc(HWND hWnd, UINT nMsg,
3829 WPARAM wParam, LPARAM lParam)
3830{
3831 wxQTMediaBackend* pThis = (wxQTMediaBackend*)wxGetWindowUserData(hWnd);
3832
3833 MSG msg;
3834 msg.hwnd = hWnd;
3835 msg.message = nMsg;
3836 msg.wParam = wParam;
3837 msg.lParam = lParam;
3838 msg.time = 0;
3839 msg.pt.x = 0;
3840 msg.pt.y = 0;
3841 EventRecord theEvent;
3842 pThis->m_lib.NativeEventToMacEvent(&msg, &theEvent);
3843 pThis->m_lib.MCIsPlayerEvent(pThis->m_pMC, &theEvent);
3844 return pThis->m_ctrl->MSWWindowProc(nMsg, wParam, lParam);
3845}
3846
ff4aedc5
RN
3847//---------------------------------------------------------------------------
3848// wxQTMediaBackend Destructor
3849//
3850// Sets m_timer to NULL signifying we havn't loaded anything yet
3851//---------------------------------------------------------------------------
c5191fbd
VZ
3852wxQTMediaBackend::wxQTMediaBackend()
3853: m_movie(NULL), m_bPlaying(false), m_timer(NULL), m_pMC(NULL)
ff4aedc5
RN
3854{
3855}
3856
3857//---------------------------------------------------------------------------
3858// wxQTMediaBackend Destructor
3859//
3860// 1) Cleans up the QuickTime movie instance
3861// 2) Decrements the QuickTime reference counter - if this reaches
3862// 0, QuickTime shuts down
3863// 3) Decrements the QuickTime Windows Media Layer reference counter -
3864// if this reaches 0, QuickTime shuts down the Windows Media Layer
3865//---------------------------------------------------------------------------
3866wxQTMediaBackend::~wxQTMediaBackend()
3867{
c5191fbd 3868 if(m_movie)
ff4aedc5
RN
3869 Cleanup();
3870
d7a9c895
RN
3871 if(m_lib.IsOk())
3872 {
c5191fbd
VZ
3873 if(m_pMC)
3874 {
3875 m_lib.DisposeMovieController(m_pMC);
3876 // m_pMC = NULL;
3877 }
3878
6ab9bf57
VZ
3879 // destroy wxQTMediaEvtHandler we pushed on it
3880 m_ctrl->PopEventHandler(true);
3881
c5191fbd
VZ
3882 m_lib.DestroyPortAssociation(
3883 (CGrafPtr)m_lib.GetNativeWindowPort(m_ctrl->GetHWND()));
3884
3103e8a9 3885 //Note that ExitMovies() is not necessary, but
d7a9c895
RN
3886 //the docs are fuzzy on whether or not TerminateQTML is
3887 m_lib.ExitMovies();
3888 m_lib.TerminateQTML();
3889 }
ff4aedc5
RN
3890}
3891
3892//---------------------------------------------------------------------------
3893// wxQTMediaBackend::CreateControl
3894//
3895// 1) Intializes QuickTime
3896// 2) Creates the control window
3897//---------------------------------------------------------------------------
226ec5a7 3898bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 3899 wxWindowID id,
226ec5a7 3900 const wxPoint& pos,
ff4aedc5 3901 const wxSize& size,
226ec5a7 3902 long style,
ff4aedc5
RN
3903 const wxValidator& validator,
3904 const wxString& name)
3905{
d7a9c895
RN
3906 if(!m_lib.Initialize())
3907 return false;
b11eba7e 3908
600ffb32
WS
3909 int nError = m_lib.InitializeQTML(0);
3910 if (nError != noErr) //-2093 no dll
ff4aedc5 3911 {
c5191fbd
VZ
3912 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"),
3913 nError));
ff4aedc5
RN
3914 return false;
3915 }
d7a9c895 3916 m_lib.EnterMovies();
ff4aedc5
RN
3917
3918 //
3919 // Create window
3920 // By default wxWindow(s) is created with a border -
3921 // so we need to get rid of those
3922 //
3923 // Since we don't have a child window like most other
3924 // backends, we don't need wxCLIP_CHILDREN
3925 //
3926 if ( !ctrl->wxControl::Create(parent, id, pos, size,
11085e4b 3927 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
ff4aedc5
RN
3928 validator, name) )
3929 return false;
3930
c5191fbd
VZ
3931
3932 m_ctrl = ctrl; //assign the control to our member
3933
3934 // Create a port association for our window so we
3935 // can use it as a WindowRef
3936 m_lib.CreatePortAssociation(m_ctrl->GetHWND(), NULL, 0L);
3937
3938 //Part of a suggestion from Greg Hazel to repaint
3939 //movie when idle
7e41b689 3940 m_ctrl->PushEventHandler(new wxQTMediaEvtHandler(this, m_ctrl->GetHWND()));
c5191fbd
VZ
3941
3942 // done
ff4aedc5
RN
3943 return true;
3944}
3945
3946//---------------------------------------------------------------------------
3947// wxQTMediaBackend::Load (file version)
3948//
3949// 1) Get an FSSpec from the Windows path name
3950// 2) Open the movie
3951// 3) Obtain the movie instance from the movie resource
c5191fbd
VZ
3952// 4) Close the movie resource
3953// 5) Finish loading
ff4aedc5
RN
3954//---------------------------------------------------------------------------
3955bool wxQTMediaBackend::Load(const wxString& fileName)
3956{
c5191fbd 3957 if(m_movie)
ff4aedc5 3958 Cleanup();
3f9a3bf9 3959
920a7c15 3960 short movieResFile = 0; //= 0 because of annoying VC6 warning
ff4aedc5
RN
3961 FSSpec sfFile;
3962
d7a9c895 3963 if (m_lib.NativePathNameToFSSpec ((char*) (const char*) fileName.mb_str(),
78450975 3964 &sfFile, 0) != noErr)
ff4aedc5 3965 return false;
226ec5a7 3966
d7a9c895 3967 if (m_lib.OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
ff4aedc5
RN
3968 return false;
3969
3970 short movieResID = 0;
3971 Str255 movieName;
3972
600ffb32
WS
3973 OSErr err = m_lib.NewMovieFromFile (
3974 &m_movie,
3975 movieResFile,
3976 &movieResID,
3977 movieName,
3978 newMovieActive,
3979 NULL
3980 ); //wasChanged
ff4aedc5 3981
c5191fbd
VZ
3982 //m_lib.GetMoviesStickyError() because it may not find the
3983 //proper codec and play black video and other strange effects,
3984 //not to mention mess up the dynamic backend loading scheme
3985 //of wxMediaCtrl - so it just does what the QuickTime player does
3986 if(err == noErr && m_lib.GetMoviesStickyError() == noErr)
3987 {
d7a9c895 3988 m_lib.CloseMovieFile (movieResFile);
ff4aedc5 3989
c5191fbd
VZ
3990 FinishLoad();
3991 return true;
3992 }
3993 else
ff4aedc5 3994 return false;
c5191fbd 3995}
ff4aedc5 3996
ff4aedc5 3997
c5191fbd
VZ
3998//---------------------------------------------------------------------------
3999// wxQTMediaBackend::PPRMProc (static)
4000//
4001// Called when done PrePrerolling the movie.
4002// Note that in 99% of the cases this does nothing...
4003// Anyway we set up the loading timer here to tell us when the movie is done
4004//---------------------------------------------------------------------------
3832f946
WS
4005void wxQTMediaBackend::PPRMProc (Movie theMovie,
4006 OSErr WXUNUSED_UNLESS_DEBUG(theErr),
4007 void* theRefCon)
c5191fbd
VZ
4008{
4009 wxASSERT( theMovie );
4010 wxASSERT( theRefCon );
4011 wxASSERT( theErr == noErr );
4012
4013 wxQTMediaBackend* pBE = (wxQTMediaBackend*) theRefCon;
4014
4015 long lTime = pBE->m_lib.GetMovieTime(theMovie,NULL);
4016 Fixed rate = pBE->m_lib.GetMoviePreferredRate(theMovie);
4017 pBE->m_lib.PrerollMovie(theMovie,lTime,rate);
4018 pBE->m_timer = new wxQTLoadTimer(pBE->m_movie, pBE, &pBE->m_lib);
4019 pBE->m_timer->Start(MOVIE_DELAY);
ff4aedc5
RN
4020}
4021
c5191fbd 4022
ff4aedc5 4023//---------------------------------------------------------------------------
c5191fbd 4024// wxQTMediaBackend::Load (URL Version)
ff4aedc5 4025//
c5191fbd
VZ
4026// 1) Build an escaped URI from location
4027// 2) Create a handle to store the URI string
4028// 3) Put the URI string inside the handle
4029// 4) Make a QuickTime URL data ref from the handle with the URI in it
4030// 5) Clean up the URI string handle
4031// 6) Do some prerolling
4032// 7) Finish Loading
ff4aedc5
RN
4033//---------------------------------------------------------------------------
4034bool wxQTMediaBackend::Load(const wxURI& location)
4035{
c5191fbd 4036 if(m_movie)
ff4aedc5
RN
4037 Cleanup();
4038
4039 wxString theURI = location.BuildURI();
4040
d7a9c895 4041 Handle theHandle = m_lib.NewHandleClear(theURI.length() + 1);
ff4aedc5
RN
4042 wxASSERT(theHandle);
4043
d7a9c895 4044 m_lib.BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1);
ff4aedc5
RN
4045
4046 //create the movie from the handle that refers to the URI
c5191fbd
VZ
4047 OSErr err = m_lib.NewMovieFromDataRef(&m_movie, newMovieActive |
4048 newMovieAsyncOK
4049 /*|newMovieIdleImportOK*/,
226ec5a7 4050 NULL, theHandle,
19b6f122 4051 URLDataHandlerSubType);
ff4aedc5 4052
d7a9c895 4053 m_lib.DisposeHandle(theHandle);
ff4aedc5 4054
c5191fbd
VZ
4055 if (err == noErr)
4056 {
4057 long timeNow;
ff4aedc5 4058 Fixed playRate;
ff4aedc5 4059
c5191fbd
VZ
4060 timeNow = m_lib.GetMovieTime(m_movie, NULL);
4061 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5 4062
c5191fbd
VZ
4063 playRate = m_lib.GetMoviePreferredRate(m_movie);
4064 wxASSERT(m_lib.GetMoviesError() == noErr);
4065
4066 //
4067 // Note that the callback here is optional,
4068 // but without it PrePrerollMovie can be buggy
4069 // (see Apple ml). Also, some may wonder
4070 // why we need this at all - this is because
4071 // Apple docs say QuickTime streamed movies
4072 // require it if you don't use a Movie Controller,
4073 // which we don't by default.
4074 //
4075 m_lib.PrePrerollMovie(m_movie, timeNow, playRate,
4076 (WXFARPROC)wxQTMediaBackend::PPRMProc,
4077 (void*)this);
4078 return true;
4079 }
4080 else
4081 return false;
ff4aedc5
RN
4082}
4083
c5191fbd 4084
ff4aedc5 4085//---------------------------------------------------------------------------
c5191fbd 4086// wxQTMediaBackend::FinishLoad
ff4aedc5 4087//
c5191fbd
VZ
4088// 1) Create the movie timer
4089// 2) Get real size of movie for GetBestSize/sizers
4090// 3) Set the movie time scale to something usable so that seeking
4091// etc. will work correctly
4092// 4) Set our Movie Controller to display the movie if it exists,
4093// otherwise set the bounds of the Movie
4094// 5) Refresh parent window
ff4aedc5
RN
4095//---------------------------------------------------------------------------
4096void wxQTMediaBackend::FinishLoad()
4097{
c5191fbd
VZ
4098 // Create the playing/streaming timer
4099 m_timer = new wxQTPlayTimer(m_movie, (wxQTMediaBackend*) this, &m_lib);
ff4aedc5 4100 wxASSERT(m_timer);
c5191fbd 4101 m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
ff4aedc5
RN
4102
4103 //get the real size of the movie
4104 Rect outRect;
920a7c15 4105 memset(&outRect, 0, sizeof(Rect)); //for annoying VC6 warning
d7a9c895
RN
4106 m_lib.GetMovieNaturalBoundsRect (m_movie, &outRect);
4107 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5
RN
4108
4109 m_bestSize.x = outRect.right - outRect.left;
4110 m_bestSize.y = outRect.bottom - outRect.top;
226ec5a7 4111
c5191fbd
VZ
4112 //
4113 // Handle the movie GWorld
4114 //
4115 if(m_pMC)
4116 {
4117 Point thePoint;
4118 thePoint.h = thePoint.v = 0;
4119 m_lib.MCSetMovie(m_pMC, m_movie,
4120 m_lib.GetNativeWindowPort(m_ctrl->GetHandle()),
4121 thePoint);
4122 m_lib.MCSetVisible(m_pMC, true);
4123 m_bestSize.y += 16;
4124 }
4125 else
ff4aedc5 4126 {
d7a9c895
RN
4127 m_lib.SetMovieGWorld(m_movie,
4128 (CGrafPtr) m_lib.GetNativeWindowPort(m_ctrl->GetHWND()),
4129 NULL);
ff4aedc5
RN
4130 }
4131
c5191fbd
VZ
4132 //
4133 // Set the movie to millisecond precision
4134 //
d7a9c895
RN
4135 m_lib.SetMovieTimeScale(m_movie, 1000);
4136 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5 4137
7e41b689 4138 NotifyMovieLoaded();
ff4aedc5
RN
4139}
4140
4141//---------------------------------------------------------------------------
c5191fbd 4142// wxQTMediaBackend::Play
ff4aedc5 4143//
c5191fbd
VZ
4144// 1) Start the QT movie
4145// 2) Start the movie loading timer
4146//
4147// NOTE: This will still return success even when
4148// the movie is still loading, and as mentioned in wxQTLoadTimer
4149// I don't know of a way to force this to be sync - so if its
4150// still loading the function will return true but the movie will
4151// still be in the stopped state
ff4aedc5
RN
4152//---------------------------------------------------------------------------
4153bool wxQTMediaBackend::Play()
4154{
d7a9c895 4155 m_lib.StartMovie(m_movie);
c5191fbd 4156 m_bPlaying = true;
d7a9c895 4157 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
4158}
4159
4160//---------------------------------------------------------------------------
c5191fbd 4161// wxQTMediaBackend::Pause
ff4aedc5 4162//
c5191fbd
VZ
4163// 1) Stop the movie
4164// 2) Stop the movie timer
ff4aedc5
RN
4165//---------------------------------------------------------------------------
4166bool wxQTMediaBackend::Pause()
4167{
c5191fbd 4168 m_bPlaying = false;
d7a9c895 4169 m_lib.StopMovie(m_movie);
d7a9c895 4170 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
4171}
4172
4173//---------------------------------------------------------------------------
c5191fbd 4174// wxQTMediaBackend::Stop
ff4aedc5 4175//
c5191fbd
VZ
4176// 1) Stop the movie
4177// 2) Stop the movie timer
4178// 3) Seek to the beginning of the movie
ff4aedc5
RN
4179//---------------------------------------------------------------------------
4180bool wxQTMediaBackend::Stop()
4181{
c5191fbd 4182 m_bPlaying = false;
ff4aedc5 4183
d7a9c895
RN
4184 m_lib.StopMovie(m_movie);
4185 if(m_lib.GetMoviesError() != noErr)
ff4aedc5 4186 return false;
226ec5a7 4187
d7a9c895
RN
4188 m_lib.GoToBeginningOfMovie(m_movie);
4189 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
4190}
4191
4192//---------------------------------------------------------------------------
c5191fbd 4193// wxQTMediaBackend::GetPlaybackRate
ff4aedc5 4194//
c5191fbd 4195// 1) Get the movie playback rate from ::GetMovieRate
ff4aedc5
RN
4196//---------------------------------------------------------------------------
4197double wxQTMediaBackend::GetPlaybackRate()
4198{
d7a9c895 4199 return ( ((double)m_lib.GetMovieRate(m_movie)) / 0x10000);
ff4aedc5
RN
4200}
4201
4202//---------------------------------------------------------------------------
c5191fbd 4203// wxQTMediaBackend::SetPlaybackRate
ff4aedc5 4204//
c5191fbd 4205// 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate
ff4aedc5
RN
4206//---------------------------------------------------------------------------
4207bool wxQTMediaBackend::SetPlaybackRate(double dRate)
4208{
d7a9c895
RN
4209 m_lib.SetMovieRate(m_movie, (Fixed) (dRate * 0x10000));
4210 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
4211}
4212
4213//---------------------------------------------------------------------------
c5191fbd 4214// wxQTMediaBackend::SetPosition
ff4aedc5 4215//
c5191fbd
VZ
4216// 1) Create a time record struct (TimeRecord) with appropriate values
4217// 2) Pass struct to SetMovieTime
ff4aedc5
RN
4218//---------------------------------------------------------------------------
4219bool wxQTMediaBackend::SetPosition(wxLongLong where)
4220{
c5191fbd
VZ
4221 //NB: For some reason SetMovieTime does not work
4222 //correctly with the Quicktime Windows SDK (6)
4223 //From Muskelkatermann at the wxForum
4224 //http://www.solidsteel.nl/users/wxwidgets/viewtopic.php?t=2957
4225 //RN - note that I have not verified this but there
4226 //is no harm in calling SetMovieTimeValue instead
4227#if 0
ff4aedc5
RN
4228 TimeRecord theTimeRecord;
4229 memset(&theTimeRecord, 0, sizeof(TimeRecord));
600ffb32 4230 theTimeRecord.value.lo = where.GetLo();
d7a9c895
RN
4231 theTimeRecord.scale = m_lib.GetMovieTimeScale(m_movie);
4232 theTimeRecord.base = m_lib.GetMovieTimeBase(m_movie);
4233 m_lib.SetMovieTime(m_movie, &theTimeRecord);
c5191fbd
VZ
4234#else
4235 m_lib.SetMovieTimeValue(m_movie, where.GetLo());
4236#endif
d7a9c895 4237 if (m_lib.GetMoviesError() != noErr)
ff4aedc5
RN
4238 return false;
4239
4240 return true;
4241}
4242
4243//---------------------------------------------------------------------------
e163773d 4244// wxQTMediaBackend::GetPosition
ff4aedc5 4245//
e163773d 4246// 1) Calls GetMovieTime to get the position we are in in the movie
8b5d5223 4247// in milliseconds (we called
ff4aedc5
RN
4248//---------------------------------------------------------------------------
4249wxLongLong wxQTMediaBackend::GetPosition()
4250{
d7a9c895 4251 return m_lib.GetMovieTime(m_movie, NULL);
ff4aedc5
RN
4252}
4253
6f8c67e7
JS
4254//---------------------------------------------------------------------------
4255// wxQTMediaBackend::GetVolume
4256//
4257// Gets the volume through GetMovieVolume - which returns a 16 bit short -
4258//
4259// +--------+--------+
4260// + (1) + (2) +
4261// +--------+--------+
4262//
4263// (1) first 8 bits are value before decimal
4264// (2) second 8 bits are value after decimal
4265//
4266// Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
4267// 1 (full gain and sound)
4268//---------------------------------------------------------------------------
4269double wxQTMediaBackend::GetVolume()
4270{
4271 short sVolume = m_lib.GetMovieVolume(m_movie);
c5191fbd 4272 wxASSERT(m_lib.GetMoviesError() == noErr);
b11eba7e 4273
6f8c67e7
JS
4274 if(sVolume & (128 << 8)) //negative - no sound
4275 return 0.0;
4276
c5191fbd 4277 return sVolume/256.0;
6f8c67e7
JS
4278}
4279
4280//---------------------------------------------------------------------------
4281// wxQTMediaBackend::SetVolume
4282//
4283// Sets the volume through SetMovieVolume - which takes a 16 bit short -
4284//
4285// +--------+--------+
4286// + (1) + (2) +
4287// +--------+--------+
4288//
4289// (1) first 8 bits are value before decimal
4290// (2) second 8 bits are value after decimal
4291//
4292// Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
4293// 1 (full gain and sound)
4294//---------------------------------------------------------------------------
4295bool wxQTMediaBackend::SetVolume(double dVolume)
4296{
c5191fbd
VZ
4297 m_lib.SetMovieVolume(m_movie, (short) (dVolume * 256));
4298 return m_lib.GetMoviesError() == noErr;
6f8c67e7
JS
4299}
4300
ff4aedc5 4301//---------------------------------------------------------------------------
c5191fbd 4302// wxQTMediaBackend::GetDuration
ff4aedc5 4303//
c5191fbd 4304// Calls GetMovieDuration
ff4aedc5
RN
4305//---------------------------------------------------------------------------
4306wxLongLong wxQTMediaBackend::GetDuration()
4307{
d7a9c895 4308 return m_lib.GetMovieDuration(m_movie);
ff4aedc5
RN
4309}
4310
4311//---------------------------------------------------------------------------
c5191fbd 4312// wxQTMediaBackend::GetState
ff4aedc5 4313//
c5191fbd
VZ
4314// Determines the current state - if we are at the beginning we
4315// are stopped
ff4aedc5
RN
4316//---------------------------------------------------------------------------
4317wxMediaState wxQTMediaBackend::GetState()
4318{
c5191fbd 4319 if (m_bPlaying == true)
ff4aedc5 4320 return wxMEDIASTATE_PLAYING;
c5191fbd
VZ
4321 else if ( !m_movie || wxQTMediaBackend::GetPosition() == 0)
4322 return wxMEDIASTATE_STOPPED;
ff4aedc5
RN
4323 else
4324 return wxMEDIASTATE_PAUSED;
4325}
4326
4327//---------------------------------------------------------------------------
c5191fbd 4328// wxQTMediaBackend::Cleanup
ff4aedc5 4329//
c5191fbd
VZ
4330// Diposes of the movie timer, Disassociates the Movie Controller with
4331// movie and hides it if it exists, and stops and disposes
4332// of the QT movie
ff4aedc5
RN
4333//---------------------------------------------------------------------------
4334void wxQTMediaBackend::Cleanup()
4335{
c5191fbd
VZ
4336 m_bPlaying = false;
4337
4338 if(m_timer)
4339 {
ff4aedc5
RN
4340 delete m_timer;
4341 m_timer = NULL;
c5191fbd 4342 }
ff4aedc5 4343
d7a9c895 4344 m_lib.StopMovie(m_movie);
c5191fbd
VZ
4345
4346 if(m_pMC)
4347 {
4348 Point thePoint;
4349 thePoint.h = thePoint.v = 0;
4350 m_lib.MCSetVisible(m_pMC, false);
4351 m_lib.MCSetMovie(m_pMC, NULL, NULL, thePoint);
4352 }
4353
d7a9c895 4354 m_lib.DisposeMovie(m_movie);
c5191fbd 4355 m_movie = NULL;
ff4aedc5
RN
4356}
4357
4358//---------------------------------------------------------------------------
c5191fbd 4359// wxQTMediaBackend::ShowPlayerControls
ff4aedc5 4360//
c5191fbd
VZ
4361// Creates a movie controller for the Movie if the user wants it
4362//---------------------------------------------------------------------------
4363bool wxQTMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
4364{
4365 if(m_pMC)
4366 {
4367 //restore old wndproc
4368 wxSetWindowProc((HWND)m_ctrl->GetHWND(), wxWndProc);
4369 m_lib.DisposeMovieController(m_pMC);
4370 m_pMC = NULL;
4371 m_bestSize.y -= 16; //movie controller height
4372 }
4373
4374 if(flags && m_movie)
4375 {
4376 Rect rect;
4377 wxRect wxrect = m_ctrl->GetClientRect();
4378
4379 //make room for controller
4380 if(wxrect.width < 320)
4381 wxrect.width = 320;
4382
3832f946
WS
4383 rect.top = (short)wxrect.y;
4384 rect.left = (short)wxrect.x;
4385 rect.right = (short)(rect.left + wxrect.width);
4386 rect.bottom = (short)(rect.top + wxrect.height);
c5191fbd
VZ
4387
4388 if(!m_pMC)
4389 {
4390 m_pMC = m_lib.NewMovieController(m_movie, &rect, mcTopLeftMovie |
4391 // mcScaleMovieToFit |
4392 // mcWithBadge |
4393 mcWithFrame);
4394 m_lib.MCDoAction(m_pMC, 32, (void*)true); //mcActionSetKeysEnabled
4395 m_lib.MCSetActionFilterWithRefCon(m_pMC,
4396 (WXFARPROC)wxQTMediaBackend::MCFilterProc, (void*)this);
4397 m_bestSize.y += 16; //movie controller height
4398
4399 //
4400 // By default the movie controller uses its own color
4401 // pallette for the movie which can be bad on some files -
4402 // so turn it off. Also turn off its frame/border for
4403 // the movie
4404 //
4405 // Also we take care of a couple of the interface flags here
4406 //
4407 long mcFlags = 0;
4408 m_lib.MCDoAction(m_pMC, 39/*mcActionGetFlags*/, (void*)&mcFlags);
4409 mcFlags |= ( //(1<<0)/*mcFlagSuppressMovieFrame*/ |
4410 (1<<3)/*mcFlagsUseWindowPalette*/
4411 | ((flags & wxMEDIACTRLPLAYERCONTROLS_STEP)
4412 ? 0 : (1<<1)/*mcFlagSuppressStepButtons*/)
4413 | ((flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME)
4414 ? 0 : (1<<2)/*mcFlagSuppressSpeakerButton*/)
4415 // | (1<<4) /*mcFlagDontInvalidate*/ //if we take care of repainting ourselves
4416 );
4417 m_lib.MCDoAction(m_pMC, 38/*mcActionSetFlags*/, (void*)mcFlags);
4418
4419 //intercept the wndproc of our control window
4420 wxSetWindowProc((HWND)m_ctrl->GetHWND(),
4421 wxQTMediaBackend::QTWndProc);
4422
4423 //set the user data of our window
4424 wxSetWindowUserData((HWND)m_ctrl->GetHWND(), this);
4425 }
4426 }
4427
7e41b689 4428 NotifyMovieSizeChanged();
c5191fbd
VZ
4429
4430 return m_lib.GetMoviesError() == noErr;
4431}
4432
4433//---------------------------------------------------------------------------
4434// wxQTMediaBackend::MCFilterProc (static)
4435//
4436// Callback for when the movie controller recieves a message
4437//---------------------------------------------------------------------------
4438Boolean
4439wxQTMediaBackend::MCFilterProc(MovieController WXUNUSED(theController),
4440 short action,
4441 void * WXUNUSED(params),
4442 LONG_PTR refCon)
4443{
4444 if(action != 1) //don't process idle events
4445 {
4446 wxQTMediaBackend* pThis = (wxQTMediaBackend*)refCon;
4447
4448 switch(action)
4449 {
4450 case 8: //play button triggered - MC will set movie to opposite state
4451 //of current - playing ? paused : playing
4452 pThis->m_bPlaying = !(pThis->m_bPlaying);
4453
4454 // NB: Sometimes it doesn't redraw properly -
4455 // if you click on the button but don't move the mouse
4456 // the button will not change its state until you move
4457 // mcActionDraw and Refresh/Update combo do nothing
4458 // to help this unfortunately
4459 break;
4460 default:
4461 break;
4462 }
4463 }
4464 return 0;
4465}
4466
4467//---------------------------------------------------------------------------
4468// wxQTMediaBackend::GetVideoSize
4469//
4470// Returns the actual size of the QT movie
ff4aedc5
RN
4471//---------------------------------------------------------------------------
4472wxSize wxQTMediaBackend::GetVideoSize() const
4473{
4474 return m_bestSize;
4475}
4476
4477//---------------------------------------------------------------------------
4478// wxQTMediaBackend::Move
4479//
c5191fbd 4480// Sets the bounds of either the Movie or Movie Controller
ff4aedc5 4481//---------------------------------------------------------------------------
d7a9c895 4482void wxQTMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y), int w, int h)
ff4aedc5 4483{
c5191fbd 4484 if(m_movie)
ff4aedc5 4485 {
c5191fbd
VZ
4486 //make room for controller
4487 if(m_pMC)
4488 {
4489 if(w < 320)
4490 w = 320;
ff4aedc5 4491
c5191fbd
VZ
4492 Rect theRect = {0, 0, (short)h, (short)w};
4493 m_lib.MCSetControllerBoundsRect(m_pMC, &theRect);
4494 }
4495 else
4496 {
4497 Rect theRect = {0, 0, (short)h, (short)w};
d7a9c895 4498 m_lib.SetMovieBox(m_movie, &theRect);
c5191fbd
VZ
4499 }
4500
d7a9c895 4501 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5
RN
4502 }
4503}
4504
c5191fbd
VZ
4505//---------------------------------------------------------------------------
4506// wxQTMediaBackend::OnEraseBackground
4507//
4508// Suggestion from Greg Hazel to repaint the movie when idle
4509// (on pause also)
4510//
4511// TODO: We may be repainting too much here - under what exact circumstances
4512// do we need this? I think Move also repaints correctly for the Movie
4513// Controller, so in that instance we don't need this either
4514//---------------------------------------------------------------------------
4515void wxQTMediaEvtHandler::OnEraseBackground(wxEraseEvent& evt)
4516{
6ab9bf57 4517 wxQuickTimeLibrary& m_pLib = m_qtb->m_lib;
c5191fbd 4518
6ab9bf57 4519 if ( m_qtb->m_pMC )
c5191fbd
VZ
4520 {
4521 //repaint movie controller
6ab9bf57 4522 m_pLib.MCDoAction(m_qtb->m_pMC, 2 /*mcActionDraw*/,
7e41b689 4523 m_pLib.GetNativeWindowPort(m_hwnd));
c5191fbd 4524 }
6ab9bf57 4525 else if(m_qtb->m_movie)
c5191fbd 4526 {
7e41b689 4527 CGrafPtr port = (CGrafPtr)m_pLib.GetNativeWindowPort(m_hwnd);
c5191fbd 4528
6ab9bf57
VZ
4529 m_pLib.BeginUpdate(port);
4530 m_pLib.UpdateMovie(m_qtb->m_movie);
4531 wxASSERT(m_pLib.GetMoviesError() == noErr);
4532 m_pLib.EndUpdate(port);
c5191fbd
VZ
4533 }
4534
6ab9bf57
VZ
4535 // VZ: this doesn't make sense: why should we erase the background after
4536 // taking the trouble to do whatever we did above? (FIXME)
c5191fbd
VZ
4537 evt.Skip(); //repaint with window background (TODO: maybe !m_movie?)
4538}
4539
ff4aedc5 4540//---------------------------------------------------------------------------
1146983c 4541// End QT Backend
ff4aedc5 4542//---------------------------------------------------------------------------
ff4aedc5
RN
4543
4544//in source file that contains stuff you don't directly use
4545#include <wx/html/forcelnk.h>
4546FORCE_LINK_ME(basewxmediabackends);
4547
4548//---------------------------------------------------------------------------
4549// End wxMediaCtrl Compilation Guard and this file
4550//---------------------------------------------------------------------------
72259e00
RL
4551#endif //wxUSE_MEDIACTRL
4552
ff4aedc5 4553