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