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