1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/mediactrl.cpp
3 // Purpose: Built-in Media Backends for Windows
4 // Author: Ryan Norton <wxprojects@comcast.net>
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 //===========================================================================
14 //===========================================================================
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "mediactrl.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
31 //---------------------------------------------------------------------------
33 //---------------------------------------------------------------------------
34 #include "wx/mediactrl.h"
36 //---------------------------------------------------------------------------
38 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
42 // Externals (somewhere in src/msw/app.cpp)
43 //---------------------------------------------------------------------------
44 extern "C" WXDLLIMPEXP_BASE HINSTANCE
wxGetInstance(void);
46 extern WXDLLIMPEXP_CORE wxChar
*wxCanvasClassName
;
48 extern WXDLLIMPEXP_CORE
const wxChar
*wxCanvasClassName
;
51 //===========================================================================
52 // BACKEND DECLARATIONS
53 //===========================================================================
55 //---------------------------------------------------------------------------
59 //---------------------------------------------------------------------------
61 //---------------------------------------------------------------------------
62 // Compilation guard for DirectShow
63 //---------------------------------------------------------------------------
66 //---------------------------------------------------------------------------
68 //---------------------------------------------------------------------------
69 #include "wx/msw/ole/oleutils.h" //wxBasicString, IID etc.
70 #include "wx/msw/ole/uuid.h" //IID etc..
72 //---------------------------------------------------------------------------
73 // IIDS - used by CoCreateInstance and IUnknown::QueryInterface
74 //---------------------------------------------------------------------------
75 const IID LIBID_QuartzTypeLib
= {0x56A868B0,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
76 const IID IID_IAMCollection
= {0x56A868B9,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
77 const IID IID_IMediaControl
= {0x56A868B1,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
78 const IID IID_IMediaEvent
= {0x56A868B6,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
79 const IID IID_IMediaEventEx
= {0x56A868C0,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
80 const IID IID_IMediaPosition
= {0x56A868B2,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
81 const IID IID_IBasicAudio
= {0x56A868B3,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
82 const IID IID_IVideoWindow
= {0x56A868B4,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
83 const IID IID_IBasicVideo
= {0x56A868B5,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
84 const IID IID_IBasicVideo2
= {0x329BB360,0xF6EA,0x11D1,{0x90,0x38,0x00,0xA0,0xC9,0x69,0x72,0x98}};
85 const IID IID_IDeferredCommand
= {0x56A868B8,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
86 const IID IID_IQueueCommand
= {0x56A868B7,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
87 const IID IID_IFilterInfo
= {0x56A868BA,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
88 const IID IID_IRegFilterInfo
= {0x56A868BB,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
89 const IID IID_IMediaTypeInfo
= {0x56A868BC,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
90 const IID IID_IPinInfo
= {0x56A868BD,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
91 const IID IID_IAMStats
= {0xBC9BCF80,0xDCD2,0x11D2,{0xAB,0xF6,0x00,0xA0,0xC9,0x05,0xF3,0x75}};
93 //TODO: These 4 lines needed?
97 #endif // CLSID_DEFINED
100 const CLSID CLSID_FilgraphManager
= {0xE436EBB3,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
102 //---------------------------------------------------------------------------
103 // COM INTERFACES (dumped from midl from quartz.idl from MSVC COM Browser)
104 //---------------------------------------------------------------------------
105 MIDL_INTERFACE("56A868B9-0AD4-11CE-B03A-0020AF0BA770")
106 IAMCollection
: public IDispatch
109 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Count(
110 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
112 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Item(
113 /* [in] */ long lItem
,
114 /* [out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
116 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get__NewEnum(
117 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
121 MIDL_INTERFACE("56A868B1-0AD4-11CE-B03A-0020AF0BA770")
122 IMediaControl
: public IDispatch
125 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Run( void) = 0;
127 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Pause( void) = 0;
129 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Stop( void) = 0;
131 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetState(
132 /* [in] */ long msTimeout
,
133 /* [out] */ long __RPC_FAR
*pfs
) = 0;
135 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
RenderFile(
136 /* [in] */ BSTR strFilename
) = 0;
138 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
AddSourceFilter(
139 /* [in] */ BSTR strFilename
,
140 /* [out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
142 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_FilterCollection(
143 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
145 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_RegFilterCollection(
146 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
148 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
StopWhenReady( void) = 0;
152 MIDL_INTERFACE("56A868B6-0AD4-11CE-B03A-0020AF0BA770")
153 IMediaEvent
: public IDispatch
156 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetEventHandle(
157 /* [out] */ LONG_PTR __RPC_FAR
*hEvent
) = 0;
159 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetEvent(
160 /* [out] */ long __RPC_FAR
*lEventCode
,
161 /* [out] */ LONG_PTR __RPC_FAR
*lParam1
,
162 /* [out] */ LONG_PTR __RPC_FAR
*lParam2
,
163 /* [in] */ long msTimeout
) = 0;
165 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
WaitForCompletion(
166 /* [in] */ long msTimeout
,
167 /* [out] */ long __RPC_FAR
*pEvCode
) = 0;
169 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
CancelDefaultHandling(
170 /* [in] */ long lEvCode
) = 0;
172 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
RestoreDefaultHandling(
173 /* [in] */ long lEvCode
) = 0;
175 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
FreeEventParams(
176 /* [in] */ long lEvCode
,
177 /* [in] */ LONG_PTR lParam1
,
178 /* [in] */ LONG_PTR lParam2
) = 0;
182 MIDL_INTERFACE("56A868C0-0AD4-11CE-B03A-0020AF0BA770")
183 IMediaEventEx
: public IMediaEvent
186 virtual HRESULT __stdcall
SetNotifyWindow(
187 /* [in] */ LONG_PTR hwnd
,
188 /* [in] */ long lMsg
,
189 /* [in] */ LONG_PTR lInstanceData
) = 0;
191 virtual HRESULT __stdcall
SetNotifyFlags(
192 /* [in] */ long lNoNotifyFlags
) = 0;
194 virtual HRESULT __stdcall
GetNotifyFlags(
195 /* [out] */ long __RPC_FAR
*lplNoNotifyFlags
) = 0;
199 MIDL_INTERFACE("56A868B2-0AD4-11CE-B03A-0020AF0BA770")
200 IMediaPosition
: public IDispatch
203 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Duration(
204 /* [retval][out] */ double __RPC_FAR
*plength
) = 0;
206 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_CurrentPosition(
207 /* [in] */ double pllTime
) = 0;
209 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_CurrentPosition(
210 /* [retval][out] */ double __RPC_FAR
*pllTime
) = 0;
212 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_StopTime(
213 /* [retval][out] */ double __RPC_FAR
*pllTime
) = 0;
215 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_StopTime(
216 /* [in] */ double pllTime
) = 0;
218 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_PrerollTime(
219 /* [retval][out] */ double __RPC_FAR
*pllTime
) = 0;
221 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_PrerollTime(
222 /* [in] */ double pllTime
) = 0;
224 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Rate(
225 /* [in] */ double pdRate
) = 0;
227 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Rate(
228 /* [retval][out] */ double __RPC_FAR
*pdRate
) = 0;
230 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
CanSeekForward(
231 /* [retval][out] */ long __RPC_FAR
*pCanSeekForward
) = 0;
233 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
CanSeekBackward(
234 /* [retval][out] */ long __RPC_FAR
*pCanSeekBackward
) = 0;
238 MIDL_INTERFACE("56A868B3-0AD4-11CE-B03A-0020AF0BA770")
239 IBasicAudio
: public IDispatch
242 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Volume(
243 /* [in] */ long plVolume
) = 0;
245 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Volume(
246 /* [retval][out] */ long __RPC_FAR
*plVolume
) = 0;
248 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Balance(
249 /* [in] */ long plBalance
) = 0;
251 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Balance(
252 /* [retval][out] */ long __RPC_FAR
*plBalance
) = 0;
256 MIDL_INTERFACE("56A868B4-0AD4-11CE-B03A-0020AF0BA770")
257 IVideoWindow
: public IDispatch
260 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Caption(
261 /* [in] */ BSTR strCaption
) = 0;
263 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Caption(
264 /* [retval][out] */ BSTR __RPC_FAR
*strCaption
) = 0;
266 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_WindowStyle(
267 /* [in] */ long WindowStyle
) = 0;
269 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_WindowStyle(
270 /* [retval][out] */ long __RPC_FAR
*WindowStyle
) = 0;
272 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_WindowStyleEx(
273 /* [in] */ long WindowStyleEx
) = 0;
275 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_WindowStyleEx(
276 /* [retval][out] */ long __RPC_FAR
*WindowStyleEx
) = 0;
278 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_AutoShow(
279 /* [in] */ long AutoShow
) = 0;
281 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_AutoShow(
282 /* [retval][out] */ long __RPC_FAR
*AutoShow
) = 0;
284 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_WindowState(
285 /* [in] */ long WindowState
) = 0;
287 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_WindowState(
288 /* [retval][out] */ long __RPC_FAR
*WindowState
) = 0;
290 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_BackgroundPalette(
291 /* [in] */ long pBackgroundPalette
) = 0;
293 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_BackgroundPalette(
294 /* [retval][out] */ long __RPC_FAR
*pBackgroundPalette
) = 0;
296 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Visible(
297 /* [in] */ long pVisible
) = 0;
299 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Visible(
300 /* [retval][out] */ long __RPC_FAR
*pVisible
) = 0;
302 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Left(
303 /* [in] */ long pLeft
) = 0;
305 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Left(
306 /* [retval][out] */ long __RPC_FAR
*pLeft
) = 0;
308 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Width(
309 /* [in] */ long pWidth
) = 0;
311 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Width(
312 /* [retval][out] */ long __RPC_FAR
*pWidth
) = 0;
314 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Top(
315 /* [in] */ long pTop
) = 0;
317 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Top(
318 /* [retval][out] */ long __RPC_FAR
*pTop
) = 0;
320 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Height(
321 /* [in] */ long pHeight
) = 0;
323 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Height(
324 /* [retval][out] */ long __RPC_FAR
*pHeight
) = 0;
326 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Owner(
327 /* [in] */ LONG_PTR Owner
) = 0;
329 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Owner(
330 /* [retval][out] */ LONG_PTR __RPC_FAR
*Owner
) = 0;
332 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_MessageDrain(
333 /* [in] */ LONG_PTR Drain
) = 0;
335 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_MessageDrain(
336 /* [retval][out] */ LONG_PTR __RPC_FAR
*Drain
) = 0;
338 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_BorderColor(
339 /* [retval][out] */ long __RPC_FAR
*Color
) = 0;
341 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_BorderColor(
342 /* [in] */ long Color
) = 0;
344 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_FullScreenMode(
345 /* [retval][out] */ long __RPC_FAR
*FullScreenMode
) = 0;
347 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_FullScreenMode(
348 /* [in] */ long FullScreenMode
) = 0;
350 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetWindowForeground(
351 /* [in] */ long Focus
) = 0;
353 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
NotifyOwnerMessage(
354 /* [in] */ LONG_PTR hwnd
,
355 /* [in] */ long uMsg
,
356 /* [in] */ LONG_PTR wParam
,
357 /* [in] */ LONG_PTR lParam
) = 0;
359 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetWindowPosition(
360 /* [in] */ long Left
,
362 /* [in] */ long Width
,
363 /* [in] */ long Height
) = 0;
365 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetWindowPosition(
366 /* [out] */ long __RPC_FAR
*pLeft
,
367 /* [out] */ long __RPC_FAR
*pTop
,
368 /* [out] */ long __RPC_FAR
*pWidth
,
369 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
371 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetMinIdealImageSize(
372 /* [out] */ long __RPC_FAR
*pWidth
,
373 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
375 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetMaxIdealImageSize(
376 /* [out] */ long __RPC_FAR
*pWidth
,
377 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
379 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetRestorePosition(
380 /* [out] */ long __RPC_FAR
*pLeft
,
381 /* [out] */ long __RPC_FAR
*pTop
,
382 /* [out] */ long __RPC_FAR
*pWidth
,
383 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
385 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
HideCursor(
386 /* [in] */ long HideCursor
) = 0;
388 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
IsCursorHidden(
389 /* [out] */ long __RPC_FAR
*CursorHidden
) = 0;
393 MIDL_INTERFACE("56A868B5-0AD4-11CE-B03A-0020AF0BA770")
394 IBasicVideo
: public IDispatch
397 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_AvgTimePerFrame(
398 /* [retval][out] */ double __RPC_FAR
*pAvgTimePerFrame
) = 0;
400 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_BitRate(
401 /* [retval][out] */ long __RPC_FAR
*pBitRate
) = 0;
403 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_BitErrorRate(
404 /* [retval][out] */ long __RPC_FAR
*pBitErrorRate
) = 0;
406 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_VideoWidth(
407 /* [retval][out] */ long __RPC_FAR
*pVideoWidth
) = 0;
409 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_VideoHeight(
410 /* [retval][out] */ long __RPC_FAR
*pVideoHeight
) = 0;
412 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_SourceLeft(
413 /* [in] */ long pSourceLeft
) = 0;
415 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_SourceLeft(
416 /* [retval][out] */ long __RPC_FAR
*pSourceLeft
) = 0;
418 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_SourceWidth(
419 /* [in] */ long pSourceWidth
) = 0;
421 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_SourceWidth(
422 /* [retval][out] */ long __RPC_FAR
*pSourceWidth
) = 0;
424 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_SourceTop(
425 /* [in] */ long pSourceTop
) = 0;
427 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_SourceTop(
428 /* [retval][out] */ long __RPC_FAR
*pSourceTop
) = 0;
430 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_SourceHeight(
431 /* [in] */ long pSourceHeight
) = 0;
433 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_SourceHeight(
434 /* [retval][out] */ long __RPC_FAR
*pSourceHeight
) = 0;
436 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_DestinationLeft(
437 /* [in] */ long pDestinationLeft
) = 0;
439 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_DestinationLeft(
440 /* [retval][out] */ long __RPC_FAR
*pDestinationLeft
) = 0;
442 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_DestinationWidth(
443 /* [in] */ long pDestinationWidth
) = 0;
445 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_DestinationWidth(
446 /* [retval][out] */ long __RPC_FAR
*pDestinationWidth
) = 0;
448 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_DestinationTop(
449 /* [in] */ long pDestinationTop
) = 0;
451 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_DestinationTop(
452 /* [retval][out] */ long __RPC_FAR
*pDestinationTop
) = 0;
454 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_DestinationHeight(
455 /* [in] */ long pDestinationHeight
) = 0;
457 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_DestinationHeight(
458 /* [retval][out] */ long __RPC_FAR
*pDestinationHeight
) = 0;
460 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetSourcePosition(
461 /* [in] */ long Left
,
463 /* [in] */ long Width
,
464 /* [in] */ long Height
) = 0;
466 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetSourcePosition(
467 /* [out] */ long __RPC_FAR
*pLeft
,
468 /* [out] */ long __RPC_FAR
*pTop
,
469 /* [out] */ long __RPC_FAR
*pWidth
,
470 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
472 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetDefaultSourcePosition( void) = 0;
474 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetDestinationPosition(
475 /* [in] */ long Left
,
477 /* [in] */ long Width
,
478 /* [in] */ long Height
) = 0;
480 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetDestinationPosition(
481 /* [out] */ long __RPC_FAR
*pLeft
,
482 /* [out] */ long __RPC_FAR
*pTop
,
483 /* [out] */ long __RPC_FAR
*pWidth
,
484 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
486 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
SetDefaultDestinationPosition( void) = 0;
488 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetVideoSize(
489 /* [out] */ long __RPC_FAR
*pWidth
,
490 /* [out] */ long __RPC_FAR
*pHeight
) = 0;
492 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetVideoPaletteEntries(
493 /* [in] */ long StartIndex
,
494 /* [in] */ long Entries
,
495 /* [out] */ long __RPC_FAR
*pRetrieved
,
496 /* [out] */ long __RPC_FAR
*pPalette
) = 0;
498 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetCurrentImage(
499 /* [out][in] */ long __RPC_FAR
*pBufferSize
,
500 /* [out] */ long __RPC_FAR
*pDIBImage
) = 0;
502 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
IsUsingDefaultSource( void) = 0;
504 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
IsUsingDefaultDestination( void) = 0;
508 MIDL_INTERFACE("329BB360-F6EA-11D1-9038-00A0C9697298")
509 IBasicVideo2
: public IBasicVideo
512 virtual HRESULT __stdcall
GetPreferredAspectRatio(
513 /* [out] */ long __RPC_FAR
*plAspectX
,
514 /* [out] */ long __RPC_FAR
*plAspectY
) = 0;
518 MIDL_INTERFACE("56A868B8-0AD4-11CE-B03A-0020AF0BA770")
519 IDeferredCommand
: public IUnknown
522 virtual HRESULT __stdcall
Cancel( void) = 0;
524 virtual HRESULT __stdcall
Confidence(
525 /* [out] */ long __RPC_FAR
*pConfidence
) = 0;
527 virtual HRESULT __stdcall
Postpone(
528 /* [in] */ double newtime
) = 0;
530 virtual HRESULT __stdcall
GetHResult(
531 /* [out] */ HRESULT __RPC_FAR
*phrResult
) = 0;
535 MIDL_INTERFACE("56A868B7-0AD4-11CE-B03A-0020AF0BA770")
536 IQueueCommand
: public IUnknown
539 virtual HRESULT __stdcall
InvokeAtStreamTime(
540 /* [out] */ IDeferredCommand __RPC_FAR
*__RPC_FAR
*pCmd
,
541 /* [in] */ double time
,
542 /* [in] */ GUID __RPC_FAR
*iid
,
543 /* [in] */ long dispidMethod
,
544 /* [in] */ short wFlags
,
545 /* [in] */ long cArgs
,
546 /* [in] */ VARIANT __RPC_FAR
*pDispParams
,
547 /* [out][in] */ VARIANT __RPC_FAR
*pvarResult
,
548 /* [out] */ short __RPC_FAR
*puArgErr
) = 0;
550 virtual HRESULT __stdcall
InvokeAtPresentationTime(
551 /* [out] */ IDeferredCommand __RPC_FAR
*__RPC_FAR
*pCmd
,
552 /* [in] */ double time
,
553 /* [in] */ GUID __RPC_FAR
*iid
,
554 /* [in] */ long dispidMethod
,
555 /* [in] */ short wFlags
,
556 /* [in] */ long cArgs
,
557 /* [in] */ VARIANT __RPC_FAR
*pDispParams
,
558 /* [out][in] */ VARIANT __RPC_FAR
*pvarResult
,
559 /* [out] */ short __RPC_FAR
*puArgErr
) = 0;
563 MIDL_INTERFACE("56A868BA-0AD4-11CE-B03A-0020AF0BA770")
564 IFilterInfo
: public IDispatch
567 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
FindPin(
568 /* [in] */ BSTR strPinID
,
569 /* [out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
571 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Name(
572 /* [retval][out] */ BSTR __RPC_FAR
*strName
) = 0;
574 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_VendorInfo(
575 /* [retval][out] */ BSTR __RPC_FAR
*strVendorInfo
) = 0;
577 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Filter(
578 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
580 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Pins(
581 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
583 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_IsFileSource(
584 /* [retval][out] */ long __RPC_FAR
*pbIsSource
) = 0;
586 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Filename(
587 /* [retval][out] */ BSTR __RPC_FAR
*pstrFilename
) = 0;
589 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE
put_Filename(
590 /* [in] */ BSTR pstrFilename
) = 0;
594 MIDL_INTERFACE("56A868BB-0AD4-11CE-B03A-0020AF0BA770")
595 IRegFilterInfo
: public IDispatch
598 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Name(
599 /* [retval][out] */ BSTR __RPC_FAR
*strName
) = 0;
601 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Filter(
602 /* [out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
606 MIDL_INTERFACE("56A868BC-0AD4-11CE-B03A-0020AF0BA770")
607 IMediaTypeInfo
: public IDispatch
610 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Type(
611 /* [retval][out] */ BSTR __RPC_FAR
*strType
) = 0;
613 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Subtype(
614 /* [retval][out] */ BSTR __RPC_FAR
*strType
) = 0;
618 MIDL_INTERFACE("56A868BD-0AD4-11CE-B03A-0020AF0BA770")
619 IPinInfo
: public IDispatch
622 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Pin(
623 /* [retval][out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
625 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_ConnectedTo(
626 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
628 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_ConnectionMediaType(
629 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
631 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_FilterInfo(
632 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
634 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Name(
635 /* [retval][out] */ BSTR __RPC_FAR
*ppUnk
) = 0;
637 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Direction(
638 /* [retval][out] */ long __RPC_FAR
*ppDirection
) = 0;
640 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_PinID(
641 /* [retval][out] */ BSTR __RPC_FAR
*strPinID
) = 0;
643 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_MediaTypes(
644 /* [retval][out] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppUnk
) = 0;
646 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Connect(
647 /* [in] */ IUnknown __RPC_FAR
*pPin
) = 0;
649 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
ConnectDirect(
650 /* [in] */ IUnknown __RPC_FAR
*pPin
) = 0;
652 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
ConnectWithType(
653 /* [in] */ IUnknown __RPC_FAR
*pPin
,
654 /* [in] */ IDispatch __RPC_FAR
*pMediaType
) = 0;
656 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Disconnect( void) = 0;
658 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Render( void) = 0;
662 MIDL_INTERFACE("BC9BCF80-DCD2-11D2-ABF6-00A0C905F375")
663 IAMStats
: public IDispatch
666 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
Reset( void) = 0;
668 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE
get_Count(
669 /* [retval][out] */ long __RPC_FAR
*plCount
) = 0;
671 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetValueByIndex(
672 /* [in] */ long lIndex
,
673 /* [out] */ BSTR __RPC_FAR
*szName
,
674 /* [out] */ long __RPC_FAR
*lCount
,
675 /* [out] */ double __RPC_FAR
*dLast
,
676 /* [out] */ double __RPC_FAR
*dAverage
,
677 /* [out] */ double __RPC_FAR
*dStdDev
,
678 /* [out] */ double __RPC_FAR
*dMin
,
679 /* [out] */ double __RPC_FAR
*dMax
) = 0;
681 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetValueByName(
682 /* [in] */ BSTR szName
,
683 /* [out] */ long __RPC_FAR
*lIndex
,
684 /* [out] */ long __RPC_FAR
*lCount
,
685 /* [out] */ double __RPC_FAR
*dLast
,
686 /* [out] */ double __RPC_FAR
*dAverage
,
687 /* [out] */ double __RPC_FAR
*dStdDev
,
688 /* [out] */ double __RPC_FAR
*dMin
,
689 /* [out] */ double __RPC_FAR
*dMax
) = 0;
691 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
GetIndex(
692 /* [in] */ BSTR szName
,
693 /* [in] */ long lCreate
,
694 /* [out] */ long __RPC_FAR
*plIndex
) = 0;
696 virtual /* [id] */ HRESULT STDMETHODCALLTYPE
AddValue(
697 /* [in] */ long lIndex
,
698 /* [in] */ double dValue
) = 0;
702 //------------------------------------------------------------------
703 // wxAMMediaBackend (Active Movie)
704 //------------------------------------------------------------------
705 class WXDLLIMPEXP_MEDIA wxAMMediaBackend
: public wxMediaBackend
710 virtual ~wxAMMediaBackend();
712 virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
717 const wxValidator
& validator
,
718 const wxString
& name
);
721 virtual bool Pause();
724 virtual bool Load(const wxString
& fileName
);
725 virtual bool Load(const wxURI
& location
);
727 virtual wxMediaState
GetState();
729 virtual bool SetPosition(wxLongLong where
);
730 virtual wxLongLong
GetPosition();
731 virtual wxLongLong
GetDuration();
733 virtual void Move(int x
, int y
, int w
, int h
);
734 wxSize
GetVideoSize() const;
736 virtual double GetPlaybackRate();
737 virtual bool SetPlaybackRate(double);
739 virtual double GetVolume();
740 virtual bool SetVolume(double);
746 static LRESULT CALLBACK
NotifyWndProc(HWND hWnd
, UINT nMsg
,
747 WPARAM wParam
, LPARAM lParam
);
749 LRESULT CALLBACK
OnNotifyWndProc(HWND hWnd
, UINT nMsg
,
750 WPARAM wParam
, LPARAM lParam
);
756 IMediaControl
* m_pMC
;
757 IMediaEventEx
* m_pME
;
758 IMediaPosition
* m_pMS
;
764 DECLARE_DYNAMIC_CLASS(wxAMMediaBackend
);
767 #endif //wxUSE_DIRECTSHOW
769 //---------------------------------------------------------------------------
773 //---------------------------------------------------------------------------
775 //---------------------------------------------------------------------------
777 //---------------------------------------------------------------------------
778 #include <mmsystem.h>
780 class WXDLLIMPEXP_MEDIA wxMCIMediaBackend
: public wxMediaBackend
785 ~wxMCIMediaBackend();
787 virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
792 const wxValidator
& validator
,
793 const wxString
& name
);
796 virtual bool Pause();
799 virtual bool Load(const wxString
& fileName
);
800 virtual bool Load(const wxURI
& location
);
802 virtual wxMediaState
GetState();
804 virtual bool SetPosition(wxLongLong where
);
805 virtual wxLongLong
GetPosition();
806 virtual wxLongLong
GetDuration();
808 virtual void Move(int x
, int y
, int w
, int h
);
809 wxSize
GetVideoSize() const;
811 virtual double GetPlaybackRate();
812 virtual bool SetPlaybackRate(double dRate
);
814 virtual double GetVolume();
815 virtual bool SetVolume(double);
817 static LRESULT CALLBACK
NotifyWndProc(HWND hWnd
, UINT nMsg
,
818 WPARAM wParam
, LPARAM lParam
);
820 LRESULT CALLBACK
OnNotifyWndProc(HWND hWnd
, UINT nMsg
,
821 WPARAM wParam
, LPARAM lParam
);
823 MCIDEVICEID m_hDev
; //Our MCI Device ID/Handler
824 wxControl
* m_ctrl
; //Parent control
825 HWND m_hNotifyWnd
; //Window to use for MCI events
826 bool m_bVideo
; //Whether or not we have video
828 DECLARE_DYNAMIC_CLASS(wxMCIMediaBackend
)
831 //---------------------------------------------------------------------------
835 //---------------------------------------------------------------------------
837 //---------------------------------------------------------------------------
838 // QT Compilation Guard
839 //---------------------------------------------------------------------------
842 //---------------------------------------------------------------------------
844 //---------------------------------------------------------------------------
845 //#include <qtml.h> //Windoze QT include
846 //#include <QuickTimeComponents.h> //Standard QT stuff
847 #include "wx/dynlib.h"
849 //---------------------------------------------------------------------------
851 //---------------------------------------------------------------------------
852 typedef struct MovieRecord
* Movie
;
853 typedef wxInt16 OSErr
;
854 typedef wxInt32 OSStatus
;
857 typedef unsigned char Str255
[256];
858 #define StringPtr unsigned char*
859 #define newMovieActive 1
863 #define OSType unsigned long
864 #define CGrafPtr struct GrafPort *
865 #define TimeScale long
866 #define TimeBase struct TimeBaseRecord *
871 Str255 name
; /*Str63 on mac, Str255 on msw */
887 wide value
; /* units */
888 TimeScale scale
; /* units per second */
892 //---------------------------------------------------------------------------
894 //---------------------------------------------------------------------------
895 #define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
896 typedef rettype (* name ## Type) args ; \
897 name ## Type pfn_ ## name; \
899 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
901 #define wxDL_VOIDMETHOD_DEFINE( name, args, shortargs ) \
902 typedef void (* name ## Type) args ; \
903 name ## Type pfn_ ## name; \
905 { if (m_ok) pfn_ ## name shortargs ; }
907 #define wxDL_METHOD_LOAD( lib, name, success ) \
908 pfn_ ## name = (name ## Type) lib.GetSymbol( wxT(#name), &success ); \
909 if (!success) return false;
911 //Class that utilizes Robert Roeblings Dynamic Library Macros
912 class wxQuickTimeLibrary
915 ~wxQuickTimeLibrary()
922 bool IsOk() const {return m_ok
;}
925 wxDynamicLibrary m_dll
;
929 wxDL_VOIDMETHOD_DEFINE( StartMovie
, (Movie m
), (m
) );
930 wxDL_VOIDMETHOD_DEFINE( StopMovie
, (Movie m
), (m
) );
931 wxDL_METHOD_DEFINE( bool, IsMovieDone
, (Movie m
), (m
), false);
932 wxDL_VOIDMETHOD_DEFINE( GoToBeginningOfMovie
, (Movie m
), (m
) );
933 wxDL_METHOD_DEFINE( OSErr
, GetMoviesError
, (), (), -1);
934 wxDL_METHOD_DEFINE( OSErr
, EnterMovies
, (), (), -1);
935 wxDL_VOIDMETHOD_DEFINE( ExitMovies
, (), () );
936 wxDL_METHOD_DEFINE( OSErr
, InitializeQTML
, (long flags
), (flags
), -1);
937 wxDL_VOIDMETHOD_DEFINE( TerminateQTML
, (), () );
939 wxDL_METHOD_DEFINE( OSErr
, NativePathNameToFSSpec
,
940 (char* inName
, FSSpec
* outFile
, long flags
),
941 (inName
, outFile
, flags
), -1);
943 wxDL_METHOD_DEFINE( OSErr
, OpenMovieFile
,
944 (const FSSpec
* fileSpec
, short * resRefNum
, wxInt8 permission
),
945 (fileSpec
, resRefNum
, permission
), -1 );
947 wxDL_METHOD_DEFINE( OSErr
, CloseMovieFile
,
948 (short resRefNum
), (resRefNum
), -1);
950 wxDL_METHOD_DEFINE( OSErr
, NewMovieFromFile
,
951 (Movie
* theMovie
, short resRefNum
, short * resId
,
952 StringPtr resName
, short newMovieFlags
,
953 bool * dataRefWasChanged
),
954 (theMovie
, resRefNum
, resId
, resName
, newMovieFlags
,
955 dataRefWasChanged
), -1);
957 wxDL_VOIDMETHOD_DEFINE( SetMovieRate
, (Movie m
, Fixed rate
), (m
, rate
) );
958 wxDL_METHOD_DEFINE( Fixed
, GetMovieRate
, (Movie m
), (m
), 0);
959 wxDL_VOIDMETHOD_DEFINE( MoviesTask
, (Movie m
, long maxms
), (m
, maxms
) );
960 wxDL_VOIDMETHOD_DEFINE( BlockMove
,
961 (const char* p1
, const char* p2
, long s
), (p1
,p2
,s
) );
962 wxDL_METHOD_DEFINE( Handle
, NewHandleClear
, (long s
), (s
), NULL
);
964 wxDL_METHOD_DEFINE( OSErr
, NewMovieFromDataRef
,
965 (Movie
* m
, short flags
, short * id
,
966 Handle dataRef
, OSType dataRefType
),
967 (m
,flags
,id
,dataRef
,dataRefType
), -1 );
969 wxDL_VOIDMETHOD_DEFINE( DisposeHandle
, (Handle h
), (h
) );
970 wxDL_VOIDMETHOD_DEFINE( GetMovieNaturalBoundsRect
, (Movie m
, Rect
* r
), (m
,r
) );
971 wxDL_METHOD_DEFINE( void*, GetMovieIndTrackType
,
972 (Movie m
, long index
, OSType type
, long flags
),
973 (m
,index
,type
,flags
), NULL
);
974 wxDL_VOIDMETHOD_DEFINE( CreatePortAssociation
,
975 (void* hWnd
, void* junk
, long morejunk
), (hWnd
, junk
, morejunk
) );
976 wxDL_METHOD_DEFINE(void*, GetNativeWindowPort
, (void* hWnd
), (hWnd
), NULL
);
977 wxDL_VOIDMETHOD_DEFINE(SetMovieGWorld
, (Movie m
, CGrafPtr port
, void* whatever
),
978 (m
, port
, whatever
) );
979 wxDL_VOIDMETHOD_DEFINE(DisposeMovie
, (Movie m
), (m
) );
980 wxDL_VOIDMETHOD_DEFINE(SetMovieBox
, (Movie m
, Rect
* r
), (m
,r
));
981 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeScale
, (Movie m
, long s
), (m
,s
));
982 wxDL_METHOD_DEFINE(long, GetMovieDuration
, (Movie m
), (m
), 0);
983 wxDL_METHOD_DEFINE(TimeBase
, GetMovieTimeBase
, (Movie m
), (m
), 0);
984 wxDL_METHOD_DEFINE(TimeScale
, GetMovieTimeScale
, (Movie m
), (m
), 0);
985 wxDL_METHOD_DEFINE(long, GetMovieTime
, (Movie m
, void* cruft
), (m
,cruft
), 0);
986 wxDL_VOIDMETHOD_DEFINE(SetMovieTime
, (Movie m
, TimeRecord
* tr
), (m
,tr
) );
987 wxDL_METHOD_DEFINE(short, GetMovieVolume
, (Movie m
), (m
), 0);
988 wxDL_VOIDMETHOD_DEFINE(SetMovieVolume
, (Movie m
, short sVolume
), (m
,sVolume
) );
991 bool wxQuickTimeLibrary::Initialize()
995 if(!m_dll
.Load(wxT("qtmlClient.dll")))
1000 wxDL_METHOD_LOAD( m_dll
, StartMovie
, bOk
);
1001 wxDL_METHOD_LOAD( m_dll
, StopMovie
, bOk
);
1002 wxDL_METHOD_LOAD( m_dll
, IsMovieDone
, bOk
);
1003 wxDL_METHOD_LOAD( m_dll
, GoToBeginningOfMovie
, bOk
);
1004 wxDL_METHOD_LOAD( m_dll
, GetMoviesError
, bOk
);
1005 wxDL_METHOD_LOAD( m_dll
, EnterMovies
, bOk
);
1006 wxDL_METHOD_LOAD( m_dll
, ExitMovies
, bOk
);
1007 wxDL_METHOD_LOAD( m_dll
, InitializeQTML
, bOk
);
1008 wxDL_METHOD_LOAD( m_dll
, TerminateQTML
, bOk
);
1009 wxDL_METHOD_LOAD( m_dll
, NativePathNameToFSSpec
, bOk
);
1010 wxDL_METHOD_LOAD( m_dll
, OpenMovieFile
, bOk
);
1011 wxDL_METHOD_LOAD( m_dll
, CloseMovieFile
, bOk
);
1012 wxDL_METHOD_LOAD( m_dll
, NewMovieFromFile
, bOk
);
1013 wxDL_METHOD_LOAD( m_dll
, GetMovieRate
, bOk
);
1014 wxDL_METHOD_LOAD( m_dll
, SetMovieRate
, bOk
);
1015 wxDL_METHOD_LOAD( m_dll
, MoviesTask
, bOk
);
1016 wxDL_METHOD_LOAD( m_dll
, BlockMove
, bOk
);
1017 wxDL_METHOD_LOAD( m_dll
, NewHandleClear
, bOk
);
1018 wxDL_METHOD_LOAD( m_dll
, NewMovieFromDataRef
, bOk
);
1019 wxDL_METHOD_LOAD( m_dll
, DisposeHandle
, bOk
);
1020 wxDL_METHOD_LOAD( m_dll
, GetMovieNaturalBoundsRect
, bOk
);
1021 wxDL_METHOD_LOAD( m_dll
, GetMovieIndTrackType
, bOk
);
1022 wxDL_METHOD_LOAD( m_dll
, CreatePortAssociation
, bOk
);
1023 wxDL_METHOD_LOAD( m_dll
, GetNativeWindowPort
, bOk
);
1024 wxDL_METHOD_LOAD( m_dll
, SetMovieGWorld
, bOk
);
1025 wxDL_METHOD_LOAD( m_dll
, DisposeMovie
, bOk
);
1026 wxDL_METHOD_LOAD( m_dll
, SetMovieBox
, bOk
);
1027 wxDL_METHOD_LOAD( m_dll
, SetMovieTimeScale
, bOk
);
1028 wxDL_METHOD_LOAD( m_dll
, GetMovieDuration
, bOk
);
1029 wxDL_METHOD_LOAD( m_dll
, GetMovieTimeBase
, bOk
);
1030 wxDL_METHOD_LOAD( m_dll
, GetMovieTimeScale
, bOk
);
1031 wxDL_METHOD_LOAD( m_dll
, GetMovieTime
, bOk
);
1032 wxDL_METHOD_LOAD( m_dll
, SetMovieTime
, bOk
);
1033 wxDL_METHOD_LOAD( m_dll
, GetMovieVolume
, bOk
);
1034 wxDL_METHOD_LOAD( m_dll
, SetMovieVolume
, bOk
);
1041 class WXDLLIMPEXP_MEDIA wxQTMediaBackend
: public wxMediaBackend
1046 ~wxQTMediaBackend();
1048 virtual bool CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
1053 const wxValidator
& validator
,
1054 const wxString
& name
);
1056 virtual bool Play();
1057 virtual bool Pause();
1058 virtual bool Stop();
1060 virtual bool Load(const wxString
& fileName
);
1061 virtual bool Load(const wxURI
& location
);
1063 virtual wxMediaState
GetState();
1065 virtual bool SetPosition(wxLongLong where
);
1066 virtual wxLongLong
GetPosition();
1067 virtual wxLongLong
GetDuration();
1069 virtual void Move(int x
, int y
, int w
, int h
);
1070 wxSize
GetVideoSize() const;
1072 virtual double GetPlaybackRate();
1073 virtual bool SetPlaybackRate(double dRate
);
1075 virtual double GetVolume();
1076 virtual bool SetVolume(double);
1081 wxSize m_bestSize
; //Original movie size
1082 Movie m_movie
; //QT Movie handle/instance
1083 wxControl
* m_ctrl
; //Parent control
1084 bool m_bVideo
; //Whether or not we have video
1085 class _wxQTTimer
* m_timer
; //Timer for streaming the movie
1086 wxQuickTimeLibrary m_lib
;
1089 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend
);
1092 //---------------------------------------------------------------------------
1093 // End QT Compilation Guard
1094 //---------------------------------------------------------------------------
1095 #endif //wxUSE_QUICKTIME
1097 //===========================================================================
1099 //===========================================================================
1101 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1105 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1107 //---------------------------------------------------------------------------
1108 // Only use if user wants it -
1109 //---------------------------------------------------------------------------
1110 #if wxUSE_DIRECTSHOW
1112 IMPLEMENT_DYNAMIC_CLASS(wxAMMediaBackend
, wxMediaBackend
);
1114 // Numerical value for when the graph reaches the stop position
1115 #define WM_GRAPHNOTIFY WM_USER+13
1117 //---------------------------------------------------------------------------
1118 // Usual debugging macros
1119 //---------------------------------------------------------------------------
1121 #define wxAMVERIFY(x) \
1123 HRESULT hrdsv = (x); \
1124 if ( FAILED(hrdsv) ) \
1126 /*TCHAR szError[MAX_ERROR_TEXT_LEN];*/ \
1127 /*if( AMGetErrorText(hrdsv, szError, MAX_ERROR_TEXT_LEN) == 0)*/ \
1129 /*wxFAIL_MSG( wxString::Format(wxT("DirectShow error \"%s\" ")*/\
1130 /*wxT("occured at line %i in ")*/ \
1131 /*wxT("mediactrl.cpp"),*/ \
1132 /*szError, __LINE__) );*/ \
1135 wxFAIL_MSG( wxString::Format(wxT("Unknown error (%i) ") \
1137 wxT(" line %i in mediactrl.cpp."), \
1138 (int)hrdsv, __LINE__) ); \
1141 #define wxVERIFY(x) wxASSERT((x))
1143 #define wxAMVERIFY(x) (x)
1144 #define wxVERIFY(x) (x)
1147 //---------------------------------------------------------------------------
1148 // Standard macros for ease of use
1149 //---------------------------------------------------------------------------
1150 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
1152 //---------------------------------------------------------------------------
1153 // wxAMMediaBackend Constructor
1155 // Sets m_hNotifyWnd to NULL to signify that we haven't loaded anything yet
1156 //---------------------------------------------------------------------------
1157 wxAMMediaBackend::wxAMMediaBackend() : m_hNotifyWnd(NULL
)
1161 //---------------------------------------------------------------------------
1162 // wxAMMediaBackend Destructor
1164 // Cleans up everything
1165 //---------------------------------------------------------------------------
1166 wxAMMediaBackend::~wxAMMediaBackend()
1172 //---------------------------------------------------------------------------
1173 // wxAMMediaBackend::CreateControl
1175 // ActiveMovie does not really have any native control to speak of,
1176 // so we just create a normal control.
1178 // We also check to see if ActiveMovie is installed
1179 //---------------------------------------------------------------------------
1180 bool wxAMMediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
1185 const wxValidator
& validator
,
1186 const wxString
& name
)
1188 //create our filter graph - the beuty of COM is that it loads
1189 //quartz.dll for us :)
1190 HRESULT hr
= CoCreateInstance(CLSID_FilgraphManager
, NULL
, CLSCTX_INPROC_SERVER
,
1191 IID_IMediaControl
, (void**)&m_pMC
);
1193 //directshow not installed?
1197 //release the filter graph - we don't need it yet
1203 // By default wxWindow(s) is created with a border -
1204 // so we need to get rid of those, and create with
1205 // wxCLIP_CHILDREN, so that if the driver/backend
1206 // is a child window, it refereshes properly
1208 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
1209 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
| wxCLIP_CHILDREN
,
1218 //---------------------------------------------------------------------------
1219 // wxAMMediaBackend::Load (file version)
1221 // Creates an Active Movie filter graph from a file or url
1222 //---------------------------------------------------------------------------
1223 bool wxAMMediaBackend::Load(const wxString
& fileName
)
1225 //if previously loaded cleanup
1229 //We already checked for success in CreateControl
1230 CoCreateInstance(CLSID_FilgraphManager
, NULL
, CLSCTX_INPROC_SERVER
,
1231 IID_IMediaControl
, (void**)&m_pMC
);
1233 //load the graph & render
1234 if( FAILED(m_pMC
->RenderFile(wxBasicString(fileName
).Get())) )
1237 //get the interfaces, all of them
1238 wxAMVERIFY( m_pMC
->QueryInterface(IID_IMediaEventEx
, (void**)&m_pME
) );
1239 wxAMVERIFY( m_pMC
->QueryInterface(IID_IMediaPosition
, (void**)&m_pMS
) );
1240 wxAMVERIFY( m_pMC
->QueryInterface(IID_IVideoWindow
, (void**)&m_pVW
) );
1241 wxAMVERIFY( m_pMC
->QueryInterface(IID_IBasicAudio
, (void**)&m_pBA
) );
1242 wxAMVERIFY( m_pMC
->QueryInterface(IID_IBasicVideo
, (void**)&m_pBV
) );
1244 //We could tell if the media has audio or not by
1248 //pBA->get_Volume(&lVolume) == E_NOTIMPL
1253 //Obtain the _actual_ size of the movie & remember it
1258 m_bestSize
.x
= m_bestSize
.y
= 0;
1260 m_bVideo
= SUCCEEDED( m_pVW
->GetWindowPosition( &nX
,
1262 (long*)&m_bestSize
.x
,
1263 (long*)&m_bestSize
.y
) );
1266 //If we have video in the media - set it up so that
1267 //its a child window of the control, its visible,
1268 //and that the control is the owner of the video window
1272 wxAMVERIFY( m_pVW
->put_Owner((LONG_PTR
)m_ctrl
->GetHandle()) );
1273 wxAMVERIFY( m_pVW
->put_WindowStyle(WS_CHILD
| WS_CLIPSIBLINGS
) );
1274 wxAMVERIFY( m_pVW
->put_Visible(-1) ); //OATRUE == -1
1278 // Create a hidden window and register to handle
1279 // directshow events for this graph
1280 // Note that wxCanvasClassName is already registered
1281 // and used by all wxWindows and normal wxControls
1283 m_hNotifyWnd
= ::CreateWindow
1297 wxLogSysError( wxT("Could not create hidden needed for ")
1298 wxT("registering for DirectShow events!") );
1304 ::SetWindowLong(m_hNotifyWnd
, GWL_WNDPROC
,
1305 (LONG
)wxAMMediaBackend::NotifyWndProc
);
1306 ::SetWindowLong(m_hNotifyWnd
, GWL_USERDATA
,
1309 ::SetWindowLongPtr(m_hNotifyWnd
, GWLP_WNDPROC
,
1310 (LONG_PTR
)wxAMMediaBackend::NotifyWndProc
);
1311 ::SetWindowLongPtr(m_hNotifyWnd
, GWL_USERDATA
,
1316 wxAMVERIFY( m_pME
->SetNotifyWindow((LONG_PTR
)m_hNotifyWnd
,
1317 WM_GRAPHNOTIFY
, 0) );
1320 // Force the parent window of this control to recalculate
1321 // the size of this if sizers are being used
1322 // and render the results immediately
1324 m_ctrl
->InvalidateBestSize();
1325 m_ctrl
->GetParent()->Layout();
1326 m_ctrl
->GetParent()->Refresh();
1327 m_ctrl
->GetParent()->Update();
1328 m_ctrl
->SetSize(m_ctrl
->GetSize());
1333 //---------------------------------------------------------------------------
1334 // wxAMMediaBackend::Load (URL Version)
1336 // Loads media from a URL. Interestingly enough DirectShow
1337 // appears (?) to escape the URL for us, at least on normal
1339 //---------------------------------------------------------------------------
1340 bool wxAMMediaBackend::Load(const wxURI
& location
)
1342 return Load(location
.BuildUnescapedURI());
1345 //---------------------------------------------------------------------------
1346 // wxAMMediaBackend::Play
1348 // Plays the stream. If it is non-seekable, it will restart it.
1349 //---------------------------------------------------------------------------
1350 bool wxAMMediaBackend::Play()
1352 return SUCCEEDED( m_pMC
->Run() );
1355 //---------------------------------------------------------------------------
1356 // wxAMMediaBackend::Pause
1358 // Pauses the stream.
1359 //---------------------------------------------------------------------------
1360 bool wxAMMediaBackend::Pause()
1362 return SUCCEEDED( m_pMC
->Pause() );
1365 //---------------------------------------------------------------------------
1366 // wxAMMediaBackend::Stop
1368 // Stops the stream.
1369 //---------------------------------------------------------------------------
1370 bool wxAMMediaBackend::Stop()
1372 bool bOK
= SUCCEEDED( m_pMC
->Stop() );
1374 //We don't care if it can't get to the beginning in directshow -
1375 //it could be a non-seeking filter (wince midi) in which case playing
1376 //starts all over again
1381 //---------------------------------------------------------------------------
1382 // wxAMMediaBackend::SetPosition
1384 // 1) Translates the current position's time to directshow time,
1385 // which is in a scale of 1 second (in a double)
1386 // 2) Sets the play position of the IMediaSeeking interface -
1387 // passing NULL as the stop position means to keep the old
1389 //---------------------------------------------------------------------------
1390 bool wxAMMediaBackend::SetPosition(wxLongLong where
)
1392 return SUCCEEDED( m_pMS
->put_CurrentPosition(
1393 ((LONGLONG
)where
.GetValue()) / 1000
1398 //---------------------------------------------------------------------------
1399 // wxAMMediaBackend::GetPosition
1401 // 1) Obtains the current play and stop positions from IMediaSeeking
1402 // 2) Returns the play position translated to our time base
1403 //---------------------------------------------------------------------------
1404 wxLongLong
wxAMMediaBackend::GetPosition()
1407 wxAMVERIFY( m_pMS
->get_CurrentPosition(&outCur
) );
1409 //h,m,s,milli - outdur is in 1 second (double)
1410 return (outCur
*1000);
1413 //---------------------------------------------------------------------------
1414 // wxAMMediaBackend::SetVolume
1416 // Sets the volume through the IBasicAudio interface -
1417 // value ranges from 0 (MAX volume) to -10000 (minimum volume).
1418 // -100 per decibel.
1419 //---------------------------------------------------------------------------
1420 bool wxAMMediaBackend::SetVolume(double dVolume
)
1422 return SUCCEEDED(m_pBA
->put_Volume( (long) ((dVolume
-1.0) * 10000.0) ));
1425 //---------------------------------------------------------------------------
1426 // wxAMMediaBackend::GetVolume
1428 // Gets the volume through the IBasicAudio interface -
1429 // value ranges from 0 (MAX volume) to -10000 (minimum volume).
1430 // -100 per decibel.
1431 //---------------------------------------------------------------------------
1432 double wxAMMediaBackend::GetVolume()
1435 if ( SUCCEEDED(m_pBA
->get_Volume(&lVolume
)) )
1436 return (((double)(lVolume
+ 10000)) / 10000.0);
1440 //---------------------------------------------------------------------------
1441 // wxAMMediaBackend::GetDuration
1443 // 1) Obtains the duration of the media from the IMediaSeeking interface
1444 // 2) Converts that value to our time base, and returns it
1445 //---------------------------------------------------------------------------
1446 wxLongLong
wxAMMediaBackend::GetDuration()
1449 wxAMVERIFY( m_pMS
->get_Duration(&outDuration
) );
1451 //h,m,s,milli - outdur is in 1 second (double)
1452 return (outDuration
*1000);
1455 //---------------------------------------------------------------------------
1456 // wxAMMediaBackend::GetState
1458 // Obtains the state from the IMediaControl interface.
1459 // Note that it's enumeration values for stopping/playing
1460 // etc. are the same as ours, so we just do a straight cast.
1461 // TODO: MS recommends against INFINITE here for
1462 // IMediaControl::GetState- do it in stages
1463 //---------------------------------------------------------------------------
1464 wxMediaState
wxAMMediaBackend::GetState()
1467 long theState
; //OAFilterState
1468 hr
= m_pMC
->GetState(INFINITE
, &theState
);
1470 wxASSERT( SUCCEEDED(hr
) );
1472 //MSW state is the same as ours
1473 //State_Stopped = 0,
1474 //State_Paused = State_Stopped + 1,
1475 //State_Running = State_Paused + 1
1477 return (wxMediaState
) theState
;
1480 //---------------------------------------------------------------------------
1481 // wxAMMediaBackend::GetPlaybackRate
1483 // Pretty simple way of obtaining the playback rate from
1484 // the IMediaSeeking interface
1485 //---------------------------------------------------------------------------
1486 double wxAMMediaBackend::GetPlaybackRate()
1489 wxAMVERIFY( m_pMS
->get_Rate(&dRate
) );
1493 //---------------------------------------------------------------------------
1494 // wxAMMediaBackend::SetPlaybackRate
1496 // Sets the playback rate of the media - DirectShow is pretty good
1497 // about this, actually
1498 //---------------------------------------------------------------------------
1499 bool wxAMMediaBackend::SetPlaybackRate(double dRate
)
1501 return SUCCEEDED( m_pMS
->put_Rate(dRate
) );
1504 //---------------------------------------------------------------------------
1505 // wxAMMediaBackend::NotifyWndProc
1507 // Here we check to see if DirectShow tells us we've reached the stop
1508 // position in our stream - if it has, it may not actually stop
1509 // the stream - which we need to do...
1510 //---------------------------------------------------------------------------
1511 LRESULT CALLBACK
wxAMMediaBackend::NotifyWndProc(HWND hWnd
, UINT nMsg
,
1515 wxAMMediaBackend
* backend
= (wxAMMediaBackend
*)
1516 ::GetWindowLong(hWnd
, GWL_USERDATA
);
1518 return backend
->OnNotifyWndProc(hWnd
, nMsg
, wParam
, lParam
);
1521 LRESULT CALLBACK
wxAMMediaBackend::OnNotifyWndProc(HWND hWnd
, UINT nMsg
,
1525 if (nMsg
== WM_GRAPHNOTIFY
)
1532 // DirectShow keeps a list of queued events, and we need
1533 // to go through them one by one, stopping at (Hopefully only one)
1534 // EC_COMPLETE message
1536 while(SUCCEEDED(m_pME
->GetEvent(&evCode
, (LONG_PTR
*) &evParam1
,
1537 (LONG_PTR
*) &evParam2
, 0)
1541 // Cleanup memory that GetEvent allocated
1542 wxAMVERIFY( m_pME
->FreeEventParams(evCode
, evParam1
, evParam2
) );
1544 // If this is the end of the clip, notify handler
1545 if(1 == evCode
) //EC_COMPLETE
1547 //send the event to our child
1548 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
1549 m_ctrl
->ProcessEvent(theEvent
);
1551 //if the user didn't veto it, stop the stream
1552 if (theEvent
.IsAllowed())
1554 //Interestingly enough, DirectShow does not actually stop
1555 //the filters - even when it reaches the end!
1558 //send the event to our child
1559 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
,
1561 m_ctrl
->ProcessEvent(theEvent
);
1566 return DefWindowProc(hWnd
, nMsg
, wParam
, lParam
);
1569 //---------------------------------------------------------------------------
1570 // wxAMMediaBackend::Cleanup
1572 // 1) Hide/disowns the video window (MS says bad things will happen if
1574 // 2) Releases all the directshow interfaces we use
1575 // TODO: Maybe there's a way to redirect the IMediaControl each time
1576 // we load, rather then creating and destroying the interfaces
1578 //---------------------------------------------------------------------------
1579 void wxAMMediaBackend::Cleanup()
1581 // Hide then disown the window
1584 m_pVW
->put_Visible(0); //OSFALSE == 0
1585 m_pVW
->put_Owner(NULL
);
1588 // Release and zero DirectShow interfaces
1589 SAFE_RELEASE(m_pME
);
1590 SAFE_RELEASE(m_pMS
);
1591 SAFE_RELEASE(m_pBA
);
1592 SAFE_RELEASE(m_pBV
);
1593 SAFE_RELEASE(m_pVW
);
1594 SAFE_RELEASE(m_pMC
);
1596 // Get rid of our hidden Window
1597 DestroyWindow(m_hNotifyWnd
);
1598 m_hNotifyWnd
= NULL
;
1602 //---------------------------------------------------------------------------
1603 // wxAMMediaBackend::GetVideoSize
1605 // Obtains the cached original video size
1606 //---------------------------------------------------------------------------
1607 wxSize
wxAMMediaBackend::GetVideoSize() const
1612 //---------------------------------------------------------------------------
1613 // wxAMMediaBackend::Move
1615 // Resizes the IVideoWindow to the size of the control window
1616 //---------------------------------------------------------------------------
1617 void wxAMMediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
), int w
, int h
)
1619 if(m_hNotifyWnd
&& m_bVideo
)
1621 wxAMVERIFY( m_pVW
->SetWindowPosition(0, 0, w
, h
) );
1625 //---------------------------------------------------------------------------
1626 // End of wxAMMediaBackend
1627 //---------------------------------------------------------------------------
1628 #endif //wxUSE_DIRECTSHOW
1630 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1632 // wxMCIMediaBackend
1634 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1637 IMPLEMENT_DYNAMIC_CLASS(wxMCIMediaBackend
, wxMediaBackend
);
1639 //---------------------------------------------------------------------------
1640 // Usual debugging macros for MCI returns
1641 //---------------------------------------------------------------------------
1644 #define wxMCIVERIFY(arg) \
1647 if ( (nRet = (arg)) != 0) \
1650 mciGetErrorString(nRet, sz, 5000); \
1651 wxFAIL_MSG(wxString::Format(_T("MCI Error:%s"), sz)); \
1655 #define wxMCIVERIFY(arg) (arg);
1658 //---------------------------------------------------------------------------
1659 // Simulation for <digitalv.h>
1661 // Mingw and possibly other compilers don't have the digitalv.h header
1662 // that is needed to have some essential features of mci work with
1663 // windows - so we provide the declarations for the types we use here
1664 //---------------------------------------------------------------------------
1667 DWORD_PTR dwCallback
;
1668 #ifdef MCI_USE_OFFEXT
1674 } MCI_DGV_RECT_PARMS
;
1677 DWORD_PTR dwCallback
;
1687 } MCI_DGV_WINDOW_PARMS
;
1690 DWORD_PTR dwCallback
;
1695 } MCI_DGV_SET_PARMS
;
1698 DWORD_PTR dwCallback
;
1702 wxChar
* lpstrAlgorithm
;
1703 wxChar
* lpstrQuality
;
1704 } MCI_DGV_SETAUDIO_PARMS
;
1706 //---------------------------------------------------------------------------
1707 // wxMCIMediaBackend Constructor
1709 // Here we don't need to do much except say we don't have any video :)
1710 //---------------------------------------------------------------------------
1711 wxMCIMediaBackend::wxMCIMediaBackend() : m_hNotifyWnd(NULL
), m_bVideo(false)
1715 //---------------------------------------------------------------------------
1716 // wxMCIMediaBackend Destructor
1718 // We close the mci device - note that there may not be an mci device here,
1719 // or it may fail - but we don't really care, since we're destructing
1720 //---------------------------------------------------------------------------
1721 wxMCIMediaBackend::~wxMCIMediaBackend()
1725 mciSendCommand(m_hDev
, MCI_CLOSE
, 0, 0);
1726 DestroyWindow(m_hNotifyWnd
);
1727 m_hNotifyWnd
= NULL
;
1731 //---------------------------------------------------------------------------
1732 // wxMCIMediaBackend::Create
1734 // Here we just tell wxMediaCtrl that mci does exist (which it does, on all
1735 // msw systems, at least in some form dating back to win16 days)
1736 //---------------------------------------------------------------------------
1737 bool wxMCIMediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
1742 const wxValidator
& validator
,
1743 const wxString
& name
)
1747 // By default wxWindow(s) is created with a border -
1748 // so we need to get rid of those, and create with
1749 // wxCLIP_CHILDREN, so that if the driver/backend
1750 // is a child window, it refereshes properly
1752 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
1753 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
| wxCLIP_CHILDREN
,
1761 //---------------------------------------------------------------------------
1762 // wxMCIMediaBackend::Load (file version)
1764 // Here we have MCI load a file and device, set the time format to our
1765 // default (milliseconds), and set the video (if any) to play in the control
1766 //---------------------------------------------------------------------------
1767 bool wxMCIMediaBackend::Load(const wxString
& fileName
)
1770 //if the user already called load close the previous MCI device
1774 mciSendCommand(m_hDev
, MCI_CLOSE
, 0, 0);
1775 DestroyWindow(m_hNotifyWnd
);
1776 m_hNotifyWnd
= NULL
;
1780 //Opens a file and has MCI select a device. Normally you'd put
1781 //MCI_OPEN_TYPE in addition to MCI_OPEN_ELEMENT - however if you
1782 //omit this it tells MCI to select the device instead. This is
1783 //good because we have no reliable way of "enumerating" the devices
1786 MCI_OPEN_PARMS openParms
;
1787 openParms
.lpstrElementName
= (wxChar
*) fileName
.c_str();
1789 if ( mciSendCommand(0, MCI_OPEN
, MCI_OPEN_ELEMENT
,
1790 (DWORD
)(LPVOID
)&openParms
) != 0)
1793 m_hDev
= openParms
.wDeviceID
;
1796 //Now set the time format for the device to milliseconds
1798 MCI_SET_PARMS setParms
;
1799 setParms
.dwCallback
= 0;
1800 setParms
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
1802 if (mciSendCommand(m_hDev
, MCI_SET
, MCI_SET_TIME_FORMAT
,
1803 (DWORD
)(LPVOID
)&setParms
) != 0)
1807 //Now tell the MCI device to display the video in our wxMediaCtrl
1809 MCI_DGV_WINDOW_PARMS windowParms
;
1810 windowParms
.hWnd
= (HWND
)m_ctrl
->GetHandle();
1812 m_bVideo
= (mciSendCommand(m_hDev
, MCI_WINDOW
,
1813 0x00010000L
, //MCI_DGV_WINDOW_HWND
1814 (DWORD
)(LPVOID
)&windowParms
) == 0);
1817 // Create a hidden window and register to handle
1819 // Note that wxCanvasClassName is already registered
1820 // and used by all wxWindows and normal wxControls
1822 m_hNotifyWnd
= ::CreateWindow
1836 wxLogSysError( wxT("Could not create hidden needed for ")
1837 wxT("registering for DirectShow events!") );
1843 ::SetWindowLong(m_hNotifyWnd
, GWL_WNDPROC
,
1844 (LONG
)wxMCIMediaBackend::NotifyWndProc
);
1846 ::SetWindowLongPtr(m_hNotifyWnd
, GWLP_WNDPROC
,
1847 (LONG_PTR
)wxMCIMediaBackend::NotifyWndProc
);
1850 ::SetWindowLong(m_hNotifyWnd
, GWL_USERDATA
,
1854 //Here, if the parent of the control has a sizer - we
1855 //tell it to recalculate the size of this control since
1856 //the user opened a seperate media file
1858 m_ctrl
->InvalidateBestSize();
1859 m_ctrl
->GetParent()->Layout();
1860 m_ctrl
->GetParent()->Refresh();
1861 m_ctrl
->GetParent()->Update();
1862 m_ctrl
->SetSize(m_ctrl
->GetSize());
1867 //---------------------------------------------------------------------------
1868 // wxMCIMediaBackend::Load (URL version)
1870 // MCI doesn't support URLs directly (?)
1872 // TODO: Use wxURL/wxFileSystem and mmioInstallProc
1873 //---------------------------------------------------------------------------
1874 bool wxMCIMediaBackend::Load(const wxURI
& WXUNUSED(location
))
1879 //---------------------------------------------------------------------------
1880 // wxMCIMediaBackend::Play
1882 // Plays/Resumes the MCI device... a couple notes:
1883 // 1) Certain drivers will crash and burn if we don't pass them an
1884 // MCI_PLAY_PARMS, despite the documentation that says otherwise...
1885 // 2) There is a MCI_RESUME command, but MCI_PLAY does the same thing
1886 // and will resume from a stopped state also, so there's no need to
1887 // call both, for example
1888 //---------------------------------------------------------------------------
1889 bool wxMCIMediaBackend::Play()
1891 MCI_PLAY_PARMS playParms
;
1892 playParms
.dwCallback
= (DWORD
)m_hNotifyWnd
;
1894 bool bOK
= ( mciSendCommand(m_hDev
, MCI_PLAY
, MCI_NOTIFY
,
1895 (DWORD
)(LPVOID
)&playParms
) == 0 );
1898 m_ctrl
->Show(m_bVideo
);
1903 //---------------------------------------------------------------------------
1904 // wxMCIMediaBackend::Pause
1906 // Pauses the MCI device - nothing special
1907 //---------------------------------------------------------------------------
1908 bool wxMCIMediaBackend::Pause()
1910 return (mciSendCommand(m_hDev
, MCI_PAUSE
, MCI_WAIT
, 0) == 0);
1913 //---------------------------------------------------------------------------
1914 // wxMCIMediaBackend::Stop
1916 // Stops the MCI device & seeks to the beginning as wxMediaCtrl docs outline
1917 //---------------------------------------------------------------------------
1918 bool wxMCIMediaBackend::Stop()
1920 return (mciSendCommand(m_hDev
, MCI_STOP
, MCI_WAIT
, 0) == 0) &&
1921 (mciSendCommand(m_hDev
, MCI_SEEK
, MCI_SEEK_TO_START
, 0) == 0);
1924 //---------------------------------------------------------------------------
1925 // wxMCIMediaBackend::GetState
1927 // Here we get the state and convert it to a wxMediaState -
1928 // since we use direct comparisons with MCI_MODE_PLAY and
1929 // MCI_MODE_PAUSE, we don't care if the MCI_STATUS call
1931 //---------------------------------------------------------------------------
1932 wxMediaState
wxMCIMediaBackend::GetState()
1934 MCI_STATUS_PARMS statusParms
;
1935 statusParms
.dwItem
= MCI_STATUS_MODE
;
1937 mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
1938 (DWORD
)(LPVOID
)&statusParms
);
1940 if(statusParms
.dwReturn
== MCI_MODE_PAUSE
)
1941 return wxMEDIASTATE_PAUSED
;
1942 else if(statusParms
.dwReturn
== MCI_MODE_PLAY
)
1943 return wxMEDIASTATE_PLAYING
;
1945 return wxMEDIASTATE_STOPPED
;
1948 //---------------------------------------------------------------------------
1949 // wxMCIMediaBackend::SetPosition
1951 // Here we set the position of the device in the stream.
1952 // Note that MCI actually stops the device after you seek it if the
1953 // device is playing/paused, so we need to play the file after
1954 // MCI seeks like normal APIs would
1955 //---------------------------------------------------------------------------
1956 bool wxMCIMediaBackend::SetPosition(wxLongLong where
)
1958 MCI_SEEK_PARMS seekParms
;
1959 seekParms
.dwCallback
= 0;
1960 #if wxUSE_LONGLONG_NATIVE && !wxUSE_LONGLONG_WX
1961 seekParms
.dwTo
= (DWORD
)where
.GetValue();
1962 #else /* wxUSE_LONGLONG_WX */
1963 /* no way to return it in one piece */
1964 wxASSERT( where
.GetHi()==0 );
1965 seekParms
.dwTo
= (DWORD
)where
.GetLo();
1966 #endif /* wxUSE_LONGLONG_* */
1968 //device was playing?
1969 bool bReplay
= GetState() == wxMEDIASTATE_PLAYING
;
1971 if( mciSendCommand(m_hDev
, MCI_SEEK
, MCI_TO
,
1972 (DWORD
)(LPVOID
)&seekParms
) != 0)
1975 //If the device was playing, resume it
1982 //---------------------------------------------------------------------------
1983 // wxMCIMediaBackend::GetPosition
1985 // Gets the position of the device in the stream using the current
1986 // time format... nothing special here...
1987 //---------------------------------------------------------------------------
1988 wxLongLong
wxMCIMediaBackend::GetPosition()
1990 MCI_STATUS_PARMS statusParms
;
1991 statusParms
.dwItem
= MCI_STATUS_POSITION
;
1993 if (mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
1994 (DWORD
)(LPSTR
)&statusParms
) != 0)
1997 return statusParms
.dwReturn
;
2000 //---------------------------------------------------------------------------
2001 // wxMCIMediaBackend::GetVolume
2003 // Gets the volume of the current media via the MCI_DGV_STATUS_VOLUME
2004 // message. Value ranges from 0 (minimum) to 1000 (maximum volume).
2005 //---------------------------------------------------------------------------
2006 double wxMCIMediaBackend::GetVolume()
2008 MCI_STATUS_PARMS statusParms
;
2009 statusParms
.dwCallback
= NULL
;
2010 statusParms
.dwItem
= 0x4019; //MCI_DGV_STATUS_VOLUME
2012 if (mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
2013 (DWORD
)(LPSTR
)&statusParms
) != 0)
2016 return ((double)statusParms
.dwReturn
) / 1000.0;
2019 //---------------------------------------------------------------------------
2020 // wxMCIMediaBackend::SetVolume
2022 // Sets the volume of the current media via the MCI_DGV_SETAUDIO_VOLUME
2023 // message. Value ranges from 0 (minimum) to 1000 (maximum volume).
2024 //---------------------------------------------------------------------------
2025 bool wxMCIMediaBackend::SetVolume(double dVolume
)
2027 MCI_DGV_SETAUDIO_PARMS audioParms
;
2028 audioParms
.dwCallback
= NULL
;
2029 audioParms
.dwItem
= 0x4002; //MCI_DGV_SETAUDIO_VOLUME
2030 audioParms
.dwValue
= (DWORD
) (dVolume
* 1000.0);
2031 audioParms
.dwOver
= 0;
2032 audioParms
.lpstrAlgorithm
= NULL
;
2033 audioParms
.lpstrQuality
= NULL
;
2035 if (mciSendCommand(m_hDev
, 0x0873, //MCI_SETAUDIO
2036 0x00800000L
| 0x01000000L
, //MCI_DGV_SETAUDIO+(_ITEM | _VALUE)
2037 (DWORD
)(LPSTR
)&audioParms
) != 0)
2042 //---------------------------------------------------------------------------
2043 // wxMCIMediaBackend::GetDuration
2045 // Gets the duration of the stream... nothing special
2046 //---------------------------------------------------------------------------
2047 wxLongLong
wxMCIMediaBackend::GetDuration()
2049 MCI_STATUS_PARMS statusParms
;
2050 statusParms
.dwItem
= MCI_STATUS_LENGTH
;
2052 if (mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
2053 (DWORD
)(LPSTR
)&statusParms
) != 0)
2056 return statusParms
.dwReturn
;
2059 //---------------------------------------------------------------------------
2060 // wxMCIMediaBackend::Move
2062 // Moves the window to a location
2063 //---------------------------------------------------------------------------
2064 void wxMCIMediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
),
2067 if (m_hNotifyWnd
&& m_bVideo
)
2069 MCI_DGV_RECT_PARMS putParms
; //ifdefed MCI_DGV_PUT_PARMS
2070 memset(&putParms
, 0, sizeof(MCI_DGV_RECT_PARMS
));
2071 putParms
.rc
.bottom
= h
;
2072 putParms
.rc
.right
= w
;
2074 //wxStackWalker will crash and burn here on assert
2075 //and mci doesn't like 0 and 0 for some reason (out of range )
2076 //so just don't it in that case
2079 wxMCIVERIFY( mciSendCommand(m_hDev
, MCI_PUT
,
2080 0x00040000L
, //MCI_DGV_PUT_DESTINATION
2081 (DWORD
)(LPSTR
)&putParms
) );
2086 //---------------------------------------------------------------------------
2087 // wxMCIMediaBackend::GetVideoSize
2089 // Gets the original size of the movie for sizers
2090 //---------------------------------------------------------------------------
2091 wxSize
wxMCIMediaBackend::GetVideoSize() const
2095 MCI_DGV_RECT_PARMS whereParms
; //ifdefed MCI_DGV_WHERE_PARMS
2097 wxMCIVERIFY( mciSendCommand(m_hDev
, MCI_WHERE
,
2098 0x00020000L
, //MCI_DGV_WHERE_SOURCE
2099 (DWORD
)(LPSTR
)&whereParms
) );
2101 return wxSize(whereParms
.rc
.right
, whereParms
.rc
.bottom
);
2106 //---------------------------------------------------------------------------
2107 // wxMCIMediaBackend::GetPlaybackRate
2110 //---------------------------------------------------------------------------
2111 double wxMCIMediaBackend::GetPlaybackRate()
2116 //---------------------------------------------------------------------------
2117 // wxMCIMediaBackend::SetPlaybackRate
2120 //---------------------------------------------------------------------------
2121 bool wxMCIMediaBackend::SetPlaybackRate(double WXUNUSED(dRate
))
2124 MCI_WAVE_SET_SAMPLESPERSEC
2125 MCI_DGV_SET_PARMS setParms;
2126 setParms.dwSpeed = (DWORD) (dRate * 1000.0);
2128 return (mciSendCommand(m_hDev, MCI_SET,
2129 0x00020000L, //MCI_DGV_SET_SPEED
2130 (DWORD)(LPSTR)&setParms) == 0);
2135 //---------------------------------------------------------------------------
2136 // [static] wxMCIMediaBackend::MSWWindowProc
2138 // Here we process a message when MCI reaches the stopping point
2140 //---------------------------------------------------------------------------
2141 LRESULT CALLBACK
wxMCIMediaBackend::NotifyWndProc(HWND hWnd
, UINT nMsg
,
2145 wxMCIMediaBackend
* backend
= (wxMCIMediaBackend
*)
2147 ::GetWindowLong(hWnd
, GWL_USERDATA
);
2149 ::GetWindowLongPtr(hWnd
, GWLP_USERDATA
);
2153 return backend
->OnNotifyWndProc(hWnd
, nMsg
, wParam
, lParam
);
2156 LRESULT CALLBACK
wxMCIMediaBackend::OnNotifyWndProc(HWND hWnd
, UINT nMsg
,
2160 if(nMsg
== MM_MCINOTIFY
)
2162 wxASSERT(lParam
== (LPARAM
) m_hDev
);
2163 if(wParam
== MCI_NOTIFY_SUCCESSFUL
&& lParam
== (LPARAM
)m_hDev
)
2165 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
2166 m_ctrl
->ProcessEvent(theEvent
);
2168 if(theEvent
.IsAllowed())
2170 wxMCIVERIFY( mciSendCommand(m_hDev
, MCI_SEEK
,
2171 MCI_SEEK_TO_START
, 0) );
2173 //send the event to our child
2174 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
,
2176 m_ctrl
->ProcessEvent(theEvent
);
2180 return DefWindowProc(hWnd
, nMsg
, wParam
, lParam
);
2182 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2186 // TODO: Use a less cludgy way to pause/get state/set state
2187 // TODO: Dynamically load from qtml.dll
2188 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2192 IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend
, wxMediaBackend
);
2194 //Time between timer calls
2195 #define MOVIE_DELAY 100
2197 #include "wx/timer.h"
2199 // --------------------------------------------------------------------------
2200 // wxQTTimer - Handle Asyncronous Playing
2201 // --------------------------------------------------------------------------
2202 class _wxQTTimer
: public wxTimer
2205 _wxQTTimer(Movie movie
, wxQTMediaBackend
* parent
, wxQuickTimeLibrary
* pLib
) :
2206 m_movie(movie
), m_bPaused(false), m_parent(parent
), m_pLib(pLib
)
2214 bool GetPaused() {return m_bPaused
;}
2215 void SetPaused(bool bPaused
) {m_bPaused
= bPaused
;}
2217 //-----------------------------------------------------------------------
2218 // _wxQTTimer::Notify
2220 // 1) Checks to see if the movie is done, and if not continues
2221 // streaming the movie
2222 // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
2224 //-----------------------------------------------------------------------
2229 if(!m_pLib
->IsMovieDone(m_movie
))
2230 m_pLib
->MoviesTask(m_movie
, MOVIE_DELAY
);
2233 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
,
2234 m_parent
->m_ctrl
->GetId());
2235 m_parent
->m_ctrl
->ProcessEvent(theEvent
);
2237 if(theEvent
.IsAllowed())
2241 wxASSERT(m_pLib
->GetMoviesError() == noErr
);
2243 //send the event to our child
2244 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
,
2245 m_parent
->m_ctrl
->GetId());
2246 m_parent
->m_ctrl
->ProcessEvent(theEvent
);
2253 Movie m_movie
; //Our movie instance
2254 bool m_bPaused
; //Whether we are paused or not
2255 wxQTMediaBackend
* m_parent
; //Backend pointer
2256 wxQuickTimeLibrary
* m_pLib
; //Interfaces
2259 //---------------------------------------------------------------------------
2260 // wxQTMediaBackend Destructor
2262 // Sets m_timer to NULL signifying we havn't loaded anything yet
2263 //---------------------------------------------------------------------------
2264 wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL
)
2268 //---------------------------------------------------------------------------
2269 // wxQTMediaBackend Destructor
2271 // 1) Cleans up the QuickTime movie instance
2272 // 2) Decrements the QuickTime reference counter - if this reaches
2273 // 0, QuickTime shuts down
2274 // 3) Decrements the QuickTime Windows Media Layer reference counter -
2275 // if this reaches 0, QuickTime shuts down the Windows Media Layer
2276 //---------------------------------------------------------------------------
2277 wxQTMediaBackend::~wxQTMediaBackend()
2284 //Note that ExitMovies() is not neccessary, but
2285 //the docs are fuzzy on whether or not TerminateQTML is
2287 m_lib
.TerminateQTML();
2291 //---------------------------------------------------------------------------
2292 // wxQTMediaBackend::CreateControl
2294 // 1) Intializes QuickTime
2295 // 2) Creates the control window
2296 //---------------------------------------------------------------------------
2297 bool wxQTMediaBackend::CreateControl(wxControl
* ctrl
, wxWindow
* parent
,
2302 const wxValidator
& validator
,
2303 const wxString
& name
)
2305 if(!m_lib
.Initialize())
2309 if ((nError
= m_lib
.InitializeQTML(0)) != noErr
) //-2093 no dll
2311 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError
));
2314 m_lib
.EnterMovies();
2318 // By default wxWindow(s) is created with a border -
2319 // so we need to get rid of those
2321 // Since we don't have a child window like most other
2322 // backends, we don't need wxCLIP_CHILDREN
2324 if ( !ctrl
->wxControl::Create(parent
, id
, pos
, size
,
2325 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
,
2333 //---------------------------------------------------------------------------
2334 // wxQTMediaBackend::Load (file version)
2336 // 1) Get an FSSpec from the Windows path name
2337 // 2) Open the movie
2338 // 3) Obtain the movie instance from the movie resource
2340 //---------------------------------------------------------------------------
2341 bool wxQTMediaBackend::Load(const wxString
& fileName
)
2350 if (m_lib
.NativePathNameToFSSpec ((char*) (const char*) fileName
.mb_str(),
2351 &sfFile
, 0) != noErr
)
2354 if (m_lib
.OpenMovieFile (&sfFile
, &movieResFile
, fsRdPerm
) != noErr
)
2357 short movieResID
= 0;
2360 err
= m_lib
.NewMovieFromFile (
2368 m_lib
.CloseMovieFile (movieResFile
);
2375 return m_lib
.GetMoviesError() == noErr
;
2378 //---------------------------------------------------------------------------
2379 // wxQTMediaBackend::Move
2382 //---------------------------------------------------------------------------
2383 bool wxQTMediaBackend::Load(const wxURI
& location
)
2388 wxString theURI
= location
.BuildURI();
2392 Handle theHandle
= m_lib
.NewHandleClear(theURI
.length() + 1);
2393 wxASSERT(theHandle
);
2395 m_lib
.BlockMove(theURI
.mb_str(), *theHandle
, theURI
.length() + 1);
2397 //create the movie from the handle that refers to the URI
2398 err
= m_lib
.NewMovieFromDataRef(&m_movie
, newMovieActive
,
2400 'url'); //URLDataHandlerSubType
2402 m_lib
.DisposeHandle(theHandle
);
2407 //preroll movie for streaming
2412 timeNow = GetMovieTime(m_movie, NULL);
2413 playRate = GetMoviePreferredRate(m_movie);
2414 PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL);
2415 PrerollMovie(m_movie, timeNow, playRate);
2416 m_lib.SetMovieRate(m_movie, playRate);
2421 return m_lib
.GetMoviesError() == noErr
;
2424 //---------------------------------------------------------------------------
2425 // wxQTMediaBackend::Move
2428 //---------------------------------------------------------------------------
2429 void wxQTMediaBackend::FinishLoad()
2431 m_timer
= new _wxQTTimer(m_movie
, (wxQTMediaBackend
*) this, &m_lib
);
2434 //get the real size of the movie
2436 m_lib
.GetMovieNaturalBoundsRect (m_movie
, &outRect
);
2437 wxASSERT(m_lib
.GetMoviesError() == noErr
);
2439 m_bestSize
.x
= outRect
.right
- outRect
.left
;
2440 m_bestSize
.y
= outRect
.bottom
- outRect
.top
;
2442 //reparent movie/*AudioMediaCharacteristic*/
2443 if(m_lib
.GetMovieIndTrackType(m_movie
, 1,
2444 'eyes', //VisualMediaCharacteristic,
2445 (1 << 1) //movieTrackCharacteristic
2446 | (1 << 2) //movieTrackEnabledOnly
2449 m_lib
.CreatePortAssociation(m_ctrl
->GetHWND(), NULL
, 0L);
2451 m_lib
.SetMovieGWorld(m_movie
,
2452 (CGrafPtr
) m_lib
.GetNativeWindowPort(m_ctrl
->GetHWND()),
2456 //we want millisecond precision
2457 m_lib
.SetMovieTimeScale(m_movie
, 1000);
2458 wxASSERT(m_lib
.GetMoviesError() == noErr
);
2461 //Here, if the parent of the control has a sizer - we
2462 //tell it to recalculate the size of this control since
2463 //the user opened a seperate media file
2465 m_ctrl
->InvalidateBestSize();
2466 m_ctrl
->GetParent()->Layout();
2467 m_ctrl
->GetParent()->Refresh();
2468 m_ctrl
->GetParent()->Update();
2471 //---------------------------------------------------------------------------
2472 // wxQTMediaBackend::Move
2475 //---------------------------------------------------------------------------
2476 bool wxQTMediaBackend::Play()
2478 m_lib
.StartMovie(m_movie
);
2479 m_timer
->SetPaused(false);
2480 m_timer
->Start(MOVIE_DELAY
, wxTIMER_CONTINUOUS
);
2481 return m_lib
.GetMoviesError() == noErr
;
2484 //---------------------------------------------------------------------------
2485 // wxQTMediaBackend::Move
2488 //---------------------------------------------------------------------------
2489 bool wxQTMediaBackend::Pause()
2491 m_lib
.StopMovie(m_movie
);
2492 m_timer
->SetPaused(true);
2494 return m_lib
.GetMoviesError() == noErr
;
2497 //---------------------------------------------------------------------------
2498 // wxQTMediaBackend::Move
2501 //---------------------------------------------------------------------------
2502 bool wxQTMediaBackend::Stop()
2504 m_timer
->SetPaused(false);
2507 m_lib
.StopMovie(m_movie
);
2508 if(m_lib
.GetMoviesError() != noErr
)
2511 m_lib
.GoToBeginningOfMovie(m_movie
);
2512 return m_lib
.GetMoviesError() == noErr
;
2515 //---------------------------------------------------------------------------
2516 // wxQTMediaBackend::Move
2519 //---------------------------------------------------------------------------
2520 double wxQTMediaBackend::GetPlaybackRate()
2522 return ( ((double)m_lib
.GetMovieRate(m_movie
)) / 0x10000);
2525 //---------------------------------------------------------------------------
2526 // wxQTMediaBackend::Move
2529 //---------------------------------------------------------------------------
2530 bool wxQTMediaBackend::SetPlaybackRate(double dRate
)
2532 m_lib
.SetMovieRate(m_movie
, (Fixed
) (dRate
* 0x10000));
2533 return m_lib
.GetMoviesError() == noErr
;
2536 //---------------------------------------------------------------------------
2537 // wxQTMediaBackend::Move
2540 //---------------------------------------------------------------------------
2541 bool wxQTMediaBackend::SetPosition(wxLongLong where
)
2543 TimeRecord theTimeRecord
;
2544 memset(&theTimeRecord
, 0, sizeof(TimeRecord
));
2545 theTimeRecord
.value
.lo
= where
.GetValue();
2546 theTimeRecord
.scale
= m_lib
.GetMovieTimeScale(m_movie
);
2547 theTimeRecord
.base
= m_lib
.GetMovieTimeBase(m_movie
);
2548 m_lib
.SetMovieTime(m_movie
, &theTimeRecord
);
2550 if (m_lib
.GetMoviesError() != noErr
)
2556 //---------------------------------------------------------------------------
2557 // wxQTMediaBackend::GetPosition
2559 // 1) Calls GetMovieTime to get the position we are in in the movie
2560 // in milliseconds (we called
2561 //---------------------------------------------------------------------------
2562 wxLongLong
wxQTMediaBackend::GetPosition()
2564 return m_lib
.GetMovieTime(m_movie
, NULL
);
2567 //---------------------------------------------------------------------------
2568 // wxQTMediaBackend::GetVolume
2570 // Gets the volume through GetMovieVolume - which returns a 16 bit short -
2572 // +--------+--------+
2574 // +--------+--------+
2576 // (1) first 8 bits are value before decimal
2577 // (2) second 8 bits are value after decimal
2579 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
2580 // 1 (full gain and sound)
2581 //---------------------------------------------------------------------------
2582 double wxQTMediaBackend::GetVolume()
2584 short sVolume
= m_lib
.GetMovieVolume(m_movie
);
2586 if(sVolume
& (128 << 8)) //negative - no sound
2589 return (sVolume
& (127 << 8)) ? 1.0 : ((double)(sVolume
& 255)) / 255.0;
2592 //---------------------------------------------------------------------------
2593 // wxQTMediaBackend::SetVolume
2595 // Sets the volume through SetMovieVolume - which takes a 16 bit short -
2597 // +--------+--------+
2599 // +--------+--------+
2601 // (1) first 8 bits are value before decimal
2602 // (2) second 8 bits are value after decimal
2604 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
2605 // 1 (full gain and sound)
2606 //---------------------------------------------------------------------------
2607 bool wxQTMediaBackend::SetVolume(double dVolume
)
2609 short sVolume
= (dVolume
>= .9999 ? 1 << 8 :
2610 (short) (dVolume
* 255));
2611 m_lib
.SetMovieVolume(m_movie
, sVolume
);
2615 //---------------------------------------------------------------------------
2616 // wxQTMediaBackend::Move
2619 //---------------------------------------------------------------------------
2620 wxLongLong
wxQTMediaBackend::GetDuration()
2622 return m_lib
.GetMovieDuration(m_movie
);
2625 //---------------------------------------------------------------------------
2626 // wxQTMediaBackend::Move
2629 //---------------------------------------------------------------------------
2630 wxMediaState
wxQTMediaBackend::GetState()
2632 if ( !m_timer
|| (m_timer
->IsRunning() == false &&
2633 m_timer
->GetPaused() == false) )
2634 return wxMEDIASTATE_STOPPED
;
2636 if( m_timer
->IsRunning() == true )
2637 return wxMEDIASTATE_PLAYING
;
2639 return wxMEDIASTATE_PAUSED
;
2642 //---------------------------------------------------------------------------
2643 // wxQTMediaBackend::Move
2646 //---------------------------------------------------------------------------
2647 void wxQTMediaBackend::Cleanup()
2652 m_lib
.StopMovie(m_movie
);
2653 m_lib
.DisposeMovie(m_movie
);
2656 //---------------------------------------------------------------------------
2657 // wxQTMediaBackend::Move
2660 //---------------------------------------------------------------------------
2661 wxSize
wxQTMediaBackend::GetVideoSize() const
2666 //---------------------------------------------------------------------------
2667 // wxQTMediaBackend::Move
2670 //---------------------------------------------------------------------------
2671 void wxQTMediaBackend::Move(int WXUNUSED(x
), int WXUNUSED(y
), int w
, int h
)
2675 Rect theRect
= {0, 0, h
, w
};
2677 m_lib
.SetMovieBox(m_movie
, &theRect
);
2678 wxASSERT(m_lib
.GetMoviesError() == noErr
);
2682 //---------------------------------------------------------------------------
2683 // End QT Compilation Guard
2684 //---------------------------------------------------------------------------
2685 #endif //wxUSE_QUICKTIME
2687 //in source file that contains stuff you don't directly use
2688 #include <wx/html/forcelnk.h>
2689 FORCE_LINK_ME(basewxmediabackends
);
2691 //---------------------------------------------------------------------------
2692 // End wxMediaCtrl Compilation Guard and this file
2693 //---------------------------------------------------------------------------
2694 #endif //wxUSE_MEDIACTRL