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