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