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