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