From bf354396f61a2e1bd5544b67ecde341b6ff9bf35 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 11 Sep 2005 11:04:00 +0000 Subject: [PATCH] wxMediaCtrl patch from Ryan: - factored out Active X code into separate files - also refactored common part of all backends in mediactrlcmn.cpp - adds async loading from URLs support to Mac version - support for ShowPlayerControls() in Mac wxMediaCtrl - more minor bug fixes in the MSW version and the sample (this is slightly modified patch 1264533 (without the list control part)) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35461 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 64 +- build/bakefiles/files.bkl | 2 + build/msw/makefile.bcc | 20 +- build/msw/makefile.gcc | 20 +- build/msw/makefile.vc | 20 +- build/msw/makefile.wat | 20 +- build/msw/wx_core.dsp | 4 + build/msw/wx_media.dsp | 12 + include/wx/mediactrl.h | 29 + include/wx/msw/ole/activex.h | 185 +++++ samples/mediaplayer/mediaplayer.cpp | 544 +++++++------- src/common/mediactrlcmn.cpp | 43 ++ src/mac/carbon/mediactrl.cpp | 811 ++++++++++++++++----- src/msw/mediactrl.cpp | 1035 +-------------------------- src/msw/ole/activex.cpp | 824 +++++++++++++++++++++ src/wxWindows.dsp | 8 + 16 files changed, 2141 insertions(+), 1500 deletions(-) create mode 100644 include/wx/msw/ole/activex.h create mode 100644 src/msw/ole/activex.cpp diff --git a/Makefile.in b/Makefile.in index aa47071f83..f246ad9055 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2261,9 +2261,9 @@ COND_WXUNIV_1_ADVANCED_HDR = \ @COND_TOOLKIT_GTK@MEDIA_PLATFORM_HDR = @COND_TOOLKIT_MAC@MEDIA_PLATFORM_HDR = @COND_TOOLKIT_MOTIF@MEDIA_PLATFORM_HDR = -@COND_TOOLKIT_MSW@MEDIA_PLATFORM_HDR = +@COND_TOOLKIT_MSW@MEDIA_PLATFORM_HDR = wx/msw/ole/activex.h @COND_TOOLKIT_PM@MEDIA_PLATFORM_HDR = -@COND_TOOLKIT_WINCE@MEDIA_PLATFORM_HDR = +@COND_TOOLKIT_WINCE@MEDIA_PLATFORM_HDR = wx/msw/ole/activex.h @COND_TOOLKIT_X11@MEDIA_PLATFORM_HDR = @COND_USE_GUI_1_WXUNIV_0@GUI_CORE_HEADERS = $(GUI_HDR) COND_USE_GUI_1_WXUNIV_1_GUI_CORE_HEADERS = \ @@ -4039,9 +4039,11 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS = \ @COND_TOOLKIT_GTK@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o @COND_TOOLKIT_MAC@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o @COND_TOOLKIT_MOTIF@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o -@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o +@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS = \ +@COND_TOOLKIT_MSW@ monodll_mediactrl.o monodll_activex.o @COND_TOOLKIT_PM@__MEDIA_PLATFORM_SRC_OBJECTS = -@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o +@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS = \ +@COND_TOOLKIT_WINCE@ monodll_mediactrl.o monodll_activex.o @COND_TOOLKIT_X11@__MEDIA_PLATFORM_SRC_OBJECTS = monodll_mediactrl.o @COND_PLATFORM_MACOSX_1@__HTML_SRC_PLATFORM_OBJECTS = monodll_chm.o @COND_PLATFORM_UNIX_1@__HTML_SRC_PLATFORM_OBJECTS = monodll_chm.o @@ -5504,9 +5506,11 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_1 = \ @COND_TOOLKIT_GTK@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o @COND_TOOLKIT_MAC@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o @COND_TOOLKIT_MOTIF@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o -@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o +@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_1 = \ +@COND_TOOLKIT_MSW@ monolib_mediactrl.o monolib_activex.o @COND_TOOLKIT_PM@__MEDIA_PLATFORM_SRC_OBJECTS_1 = -@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o +@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_1 = \ +@COND_TOOLKIT_WINCE@ monolib_mediactrl.o monolib_activex.o @COND_TOOLKIT_X11@__MEDIA_PLATFORM_SRC_OBJECTS_1 = monolib_mediactrl.o @COND_PLATFORM_MACOSX_1@__HTML_SRC_PLATFORM_OBJECTS_1 = monolib_chm.o @COND_PLATFORM_UNIX_1@__HTML_SRC_PLATFORM_OBJECTS_1 = monolib_chm.o @@ -8525,9 +8529,11 @@ COND_USE_SOSYMLINKS_1___mediadll___so_symlinks_inst_cmd = rm -f \ @COND_TOOLKIT_GTK@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o @COND_TOOLKIT_MAC@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o @COND_TOOLKIT_MOTIF@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o -@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o +@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_2 = \ +@COND_TOOLKIT_MSW@ mediadll_mediactrl.o mediadll_activex.o @COND_TOOLKIT_PM@__MEDIA_PLATFORM_SRC_OBJECTS_2 = -@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o +@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_2 = \ +@COND_TOOLKIT_WINCE@ mediadll_mediactrl.o mediadll_activex.o @COND_TOOLKIT_X11@__MEDIA_PLATFORM_SRC_OBJECTS_2 = mediadll_mediactrl.o COND_MONOLITHIC_0_SHARED_0_USE_GUI_1___medialib___depname = \ $(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_media-$(WX_RELEASE)$(HOST_SUFFIX)$(LIBEXT) @@ -8541,9 +8547,11 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1___medialib___depname = \ @COND_TOOLKIT_GTK@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o @COND_TOOLKIT_MAC@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o @COND_TOOLKIT_MOTIF@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o -@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o +@COND_TOOLKIT_MSW@__MEDIA_PLATFORM_SRC_OBJECTS_3 = \ +@COND_TOOLKIT_MSW@ medialib_mediactrl.o medialib_activex.o @COND_TOOLKIT_PM@__MEDIA_PLATFORM_SRC_OBJECTS_3 = -@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o +@COND_TOOLKIT_WINCE@__MEDIA_PLATFORM_SRC_OBJECTS_3 = \ +@COND_TOOLKIT_WINCE@ medialib_mediactrl.o medialib_activex.o @COND_TOOLKIT_X11@__MEDIA_PLATFORM_SRC_OBJECTS_3 = medialib_mediactrl.o COND_MONOLITHIC_0_SHARED_1_USE_ODBC_1___odbcdll___depname = \ $(LIBDIRNAME)/$(DLLPREFIX)$(WXDLLNAMEPREFIX)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_odbc$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG)$(dll___targetsuf3) @@ -9148,6 +9156,8 @@ all: $(__wxregex___depname) $(__wxzlib___depname) $(__wxpng___depname) $(__wxjpe install: all $(__install_wxregex___depname) $(__install_wxzlib___depname) $(__install_wxpng___depname) $(__install_wxjpeg___depname) $(__install_wxtiff___depname) $(__install_wxodbc___depname) $(__install_wxexpat___depname) $(__install_monodll___depname) $(__install_monolib___depname) $(__install_basedll___depname) $(__install_baselib___depname) $(__install_netdll___depname) $(__install_netlib___depname) $(__install_coredll___depname) $(__install_corelib___depname) $(__install_advdll___depname) $(__install_advlib___depname) $(__install_mediadll___depname) $(__install_medialib___depname) $(__install_odbcdll___depname) $(__install_odbclib___depname) $(__install_dbgriddll___depname) $(__install_dbgridlib___depname) $(__install_htmldll___depname) $(__install_htmllib___depname) $(__install_qadll___depname) $(__install_qalib___depname) $(__install_xmldll___depname) $(__install_xmllib___depname) $(__install_xrcdll___depname) $(__install_xrclib___depname) $(__install_gldll___depname) $(__install_gllib___depname) $(__install_sound_sdl___depname) $(__install_wxrc___depname) install-wxconfig locale_install locale_msw_install $(__cocoa_res_install___depname) $(INSTALL_DIR) $(DESTDIR)$(datadir)/aclocal (cd $(srcdir) ; $(INSTALL_DATA) wxwin.m4 $(DESTDIR)$(datadir)/aclocal) + $(INSTALL_DIR) $(DESTDIR)$(datadir)/bakefile/presets + (cd build/bakefiles/wxpresets/presets/ ; $(INSTALL_DATA) wx.bkl wx_unix.bkl wx_win32.bkl $(DESTDIR)$(datadir)/bakefile/presets) $(INSTALL_DIR) $(DESTDIR)$(libdir)/wx/include/$(TOOLCHAIN_FULLNAME)/wx (cd ./ ; $(INSTALL_DATA) lib/wx/include/$(TOOLCHAIN_FULLNAME)/wx/setup.h $(DESTDIR)$(libdir)/wx/include/$(TOOLCHAIN_FULLNAME)/wx) $(INSTALL_DIR) $(DESTDIR)$(includedir)/wx-$(WX_RELEASE)$(WX_FLAVOUR) @@ -13581,6 +13591,12 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_X11_USE_GUI_1@monodll_mediactrl.o: $(srcdir)/src/unix/mediactrl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/mediactrl.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monodll_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@monodll_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + @COND_PLATFORM_UNIX_1_USE_GUI_1@monodll_chm.o: $(srcdir)/src/html/chm.cpp $(MONODLL_ODEP) @COND_PLATFORM_UNIX_1_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/html/chm.cpp @@ -17040,6 +17056,12 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_X11_USE_GUI_1@monolib_mediactrl.o: $(srcdir)/src/unix/mediactrl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/mediactrl.cpp +@COND_TOOLKIT_MSW_USE_GUI_1@monolib_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1@monolib_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + @COND_PLATFORM_UNIX_1_USE_GUI_1@monolib_chm.o: $(srcdir)/src/html/chm.cpp $(MONOLIB_ODEP) @COND_PLATFORM_UNIX_1_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/html/chm.cpp @@ -23577,6 +23599,12 @@ mediadll_mediactrlcmn.o: $(srcdir)/src/common/mediactrlcmn.cpp $(MEDIADLL_ODEP) @COND_TOOLKIT_X11@mediadll_mediactrl.o: $(srcdir)/src/unix/mediactrl.cpp $(MEDIADLL_ODEP) @COND_TOOLKIT_X11@ $(CXXC) -c -o $@ $(MEDIADLL_CXXFLAGS) $(srcdir)/src/unix/mediactrl.cpp +@COND_TOOLKIT_MSW@mediadll_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MEDIADLL_ODEP) +@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(MEDIADLL_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + +@COND_TOOLKIT_WINCE@mediadll_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MEDIADLL_ODEP) +@COND_TOOLKIT_WINCE@ $(CXXC) -c -o $@ $(MEDIADLL_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + medialib_mediactrlcmn.o: $(srcdir)/src/common/mediactrlcmn.cpp $(MEDIALIB_ODEP) $(CXXC) -c -o $@ $(MEDIALIB_CXXFLAGS) $(srcdir)/src/common/mediactrlcmn.cpp @@ -23601,6 +23629,12 @@ medialib_mediactrlcmn.o: $(srcdir)/src/common/mediactrlcmn.cpp $(MEDIALIB_ODEP) @COND_TOOLKIT_X11@medialib_mediactrl.o: $(srcdir)/src/unix/mediactrl.cpp $(MEDIALIB_ODEP) @COND_TOOLKIT_X11@ $(CXXC) -c -o $@ $(MEDIALIB_CXXFLAGS) $(srcdir)/src/unix/mediactrl.cpp +@COND_TOOLKIT_MSW@medialib_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MEDIALIB_ODEP) +@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(MEDIALIB_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + +@COND_TOOLKIT_WINCE@medialib_activex.o: $(srcdir)/src/msw/ole/activex.cpp $(MEDIALIB_ODEP) +@COND_TOOLKIT_WINCE@ $(CXXC) -c -o $@ $(MEDIALIB_CXXFLAGS) $(srcdir)/src/msw/ole/activex.cpp + odbcdll_version_rc.o: $(srcdir)/src/msw/version.rc $(ODBCDLL_ODEP) $(RESCOMP) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_49) $(__EXCEPTIONS_DEFINE_p_49) $(__RTTI_DEFINE_p_49) $(__THREAD_DEFINE_p_49) --define WXDLLNAME=$(WXDLLNAMEPREFIX)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_odbc$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) --include-dir $(top_srcdir)/include @@ -24242,6 +24276,16 @@ ALL_DIST: distrib_clean mkdir $(DISTDIR)/include mkdir $(DISTDIR)/include/wx cp $(INCDIR)/wx/fmappriv.h $(DISTDIR)/include/wx + # copy wxpresets + mkdir $(DISTDIR)/build + mkdir $(DISTDIR)/build/bakefiles + mkdir $(DISTDIR)/build/bakefiles/wxpresets + mkdir $(DISTDIR)/build/bakefiles/wxpresets/presets + mkdir $(DISTDIR)/build/bakefiles/wxpresets/sample + cp $(WXDIR)/build/bakefiles/wxpresets/presets/*.bkl $(DISTDIR)/build/bakefiles/wxpresets/presets + cp $(WXDIR)/build/bakefiles/wxpresets/sample/minimal* $(DISTDIR)/build/bakefiles/wxpresets/sample + cp $(WXDIR)/build/bakefiles/wxpresets/sample/config* $(DISTDIR)/build/bakefiles/wxpresets/sample + cp $(WXDIR)/build/bakefiles/wxpresets/*.txt $(DISTDIR)/build/bakefiles/wxpresets # this target is the common part of distribution script for all GUI toolkits, # but is not used when building wxBase distribution diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index f7654fa35e..93d580b4e8 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2466,8 +2466,10 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/mediactrl.cpp + src/msw/ole/activex.cpp + wx/msw/ole/activex.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index f9e22d7fdf..576f4c8d0c 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -697,7 +697,8 @@ MEDIADLL_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ MEDIADLL_OBJECTS = \ $(OBJS)\mediadll_dummy.obj \ $(OBJS)\mediadll_mediactrlcmn.obj \ - $(OBJS)\mediadll_mediactrl.obj + $(OBJS)\mediadll_mediactrl.obj \ + $(OBJS)\mediadll_activex.obj MEDIALIB_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ $(__OPTIMIZEFLAG) $(__THREADSFLAG) -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ @@ -708,7 +709,8 @@ MEDIALIB_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ MEDIALIB_OBJECTS = \ $(OBJS)\medialib_dummy.obj \ $(OBJS)\medialib_mediactrlcmn.obj \ - $(OBJS)\medialib_mediactrl.obj + $(OBJS)\medialib_mediactrl.obj \ + $(OBJS)\medialib_activex.obj ODBCDLL_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ $(__OPTIMIZEFLAG) $(__THREADSFLAG) -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ @@ -1050,6 +1052,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_OBJECTS) \ $(OBJS)\monodll_mediactrlcmn.obj \ $(OBJS)\monodll_mediactrl.obj \ + $(OBJS)\monodll_activex.obj \ $(OBJS)\monodll_helpbest.obj \ $(OBJS)\monodll_helpctrl.obj \ $(OBJS)\monodll_helpdata.obj \ @@ -1561,6 +1564,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_1_OBJECTS) \ $(OBJS)\monolib_mediactrlcmn.obj \ $(OBJS)\monolib_mediactrl.obj \ + $(OBJS)\monolib_activex.obj \ $(OBJS)\monolib_helpbest.obj \ $(OBJS)\monolib_helpctrl.obj \ $(OBJS)\monolib_helpdata.obj \ @@ -4339,6 +4343,9 @@ $(OBJS)\monodll_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\monodll_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** +$(OBJS)\monodll_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** + $(OBJS)\monodll_helpbest.obj: ..\..\src\msw\helpbest.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** @@ -6024,6 +6031,9 @@ $(OBJS)\monolib_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\monolib_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** +$(OBJS)\monolib_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** + $(OBJS)\monolib_helpbest.obj: ..\..\src\msw\helpbest.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** @@ -10241,6 +10251,9 @@ $(OBJS)\mediadll_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\mediadll_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) -q -c -P -o$@ $(MEDIADLL_CXXFLAGS) $** +$(OBJS)\mediadll_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) -q -c -P -o$@ $(MEDIADLL_CXXFLAGS) $** + $(OBJS)\medialib_dummy.obj: ..\..\src\msw\dummy.cpp $(CXX) -q -c -P -o$@ $(MEDIALIB_CXXFLAGS) -H $** @@ -10250,6 +10263,9 @@ $(OBJS)\medialib_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\medialib_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) -q -c -P -o$@ $(MEDIALIB_CXXFLAGS) $** +$(OBJS)\medialib_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) -q -c -P -o$@ $(MEDIALIB_CXXFLAGS) $** + $(OBJS)\odbcdll_dummy.obj: ..\..\src\msw\dummy.cpp $(CXX) -q -c -P -o$@ $(ODBCDLL_CXXFLAGS) -H $** diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 1c6cd2c40f..024e2ed444 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -689,7 +689,8 @@ MEDIADLL_OBJECTS = \ $(OBJS)\mediadll_dummy.o \ $(OBJS)\mediadll_version_rc.o \ $(OBJS)\mediadll_mediactrlcmn.o \ - $(OBJS)\mediadll_mediactrl.o + $(OBJS)\mediadll_mediactrl.o \ + $(OBJS)\mediadll_activex.o MEDIALIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ $(GCCFLAGS) -DHAVE_W32API_H -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ @@ -701,7 +702,8 @@ MEDIALIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ MEDIALIB_OBJECTS = \ $(OBJS)\medialib_dummy.o \ $(OBJS)\medialib_mediactrlcmn.o \ - $(OBJS)\medialib_mediactrl.o + $(OBJS)\medialib_mediactrl.o \ + $(OBJS)\medialib_activex.o ODBCDLL_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ $(GCCFLAGS) -DHAVE_W32API_H -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ @@ -1060,6 +1062,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_OBJECTS) \ $(OBJS)\monodll_mediactrlcmn.o \ $(OBJS)\monodll_mediactrl.o \ + $(OBJS)\monodll_activex.o \ $(OBJS)\monodll_helpbest.o \ $(OBJS)\monodll_helpctrl.o \ $(OBJS)\monodll_helpdata.o \ @@ -1577,6 +1580,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_1_OBJECTS) \ $(OBJS)\monolib_mediactrlcmn.o \ $(OBJS)\monolib_mediactrl.o \ + $(OBJS)\monolib_activex.o \ $(OBJS)\monolib_helpbest.o \ $(OBJS)\monolib_helpctrl.o \ $(OBJS)\monolib_helpdata.o \ @@ -4435,6 +4439,9 @@ $(OBJS)\monodll_mediactrlcmn.o: ../../src/common/mediactrlcmn.cpp $(OBJS)\monodll_mediactrl.o: ../../src/msw/mediactrl.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_activex.o: ../../src/msw/ole/activex.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_helpbest.o: ../../src/msw/helpbest.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -6220,6 +6227,9 @@ $(OBJS)\monolib_mediactrlcmn.o: ../../src/common/mediactrlcmn.cpp $(OBJS)\monolib_mediactrl.o: ../../src/msw/mediactrl.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_activex.o: ../../src/msw/ole/activex.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_helpbest.o: ../../src/msw/helpbest.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -10737,6 +10747,9 @@ $(OBJS)\mediadll_mediactrlcmn.o: ../../src/common/mediactrlcmn.cpp $(OBJS)\mediadll_mediactrl.o: ../../src/msw/mediactrl.cpp $(CXX) -c -o $@ $(MEDIADLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\mediadll_activex.o: ../../src/msw/ole/activex.cpp + $(CXX) -c -o $@ $(MEDIADLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\medialib_dummy.o: ../../src/msw/dummy.cpp $(CXX) -c -o $@ $(MEDIALIB_CXXFLAGS) $(CPPDEPS) $< @@ -10746,6 +10759,9 @@ $(OBJS)\medialib_mediactrlcmn.o: ../../src/common/mediactrlcmn.cpp $(OBJS)\medialib_mediactrl.o: ../../src/msw/mediactrl.cpp $(CXX) -c -o $@ $(MEDIALIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\medialib_activex.o: ../../src/msw/ole/activex.cpp + $(CXX) -c -o $@ $(MEDIALIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\odbcdll_dummy.o: ../../src/msw/dummy.cpp $(CXX) -c -o $@ $(ODBCDLL_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 00c62b7a72..e8e8cd91fc 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -738,7 +738,8 @@ MEDIADLL_OBJECTS = \ $(OBJS)\mediadll_dummy.obj \ $(OBJS)\mediadll_version.res \ $(OBJS)\mediadll_mediactrlcmn.obj \ - $(OBJS)\mediadll_mediactrl.obj + $(OBJS)\mediadll_mediactrl.obj \ + $(OBJS)\mediadll_activex.obj MEDIALIB_CXXFLAGS = /M$(__RUNTIME_LIBS_235)$(__DEBUGRUNTIME) /DWIN32 \ $(__DEBUGINFO) \ /Fd$(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_media.pdb \ @@ -752,7 +753,8 @@ MEDIALIB_CXXFLAGS = /M$(__RUNTIME_LIBS_235)$(__DEBUGRUNTIME) /DWIN32 \ MEDIALIB_OBJECTS = \ $(OBJS)\medialib_dummy.obj \ $(OBJS)\medialib_mediactrlcmn.obj \ - $(OBJS)\medialib_mediactrl.obj + $(OBJS)\medialib_mediactrl.obj \ + $(OBJS)\medialib_activex.obj ODBCDLL_CXXFLAGS = /M$(__RUNTIME_LIBS_249)$(__DEBUGRUNTIME) /DWIN32 \ $(__DEBUGINFO) \ /Fd$(LIBDIRNAME)\wxbase$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_odbc_vc$(VENDORTAG).pdb \ @@ -1185,6 +1187,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_OBJECTS) \ $(OBJS)\monodll_mediactrlcmn.obj \ $(OBJS)\monodll_mediactrl.obj \ + $(OBJS)\monodll_activex.obj \ $(OBJS)\monodll_helpbest.obj \ $(OBJS)\monodll_helpctrl.obj \ $(OBJS)\monodll_helpdata.obj \ @@ -1702,6 +1705,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = \ $(____ADVANCED_SRC_FILENAMES_1_OBJECTS) \ $(OBJS)\monolib_mediactrlcmn.obj \ $(OBJS)\monolib_mediactrl.obj \ + $(OBJS)\monolib_activex.obj \ $(OBJS)\monolib_helpbest.obj \ $(OBJS)\monolib_helpctrl.obj \ $(OBJS)\monolib_helpdata.obj \ @@ -4624,6 +4628,9 @@ $(OBJS)\monodll_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\monodll_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** +$(OBJS)\monodll_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** + $(OBJS)\monodll_helpbest.obj: ..\..\src\msw\helpbest.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** @@ -6309,6 +6316,9 @@ $(OBJS)\monolib_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\monolib_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** +$(OBJS)\monolib_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** + $(OBJS)\monolib_helpbest.obj: ..\..\src\msw\helpbest.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** @@ -10526,6 +10536,9 @@ $(OBJS)\mediadll_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\mediadll_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MEDIADLL_CXXFLAGS) $** +$(OBJS)\mediadll_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MEDIADLL_CXXFLAGS) $** + $(OBJS)\medialib_dummy.obj: ..\..\src\msw\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(MEDIALIB_CXXFLAGS) /Ycwx/wxprec.h $** @@ -10535,6 +10548,9 @@ $(OBJS)\medialib_mediactrlcmn.obj: ..\..\src\common\mediactrlcmn.cpp $(OBJS)\medialib_mediactrl.obj: ..\..\src\msw\mediactrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MEDIALIB_CXXFLAGS) $** +$(OBJS)\medialib_activex.obj: ..\..\src\msw\ole\activex.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MEDIALIB_CXXFLAGS) $** + $(OBJS)\odbcdll_dummy.obj: ..\..\src\msw\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(ODBCDLL_CXXFLAGS) /Ycwx/wxprec.h $** diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 92b2165273..8287b20eed 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -102,6 +102,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_OBJECTS = & $(____ADVANCED_SRC_FILENAMES_OBJECTS) & $(OBJS)\monodll_mediactrlcmn.obj & $(OBJS)\monodll_mediactrl.obj & + $(OBJS)\monodll_activex.obj & $(OBJS)\monodll_helpbest.obj & $(OBJS)\monodll_helpctrl.obj & $(OBJS)\monodll_helpdata.obj & @@ -623,6 +624,7 @@ ____MONOLIB_GUI_SRC_FILENAMES_1_OBJECTS = & $(____ADVANCED_SRC_FILENAMES_1_OBJECTS) & $(OBJS)\monolib_mediactrlcmn.obj & $(OBJS)\monolib_mediactrl.obj & + $(OBJS)\monolib_activex.obj & $(OBJS)\monolib_helpbest.obj & $(OBJS)\monolib_helpctrl.obj & $(OBJS)\monolib_helpdata.obj & @@ -3026,7 +3028,8 @@ MEDIADLL_CXXFLAGS = -bd $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & MEDIADLL_OBJECTS = & $(OBJS)\mediadll_dummy.obj & $(OBJS)\mediadll_mediactrlcmn.obj & - $(OBJS)\mediadll_mediactrl.obj + $(OBJS)\mediadll_mediactrl.obj & + $(OBJS)\mediadll_activex.obj MEDIALIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(__RUNTIME_LIBS) -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) & $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) & @@ -3038,7 +3041,8 @@ MEDIALIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & MEDIALIB_OBJECTS = & $(OBJS)\medialib_dummy.obj & $(OBJS)\medialib_mediactrlcmn.obj & - $(OBJS)\medialib_mediactrl.obj + $(OBJS)\medialib_mediactrl.obj & + $(OBJS)\medialib_activex.obj ODBCDLL_CXXFLAGS = -bd $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(__RUNTIME_LIBS) -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) & $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) & @@ -4634,6 +4638,9 @@ $(OBJS)\monodll_mediactrlcmn.obj : .AUTODEPEND ..\..\src\common\mediactrlcmn.cp $(OBJS)\monodll_mediactrl.obj : .AUTODEPEND ..\..\src\msw\mediactrl.cpp $(CXX) -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +$(OBJS)\monodll_activex.obj : .AUTODEPEND ..\..\src\msw\ole\activex.cpp + $(CXX) -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< + $(OBJS)\monodll_helpbest.obj : .AUTODEPEND ..\..\src\msw\helpbest.cpp $(CXX) -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -6419,6 +6426,9 @@ $(OBJS)\monolib_mediactrlcmn.obj : .AUTODEPEND ..\..\src\common\mediactrlcmn.cp $(OBJS)\monolib_mediactrl.obj : .AUTODEPEND ..\..\src\msw\mediactrl.cpp $(CXX) -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +$(OBJS)\monolib_activex.obj : .AUTODEPEND ..\..\src\msw\ole\activex.cpp + $(CXX) -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< + $(OBJS)\monolib_helpbest.obj : .AUTODEPEND ..\..\src\msw\helpbest.cpp $(CXX) -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -10936,6 +10946,9 @@ $(OBJS)\mediadll_mediactrlcmn.obj : .AUTODEPEND ..\..\src\common\mediactrlcmn.c $(OBJS)\mediadll_mediactrl.obj : .AUTODEPEND ..\..\src\msw\mediactrl.cpp $(CXX) -zq -fo=$^@ $(MEDIADLL_CXXFLAGS) $< +$(OBJS)\mediadll_activex.obj : .AUTODEPEND ..\..\src\msw\ole\activex.cpp + $(CXX) -zq -fo=$^@ $(MEDIADLL_CXXFLAGS) $< + $(OBJS)\medialib_dummy.obj : .AUTODEPEND ..\..\src\msw\dummy.cpp $(CXX) -zq -fo=$^@ $(MEDIALIB_CXXFLAGS) $< @@ -10945,6 +10958,9 @@ $(OBJS)\medialib_mediactrlcmn.obj : .AUTODEPEND ..\..\src\common\mediactrlcmn.c $(OBJS)\medialib_mediactrl.obj : .AUTODEPEND ..\..\src\msw\mediactrl.cpp $(CXX) -zq -fo=$^@ $(MEDIALIB_CXXFLAGS) $< +$(OBJS)\medialib_activex.obj : .AUTODEPEND ..\..\src\msw\ole\activex.cpp + $(CXX) -zq -fo=$^@ $(MEDIALIB_CXXFLAGS) $< + $(OBJS)\odbcdll_dummy.obj : .AUTODEPEND ..\..\src\msw\dummy.cpp $(CXX) -zq -fo=$^@ $(ODBCDLL_CXXFLAGS) $< diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index db83d1c1ca..edd418b711 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -7412,6 +7412,10 @@ SOURCE=..\..\include\wx\msw\ole\access.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\msw\ole\activex.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\msw\app.h # End Source File # Begin Source File diff --git a/build/msw/wx_media.dsp b/build/msw/wx_media.dsp index b1d81489c7..ea18834507 100644 --- a/build/msw/wx_media.dsp +++ b/build/msw/wx_media.dsp @@ -460,6 +460,10 @@ SOURCE=..\..\src\common\mediactrlcmn.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\src\msw\ole\activex.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\msw\dummy.cpp # ADD BASE CPP /Yc"wx/wxprec.h" # ADD CPP /Yc"wx/wxprec.h" @@ -804,6 +808,14 @@ InputPath=..\include\wx\msw\setup.h !ENDIF +# End Source File +# End Group +# Begin Group "MSW Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\wx\msw\ole\activex.h # End Source File # End Group # Begin Group "Common Headers" diff --git a/include/wx/mediactrl.h b/include/wx/mediactrl.h index fbd3fe2c5c..89ab6d9f15 100644 --- a/include/wx/mediactrl.h +++ b/include/wx/mediactrl.h @@ -326,6 +326,7 @@ public: DECLARE_DYNAMIC_CLASS(wxMediaBackend) }; + //Event ID to give to our events #define wxMEDIA_FINISHED_ID 13000 #define wxMEDIA_STOP_ID 13001 @@ -350,6 +351,34 @@ typedef void (wxEvtHandler::*wxMediaEventFunction)(wxMediaEvent&); # define EVT_MEDIA_LOADED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_LOADED, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ), #endif +// ---------------------------------------------------------------------------- +// common backend base class used by many other backends +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_MEDIA wxMediaBackendCommonBase : public wxMediaBackend +{ +public: + // add a pending wxMediaEvent of the given type + void QueueEvent(wxEventType evtType); + + // notify that the movie playback is finished + void QueueFinishEvent() { QueueEvent(wxEVT_MEDIA_FINISHED); } + + // send the stop event and return true if it hasn't been vetoed + bool SendStopEvent(); + +protected: + // call this when the movie size has changed but not because it has just + // been loaded (in this case, call NotifyMovieLoaded() below) + void NotifyMovieSizeChanged(); + + // call this when the movie is fully loaded + void NotifyMovieLoaded(); + + + wxMediaCtrl *m_ctrl; // parent control +}; + // ---------------------------------------------------------------------------- // End compilation gaurd // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/ole/activex.h b/include/wx/msw/ole/activex.h new file mode 100644 index 0000000000..0c9477e8fe --- /dev/null +++ b/include/wx/msw/ole/activex.h @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/activex.h +// Purpose: wxActiveXContainer class +// Author: Ryan Norton +// Modified by: +// Created: 8/18/05 +// RCS-ID: $Id$ +// Copyright: (c) Ryan Norton +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// Definitions +// ============================================================================ + +#ifndef _WX_MSW_OLE_ACTIVEXCONTAINER_H_ +#define _WX_MSW_OLE_ACTIVEXCONTAINER_H_ + +//--------------------------------------------------------------------------- +// COM includes +//--------------------------------------------------------------------------- +#include "wx/msw/ole/oleutils.h" //wxBasicString, IID etc. +#include "wx/msw/ole/uuid.h" //IID etc.. + +//--------------------------------------------------------------------------- +// COM compatability definitions +//--------------------------------------------------------------------------- +#ifndef STDMETHODCALLTYPE +#define STDMETHODCALLTYPE __stdcall +#endif +#ifndef STDMETHOD +#define STDMETHOD(funcname) virtual HRESULT STDMETHODCALLTYPE funcname +#endif +#ifndef PURE +#define PURE = 0 +#endif +#ifndef __RPC_FAR +#define __RPC_FAR FAR +#endif + +//--------------------------------------------------------------------------- +// WX includes +//--------------------------------------------------------------------------- +#include "wx/window.h" + +//--------------------------------------------------------------------------- +// MSW COM includes +//--------------------------------------------------------------------------- +#include +#include +#include +#include + +// +// These defines are from another ole header - but its not in the +// latest sdk. Also the ifndef DISPID_READYSTATE is here because at +// least on my machine with the latest sdk olectl.h defines these 3 +// +#ifndef DISPID_READYSTATE + #define DISPID_READYSTATE -525 + #define DISPID_READYSTATECHANGE -609 + #define DISPID_AMBIENT_TRANSFERPRIORITY -728 +#endif + +#define DISPID_AMBIENT_OFFLINEIFNOTCONNECTED -5501 +#define DISPID_AMBIENT_SILENT -5502 + +#ifndef DISPID_AMBIENT_CODEPAGE +# define DISPID_AMBIENT_CODEPAGE -725 +# define DISPID_AMBIENT_CHARSET -727 +#endif + + +//--------------------------------------------------------------------------- +// +// wxActiveXContainer +// +//--------------------------------------------------------------------------- + +#define WX_DECLARE_AUTOOLE(wxAutoOleInterface, I) \ +class wxAutoOleInterface \ +{ \ + protected: \ + I *m_interface; \ +\ + public: \ + explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {} \ + wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL) \ + { QueryInterface(riid, pUnk); } \ + wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL) \ + { QueryInterface(riid, pDispatch); } \ + wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)\ + { CreateInstance(clsid, riid); }\ + wxAutoOleInterface(const wxAutoOleInterface& ti) : m_interface(NULL)\ + { operator = (ti); }\ +\ + wxAutoOleInterface& operator = (const wxAutoOleInterface& ti)\ + {\ + if (ti.m_interface)\ + ti.m_interface->AddRef();\ + Free();\ + m_interface = ti.m_interface;\ + return *this;\ + }\ +\ + wxAutoOleInterface& operator = (I *&ti)\ + {\ + Free();\ + m_interface = ti;\ + return *this;\ + }\ +\ + ~wxAutoOleInterface() { Free(); }\ +\ + inline void Free()\ + {\ + if (m_interface)\ + m_interface->Release();\ + m_interface = NULL;\ + }\ +\ + HRESULT QueryInterface(REFIID riid, IUnknown *pUnk)\ + {\ + Free();\ + wxASSERT(pUnk != NULL);\ + return pUnk->QueryInterface(riid, (void **) &m_interface);\ + }\ +\ + HRESULT CreateInstance(REFCLSID clsid, REFIID riid)\ + {\ + Free();\ + return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface);\ + }\ +\ + inline operator I *() const {return m_interface;}\ + inline I* operator ->() {return m_interface;}\ + inline I** GetRef() {return &m_interface;}\ + inline bool Ok() const {return m_interface != NULL;}\ +}; + +WX_DECLARE_AUTOOLE(wxAutoIDispatch, IDispatch) +WX_DECLARE_AUTOOLE(wxAutoIOleClientSite, IOleClientSite) +WX_DECLARE_AUTOOLE(wxAutoIUnknown, IUnknown) +WX_DECLARE_AUTOOLE(wxAutoIOleObject, IOleObject) +WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceObject, IOleInPlaceObject) +WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceActiveObject, IOleInPlaceActiveObject) +WX_DECLARE_AUTOOLE(wxAutoIOleDocumentView, IOleDocumentView) +WX_DECLARE_AUTOOLE(wxAutoIViewObject, IViewObject) +WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite) +WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument) +WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit) +WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink) + +class wxActiveXContainer : public wxWindow +{ +public: + wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk); + virtual ~wxActiveXContainer(); + + void OnSize(wxSizeEvent&); + void OnPaint(wxPaintEvent&); + void OnSetFocus(wxFocusEvent&); + void OnKillFocus(wxFocusEvent&); + +protected: + friend class FrameSite; + + wxAutoIDispatch m_Dispatch; + wxAutoIOleClientSite m_clientSite; + wxAutoIUnknown m_ActiveX; + wxAutoIOleObject m_oleObject; + wxAutoIOleInPlaceObject m_oleInPlaceObject; + wxAutoIOleInPlaceActiveObject m_oleInPlaceActiveObject; + wxAutoIOleDocumentView m_docView; + wxAutoIViewObject m_viewObject; + HWND m_oleObjectHWND; + bool m_bAmbientUserMode; + DWORD m_docAdviseCookie; + wxWindow* m_realparent; + + void CreateActiveX(REFIID, IUnknown*); +}; + +#endif // _WX_MSW_OLE_ACTIVEXCONTAINER_H_ + diff --git a/samples/mediaplayer/mediaplayer.cpp b/samples/mediaplayer/mediaplayer.cpp index 998dcce962..19e337583b 100644 --- a/samples/mediaplayer/mediaplayer.cpp +++ b/samples/mediaplayer/mediaplayer.cpp @@ -207,13 +207,6 @@ private: void DoOpenFile(const wxString& path, bool bNewPage); void DoPlayFile(const wxString& path); - // Get the controls of current notebook page - wxMediaCtrl* GetCurrentMediaCtrl(); - wxSlider* GetCurrentSlider(); - wxGauge* GetCurrentGauge(); - - int m_nLastFileId; //List ID of played file in listctrl - wxString m_szFile; //Name of currently playing file/location class wxMediaPlayerTimer* m_timer; //Timer to write info to status bar wxString m_basestatus; //Base status string (see ResetStatus()) wxNotebook* m_notebook; //Notebook containing our pages @@ -249,6 +242,9 @@ public: //make wxMediaPlayerFrame able to access the private members friend class wxMediaPlayerFrame; + int m_nLastFileId; //List ID of played file in listctrl + wxString m_szFile; //Name of currently playing file/location + wxMediaCtrl* m_mediactrl; //Our media control class wxMediaPlayerListCtrl* m_playlist; //Our playlist wxSlider* m_slider; //The slider below our media control @@ -292,14 +288,13 @@ public: wxListItem kNewItem; kNewItem.SetAlign(wxLIST_FORMAT_LEFT); - int nID; - - kNewItem.SetId(nID = this->GetItemCount()); + int nID = this->GetItemCount(); + kNewItem.SetId(nID); kNewItem.SetMask(wxLIST_MASK_DATA); kNewItem.SetData(new wxString(szString)); this->InsertItem(kNewItem); - this->SetItem(nID, 0, _T("*")); + this->SetItem(nID, 0, wxT("*")); this->SetItem(nID, 1, wxFileName(szString).GetName()); if (nID % 2) @@ -328,7 +323,6 @@ public: listitem.SetId(nLastSelected == -1 ? nLast : nLastSelected); this->GetItem(listitem); } - }; // ---------------------------------------------------------------------------- @@ -416,7 +410,7 @@ IMPLEMENT_APP(wxMediaPlayerApp) bool wxMediaPlayerApp::OnInit() { wxMediaPlayerFrame *frame = - new wxMediaPlayerFrame(_T("MediaPlayer wxWidgets Sample")); + new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample")); frame->Show(true); #if wxUSE_CMDLINE_PARSER @@ -479,8 +473,7 @@ void wxMediaPlayerApp::MacOpenFile(const wxString & fileName ) // ---------------------------------------------------------------------------- wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) - : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600)), - m_nLastFileId(-1) + : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600)) { // // Create Menus @@ -491,50 +484,50 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) wxMenu *helpMenu = new wxMenu; wxMenu *debugMenu = new wxMenu; - fileMenu->Append(wxID_OPENFILESAMEPAGE, _T("&Open File\tCtrl-Shift-O"), - _T("Open a File in the current notebook page")); - fileMenu->Append(wxID_OPENFILENEWPAGE, _T("&Open File in a new page"), - _T("Open a File in a new notebook page")); - fileMenu->Append(wxID_OPENURLSAMEPAGE, _T("&Open URL"), - _T("Open a URL in the current notebook page")); - fileMenu->Append(wxID_OPENURLNEWPAGE, _T("&Open URL in a new page"), - _T("Open a URL in a new notebook page")); + fileMenu->Append(wxID_OPENFILESAMEPAGE, wxT("&Open File\tCtrl-Shift-O"), + wxT("Open a File in the current notebook page")); + fileMenu->Append(wxID_OPENFILENEWPAGE, wxT("&Open File in a new page"), + wxT("Open a File in a new notebook page")); + fileMenu->Append(wxID_OPENURLSAMEPAGE, wxT("&Open URL"), + wxT("Open a URL in the current notebook page")); + fileMenu->Append(wxID_OPENURLNEWPAGE, wxT("&Open URL in a new page"), + wxT("Open a URL in a new notebook page")); fileMenu->AppendSeparator(); - fileMenu->Append(wxID_CLOSECURRENTPAGE, _T("&Close Current Page\tCtrl-C"), - _T("Close current notebook page")); + fileMenu->Append(wxID_CLOSECURRENTPAGE, wxT("&Close Current Page\tCtrl-C"), + wxT("Close current notebook page")); fileMenu->AppendSeparator(); fileMenu->Append(wxID_EXIT, - _T("E&xit\tAlt-X"), - _T("Quit this program")); + wxT("E&xit\tAlt-X"), + wxT("Quit this program")); - controlsMenu->Append(wxID_PLAY, _T("&Play/Pause\tCtrl-P"), _T("Resume/Pause playback")); - controlsMenu->Append(wxID_STOP, _T("&Stop\tCtrl-S"), _T("Stop playback")); + controlsMenu->Append(wxID_PLAY, wxT("&Play/Pause\tCtrl-P"), wxT("Resume/Pause playback")); + controlsMenu->Append(wxID_STOP, wxT("&Stop\tCtrl-S"), wxT("Stop playback")); controlsMenu->AppendSeparator(); - controlsMenu->Append(wxID_PREV, _T("&Previous\tCtrl-B"), _T("Go to previous track")); - controlsMenu->Append(wxID_NEXT, _T("&Next\tCtrl-N"), _T("Skip to next track")); + controlsMenu->Append(wxID_PREV, wxT("&Previous\tCtrl-B"), wxT("Go to previous track")); + controlsMenu->Append(wxID_NEXT, wxT("&Next\tCtrl-N"), wxT("Skip to next track")); optionsMenu->AppendCheckItem(wxID_LOOP, - _T("&Loop\tCtrl-L"), - _T("Loop Selected Media")); + wxT("&Loop\tCtrl-L"), + wxT("Loop Selected Media")); optionsMenu->AppendCheckItem(wxID_SHOWINTERFACE, - _T("&Show Interface\tCtrl-I"), - _T("Show wxMediaCtrl native controls")); + wxT("&Show Interface\tCtrl-I"), + wxT("Show wxMediaCtrl native controls")); debugMenu->Append(wxID_SELECTBACKEND, - _T("&Select Backend...\tCtrl-D"), - _T("Select a backend manually")); + wxT("&Select Backend...\tCtrl-D"), + wxT("Select a backend manually")); helpMenu->Append(wxID_ABOUT, - _T("&About...\tF1"), - _T("Show about dialog")); + wxT("&About...\tF1"), + wxT("Show about dialog")); wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(fileMenu, _T("&File")); - menuBar->Append(controlsMenu, _T("&Controls")); - menuBar->Append(optionsMenu, _T("&Options")); - menuBar->Append(debugMenu, _T("&Debug")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(fileMenu, wxT("&File")); + menuBar->Append(controlsMenu, wxT("&Controls")); + menuBar->Append(optionsMenu, wxT("&Options")); + menuBar->Append(debugMenu, wxT("&Debug")); + menuBar->Append(helpMenu, wxT("&Help")); SetMenuBar(menuBar); // @@ -692,10 +685,32 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // Create an initial notebook page so the user has something // to work with without having to go file->open every time :). // - m_notebook->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook), + wxMediaPlayerNotebookPage* page = + new wxMediaPlayerNotebookPage(this, m_notebook); + m_notebook->AddPage(page, wxT(""), true); + // + // Here we load the our configuration - + // in our case we load all the files that were left in + // the playlist the last time the user closed our application + // + // As an exercise to the reader try modifying it so that + // it properly loads the playlist for each page without + // conflicting (loading the same data) with the other ones. + // + wxConfigBase* conf = wxConfigBase::Get(); + wxString key, outstring; + for(int i = 0; ; ++i) + { + key.clear(); + key << i; + if(!conf->Read(key, &outstring)) + break; + page->m_playlist->AddToPlayList(outstring); + } + // // Create a timer to update our status bar // @@ -710,15 +725,6 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // 2) Delete our timer explicitly // ---------------------------------------------------------------------------- wxMediaPlayerFrame::~wxMediaPlayerFrame() -{ - delete m_timer; - -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::OnClose -// ---------------------------------------------------------------------------- -void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) { // // Here we save our info to the registry or whatever @@ -737,21 +743,32 @@ void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) // all you'd need to do is just remove everything after // conf->DeleteAll() here // - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + // As an exercise to the reader, try modifying this so + // that it saves the data for each notebook page + // + wxMediaPlayerListCtrl* playlist = + ((wxMediaPlayerNotebookPage*)m_notebook->GetPage(0))->m_playlist; wxConfigBase* conf = wxConfigBase::Get(); conf->DeleteAll(); - for(int i = 0; i < m_playlist->GetItemCount(); ++i) + for(int i = 0; i < playlist->GetItemCount(); ++i) { - wxString* pData = (wxString*) m_playlist->GetItemData(i); + wxString* pData = (wxString*) playlist->GetItemData(i); wxString s; s << i; conf->Write(s, *(pData)); delete pData; } + delete m_timer; +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerFrame::OnClose +// ---------------------------------------------------------------------------- +void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) +{ event.Skip(); //really close the frame } @@ -786,10 +803,11 @@ void wxMediaPlayerFrame::AddToPlayList(const wxString& szString) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::ResetStatus() { - wxMediaCtrl* currentMediaCtrl = GetCurrentMediaCtrl(); + wxMediaCtrl* currentMediaCtrl = + ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl; - m_basestatus = wxString::Format(_T("Size(x,y):%i,%i ") - _T("Length(Seconds):%u Speed:%1.1fx"), + m_basestatus = wxString::Format(wxT("Size(x,y):%i,%i ") + wxT("Length(Seconds):%u Speed:%1.1fx"), currentMediaCtrl->GetBestSize().x, currentMediaCtrl->GetBestSize().y, (unsigned)((currentMediaCtrl->Length() / 1000)), @@ -797,37 +815,6 @@ void wxMediaPlayerFrame::ResetStatus() ); } -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentMediaCtrl -// -// Obtains the media control of the current page, or NULL if there are no -// pages open -// ---------------------------------------------------------------------------- -wxMediaCtrl* wxMediaPlayerFrame::GetCurrentMediaCtrl() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl; -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentSlider -// -// Obtains the slider of the current page -// ---------------------------------------------------------------------------- -wxSlider* wxMediaPlayerFrame::GetCurrentSlider() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_slider; -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentGauge -// -// Obtains the gauge of the current page -// ---------------------------------------------------------------------------- -wxGauge* wxMediaPlayerFrame::GetCurrentGauge() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_gauge; -} - // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnQuit // @@ -849,10 +836,10 @@ void wxMediaPlayerFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; - msg.Printf( _T("This is a test of wxMediaCtrl.\n") - _T("Welcome to %s"), wxVERSION_STRING); + msg.Printf( wxT("This is a test of wxMediaCtrl.\n") + wxT("Welcome to %s"), wxVERSION_STRING); - wxMessageBox(msg, _T("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this); + wxMessageBox(msg, wxT("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this); } // ---------------------------------------------------------------------------- @@ -863,14 +850,10 @@ void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnLoop(wxCommandEvent& WXUNUSED(event)) { - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage()); - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_bLoop = - !((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_bLoop; + currentpage->m_bLoop = !currentpage->m_bLoop; } // ---------------------------------------------------------------------------- @@ -881,15 +864,23 @@ void wxMediaPlayerFrame::OnLoop(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent& event) { - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage()); - GetCurrentMediaCtrl()->ShowPlayerControls(event.IsChecked() ? + if( !currentpage->m_mediactrl->ShowPlayerControls(event.IsChecked() ? wxMEDIACTRLPLAYERCONTROLS_DEFAULT : - wxMEDIACTRLPLAYERCONTROLS_NONE); + wxMEDIACTRLPLAYERCONTROLS_NONE) ) + { + //error - uncheck and warn user + wxMenuItem* pSIItem = GetMenuBar()->FindItem(wxID_SHOWINTERFACE); + wxASSERT(pSIItem); + pSIItem->Check(!event.IsChecked()); + + if(event.IsChecked()) + wxMessageBox(wxT("Could not show player controls")); + else + wxMessageBox(wxT("Could not hide player controls")); + } } // ---------------------------------------------------------------------------- @@ -946,34 +937,34 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) true); } - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if(m_nLastFileId != -1) - m_playlist->SetItemState(m_nLastFileId, 0, wxLIST_STATE_SELECTED); + if(currentpage->m_nLastFileId != -1) + currentpage->m_playlist->SetItemState(currentpage->m_nLastFileId, + 0, wxLIST_STATE_SELECTED); wxListItem newlistitem; newlistitem.SetAlign(wxLIST_FORMAT_LEFT); int nID; - newlistitem.SetId(nID = m_playlist->GetItemCount()); + newlistitem.SetId(nID = currentpage->m_playlist->GetItemCount()); newlistitem.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_STATE); newlistitem.SetState(wxLIST_STATE_SELECTED); newlistitem.SetData(new wxString(path)); - m_playlist->InsertItem(newlistitem); - m_playlist->SetItem(nID, 0, _T("*")); - m_playlist->SetItem(nID, 1, wxFileName(path).GetName()); + currentpage->m_playlist->InsertItem(newlistitem); + currentpage->m_playlist->SetItem(nID, 0, wxT("*")); + currentpage->m_playlist->SetItem(nID, 1, wxFileName(path).GetName()); if (nID % 2) { newlistitem.SetBackgroundColour(wxColour(192,192,192)); - m_playlist->SetItem(newlistitem); + currentpage->m_playlist->SetItem(newlistitem); } DoPlayFile(path); - // m_playlist->Focus(nID); } // ---------------------------------------------------------------------------- @@ -984,69 +975,80 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::DoPlayFile(const wxString& path) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); - - if(listitem.GetData() && - m_szFile.compare(path) == 0 && - m_nLastFileId == listitem.GetId()) + currentpage->m_playlist->GetSelectedItem(listitem); + + if( ( listitem.GetData() && + currentpage->m_nLastFileId == listitem.GetId() && + currentpage->m_szFile.compare(path) == 0 ) || + ( !listitem.GetData() && + currentpage->m_nLastFileId != -1 && + currentpage->m_szFile.compare(path) == 0) + ) { - if(GetCurrentMediaCtrl()->GetState() == wxMEDIASTATE_PLAYING) + if(currentpage->m_mediactrl->GetState() == wxMEDIASTATE_PLAYING) { - if( !GetCurrentMediaCtrl()->Pause() ) + if( !currentpage->m_mediactrl->Pause() ) wxMessageBox(wxT("Couldn't pause movie!")); else - m_playlist->SetItem(listitem.GetId(), 0, _T("||")); + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT("||")); } else { - if( !GetCurrentMediaCtrl()->Play() ) - wxMessageBox(wxT("Couldn't pause movie!")); + if( !currentpage->m_mediactrl->Play() ) + wxMessageBox(wxT("Couldn't play movie!")); else - m_playlist->SetItem(listitem.GetId(), 0, _T(">")); + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT(">")); } } else { + int nNewId = listitem.GetData() ? listitem.GetId() : + currentpage->m_playlist->GetItemCount()-1; m_notebook->SetPageText(m_notebook->GetSelection(), wxFileName(path).GetName()); - if(m_nLastFileId != -1) - m_playlist->SetItem(m_nLastFileId, 0, _T("*")); + if(currentpage->m_nLastFileId != -1) + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT("*")); wxURI uripath(path); if( uripath.IsReference() ) { - if( !GetCurrentMediaCtrl()->Load(path) ) + if( !currentpage->m_mediactrl->Load(path) ) { wxMessageBox(wxT("Couldn't load file!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T("O")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("O")); } } else { - if( !GetCurrentMediaCtrl()->Load(uripath) ) + if( !currentpage->m_mediactrl->Load(uripath) ) { - wxMessageBox(wxT("Couldn't load file!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + wxMessageBox(wxT("Couldn't load URL!")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T("O")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("O")); } } - m_nLastFileId = listitem.GetId(); - m_szFile = path; - m_playlist->SetItem(m_nLastFileId, 1, wxFileName(path).GetName()); - m_playlist->SetItem(m_nLastFileId, 2, wxT("")); + currentpage->m_nLastFileId = nNewId; + currentpage->m_szFile = path; + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + 1, wxFileName(path).GetName()); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + 2, wxT("")); } } @@ -1058,29 +1060,29 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; - wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if( !GetCurrentMediaCtrl()->Play() ) + if( !currentpage->m_mediactrl->Play() ) { wxMessageBox(wxT("Couldn't play movie!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T(">")); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT(">")); } - m_playlist->SetItem(listitem.GetId(), 2, wxString::Format(wxT("%u"), - (unsigned) GetCurrentMediaCtrl()->Length() / 1000) ); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + 2, wxString::Format(wxT("%u"), + (unsigned) currentpage->m_mediactrl->Length() / 1000) + ); ResetStatus(); - GetCurrentSlider()->SetRange(0, - (int)(GetCurrentMediaCtrl()->Length() / 1000)); - GetCurrentGauge()->SetRange((int)(GetCurrentMediaCtrl()->Length() / 1000)); + currentpage->m_slider->SetRange(0, + (int)(currentpage->m_mediactrl->Length() / 1000)); + currentpage->m_gauge->SetRange((int)(currentpage->m_mediactrl->Length() / 1000)); } // ---------------------------------------------------------------------------- @@ -1106,7 +1108,10 @@ void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent& WXUNUSED(evt)) m_notebook->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook, sBackend ), wxT(""), true); - DoOpenFile(m_szFile, false); + + DoOpenFile( + ((wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage())->m_szFile, + false); } } @@ -1184,35 +1189,36 @@ void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + currentpage->m_playlist->GetSelectedItem(listitem); if ( !listitem.GetData() ) { int nLast = -1; - if ((nLast = m_playlist->GetNextItem(nLast, + if ((nLast = currentpage->m_playlist->GetNextItem(nLast, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE)) == -1) { //no items in list - wxMessageBox(_T("No items in playlist!")); - return; + wxMessageBox(wxT("No items in playlist!")); } - wxListItem listitem; + else + { listitem.SetId(nLast); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); - wxListEvent event; - OnChangeSong(event); + currentpage->m_playlist->SetItem(listitem); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); + } } else { - wxListEvent event; - OnChangeSong(event); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } } @@ -1225,22 +1231,22 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) { if(event.GetKeyCode() == WXK_BACK/*DELETE*/) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); //delete all selected items while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem( + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; wxListItem listitem; listitem.SetId(nSelectedItem); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); delete (wxString*) listitem.GetData(); - m_playlist->DeleteItem(nSelectedItem); + currentpage->m_playlist->DeleteItem(nSelectedItem); } } @@ -1260,21 +1266,14 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; - - wxListItem listitem; - m_playlist->GetSelectedItem(listitem); - m_playlist->SetItem(listitem.GetId(), 0, _T("[]")); - - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if( !GetCurrentMediaCtrl()->Stop() ) + if( !currentpage->m_mediactrl->Stop() ) wxMessageBox(wxT("Couldn't stop movie!")); + else + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT("[]")); } @@ -1287,12 +1286,15 @@ void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + currentpage->m_playlist->GetSelectedItem(listitem); + if(listitem.GetData()) DoPlayFile((*((wxString*) listitem.GetData()))); + else + wxMessageBox(wxT("No selected item!")); } // ---------------------------------------------------------------------------- @@ -1303,37 +1305,49 @@ void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if (m_playlist->GetItemCount() == 0) + if (currentpage->m_playlist->GetItemCount() == 0) return; wxInt32 nLastSelectedItem = -1; while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem(nLastSelectedItem, + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; nLastSelectedItem = nSelectedItem; - m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); + currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); } - if (nLastSelectedItem <= 0) - nLastSelectedItem = m_playlist->GetItemCount() - 1; + if (nLastSelectedItem == -1) + { + //nothing selected, default to the file before the currently playing one + if(currentpage->m_nLastFileId == 0) + nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1; + else + nLastSelectedItem = currentpage->m_nLastFileId - 1; + } + else if (nLastSelectedItem == 0) + nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1; else nLastSelectedItem -= 1; + if(nLastSelectedItem == currentpage->m_nLastFileId) + return; //already playing... nothing to do + wxListItem listitem; listitem.SetId(nLastSelectedItem); - m_playlist->GetItem(listitem); + listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); + currentpage->m_playlist->SetItem(listitem); - wxListEvent emptyEvent; - OnChangeSong(emptyEvent); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } // ---------------------------------------------------------------------------- @@ -1344,42 +1358,48 @@ void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if (m_playlist->GetItemCount() == 0) + if (currentpage->m_playlist->GetItemCount() == 0) return; wxInt32 nLastSelectedItem = -1; while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem(nLastSelectedItem, + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; nLastSelectedItem = nSelectedItem; - m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); + currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); } if (nLastSelectedItem == -1) + { + if(currentpage->m_nLastFileId == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; else - { - if (nLastSelectedItem == m_playlist->GetItemCount() - 1) + nLastSelectedItem = currentpage->m_nLastFileId + 1; + } + else if (nLastSelectedItem == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; else nLastSelectedItem += 1; - } + + if(nLastSelectedItem == currentpage->m_nLastFileId) + return; //already playing... nothing to do wxListItem listitem; + listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA); listitem.SetId(nLastSelectedItem); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); + currentpage->m_playlist->SetItem(listitem); - wxListEvent emptyEvent; - OnChangeSong(emptyEvent); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } @@ -1390,8 +1410,11 @@ void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event)) { - double dVolume = GetCurrentMediaCtrl()->GetVolume(); - GetCurrentMediaCtrl()->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1); + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); + + double dVolume = currentpage->m_mediactrl->GetVolume(); + currentpage->m_mediactrl->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1); } // ---------------------------------------------------------------------------- @@ -1401,16 +1424,18 @@ void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event)) { - double dVolume = GetCurrentMediaCtrl()->GetVolume(); - GetCurrentMediaCtrl()->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1); + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); + + double dVolume = currentpage->m_mediactrl->GetVolume(); + currentpage->m_mediactrl->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1); } // ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::OnCloseCurrentPage +// wxMediaPlayerFrame::OnPageChange // -// Called when the user wants to closes the current notebook page +// Called when the user changes the current notebook page shown // ---------------------------------------------------------------------------- - void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event)) { ResetStatus(); @@ -1432,35 +1457,30 @@ void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerTimer::Notify() { - if(m_frame->m_notebook->GetCurrentPage()) - { - // get some control pointers from current notebook page - wxMediaCtrl* mediactrl = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_mediactrl; - wxSlider* slider = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_slider; - wxGauge* gauge = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_gauge; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_frame->m_notebook->GetCurrentPage(); + if(currentpage) + { // if the slider is being dragged then update it with the song position - if(((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->IsBeingDragged() == false) + if(currentpage->IsBeingDragged() == false) { - long lPosition = (long)( mediactrl->Tell() / 1000 ); - slider->SetValue(lPosition); + long lPosition = (long)( currentpage->m_mediactrl->Tell() / 1000 ); + currentpage->m_slider->SetValue(lPosition); } // update guage with value from slider - gauge->SetValue(slider->GetValue()); + currentpage->m_gauge->SetValue(currentpage->m_slider->GetValue()); #if wxUSE_STATUSBAR m_frame->SetStatusText(wxString::Format( wxT("%s Pos:%u State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"), m_frame->m_basestatus.c_str(), - slider->GetValue(), - wxGetMediaStateText(mediactrl->GetState()), - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_nLoops, - (int)mediactrl->GetDownloadProgress(), - (int)mediactrl->GetDownloadTotal(), - (int)(mediactrl->GetVolume() * 100))); + currentpage->m_slider->GetValue(), + wxGetMediaStateText(currentpage->m_mediactrl->GetState()), + currentpage->m_nLoops, + (int)currentpage->m_mediactrl->GetDownloadProgress(), + (int)currentpage->m_mediactrl->GetDownloadTotal(), + (int)(currentpage->m_mediactrl->GetVolume() * 100))); #endif // wxUSE_STATUSBAR } } @@ -1478,11 +1498,11 @@ void wxMediaPlayerTimer::Notify() // Creates a media control and slider and adds it to this panel, // along with some sizers for positioning // ---------------------------------------------------------------------------- - wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame, wxNotebook* theBook, const wxString& szBackend) : wxPanel(theBook, wxID_ANY), + m_nLastFileId(-1), m_nLoops(0), m_bLoop(false), m_bIsBeingDragged(false), @@ -1562,30 +1582,6 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_playlist->SetDropTarget(new wxPlayListDropTarget(*m_playlist)); sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5); - // - // Here we load the our configuration - - // in our case we load all the files that were left in - // the playlist the last time the user closed our application - // - // TODO: This is probably not the best practice since - // the user will load multiple notebook pages with multiple - // wxMediaCtrl elements. - // - // As an exercise to the reader try modifying it so that - // it properly loads the playlist for each page without - // conflicting (loading the same data) with the other ones. - // - wxConfigBase* conf = wxConfigBase::Get(); - wxString key, outstring; - for(int i = 0; ; ++i) - { - key.clear(); - key << i; - if(!conf->Read(key, &outstring)) - break; - m_playlist->AddToPlayList(outstring); - } - // // Create the control buttons // TODO/FIXME/HACK: This part about sizers is really a nice hack @@ -1601,12 +1597,12 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_vdButton = new wxButton(); m_vuButton = new wxButton(); - m_prevButton->Create(this, wxID_BUTTONPREV, _T("|<")); - m_playButton->Create(this, wxID_BUTTONPLAY, _T(">")); - m_stopButton->Create(this, wxID_BUTTONSTOP, _T("[]")); - m_nextButton->Create(this, wxID_BUTTONNEXT, _T(">|")); - m_vdButton->Create(this, wxID_BUTTONVD, _T("((")); - m_vuButton->Create(this, wxID_BUTTONVU, _T("))")); + m_prevButton->Create(this, wxID_BUTTONPREV, wxT("|<")); + m_playButton->Create(this, wxID_BUTTONPLAY, wxT(">")); + m_stopButton->Create(this, wxID_BUTTONSTOP, wxT("[]")); + m_nextButton->Create(this, wxID_BUTTONNEXT, wxT(">|")); + m_vdButton->Create(this, wxID_BUTTONVD, wxT("((")); + m_vuButton->Create(this, wxID_BUTTONVU, wxT("))")); vertsizer->Add(m_prevButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); vertsizer->Add(m_playButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); vertsizer->Add(m_stopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); @@ -1735,14 +1731,14 @@ void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event)) if ( !m_mediactrl->Play() ) { wxMessageBox(wxT("Couldn't loop movie!")); - m_playlist->SetItem(m_parentFrame->m_nLastFileId, 0, _T("E")); + m_playlist->SetItem(m_nLastFileId, 0, wxT("E")); } else ++m_nLoops; } else { - m_playlist->SetItem(m_parentFrame->m_nLastFileId, 0, _T("[]")); + m_playlist->SetItem(m_nLastFileId, 0, wxT("[]")); } } diff --git a/src/common/mediactrlcmn.cpp b/src/common/mediactrlcmn.cpp index 59a420aa81..2b1bd5d3c8 100644 --- a/src/common/mediactrlcmn.cpp +++ b/src/common/mediactrlcmn.cpp @@ -468,6 +468,49 @@ void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h) m_imp->Move(x, y, w, h); } +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +// wxMediaBackendCommonBase +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void wxMediaBackendCommonBase::NotifyMovieSizeChanged() +{ + // our best size changed after opening a new file + m_ctrl->InvalidateBestSize(); + m_ctrl->SetSize(m_ctrl->GetSize()); + + // if the parent of the control has a sizer ask it to refresh our size + wxWindow * const parent = m_ctrl->GetParent(); + if ( parent->GetSizer() ) + { + m_ctrl->GetParent()->Layout(); + m_ctrl->GetParent()->Refresh(); + m_ctrl->GetParent()->Update(); + } +} + +void wxMediaBackendCommonBase::NotifyMovieLoaded() +{ + NotifyMovieSizeChanged(); + + // notify about movie being fully loaded + QueueEvent(wxEVT_MEDIA_LOADED); +} + +bool wxMediaBackendCommonBase::SendStopEvent() +{ + wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId()); + + return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed(); +} + +void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType) +{ + wxMediaEvent theEvent(evtType, m_ctrl->GetId()); + m_ctrl->AddPendingEvent(theEvent); +} + #include "wx/html/forcelnk.h" FORCE_LINK(basewxmediabackends); diff --git a/src/mac/carbon/mediactrl.cpp b/src/mac/carbon/mediactrl.cpp index d2eb4c053f..8c56a16366 100644 --- a/src/mac/carbon/mediactrl.cpp +++ b/src/mac/carbon/mediactrl.cpp @@ -5,10 +5,15 @@ // Modified by: // Created: 11/07/04 // RCS-ID: $Id$ -// Copyright: (c) 2004-2005 Ryan Norton, portions (c) 2004 Kevin Olliver +// Copyright: (c) 2004-2005 Ryan Norton // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// There are several known bugs with CreateMovieControl +// on systems > 10.2 - see main.c of QTCarbonShell sample for details +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //=========================================================================== // DECLARATIONS //=========================================================================== @@ -43,13 +48,20 @@ // control - i.e. native positioning and event handling etc.. //--------------------------------------------------------------------------- #ifndef wxUSE_CREATEMOVIECONTROL -# if defined( __WXMAC_OSX__ ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 ) +# if defined( __WXMAC_OSX__ ) && \ + ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 ) # define wxUSE_CREATEMOVIECONTROL 1 # else # define wxUSE_CREATEMOVIECONTROL 0 # endif #endif +//--------------------------------------------------------------------------- +// Height and Width of movie controller in the movie control +//--------------------------------------------------------------------------- +#define wxMCWIDTH 320 +#define wxMCHEIGHT 16 + //=========================================================================== // BACKEND DECLARATIONS //=========================================================================== @@ -74,20 +86,9 @@ #include #endif -//Determines whether version 4 of QT is installed (Pretty much for classic only) -Boolean _wxIsQuickTime4Installed (void) -{ - short error; - long result; - - error = Gestalt (gestaltQuickTime, &result); - return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0400); -} - -class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend +class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackendCommonBase { public: - wxQTMediaBackend(); ~wxQTMediaBackend(); @@ -124,19 +125,79 @@ public: void Cleanup(); void FinishLoad(); - wxSize m_bestSize; //Original movie size + virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags); + + + // + // ------ Implementation from now on -------- + // + void DoLoadBestSize(); + void DoSetControllerVisible(wxMediaCtrlPlayerControls flags); + + //TODO: Last param actually long - does this work on 64bit machines? + static Boolean MCFilterProc (MovieController theController, + short action, void *params, long refCon); + +#if wxUSE_CREATEMOVIECONTROL + void DoCreateMovieControl(); +#else + Boolean IsQuickTime4Installed(); + void DoNewMovieController(); + static void PPRMProc (Movie theMovie, OSErr theErr, void* theRefCon); +#endif + + wxSize m_bestSize; // Original movie size #ifdef __WXMAC_OSX__ - struct MovieType** m_movie; //QT Movie handle/instance + struct MovieType** m_movie; // QT Movie handle/instance #else - Movie m_movie ; + Movie m_movie; // Movie instance #endif - wxControl* m_ctrl; //Parent control - bool m_bVideo; //Whether or not we have video - class _wxQTTimer* m_timer; //Timer for streaming the movie + bool m_bPlaying; // Whether media is playing or not + class wxTimer* m_timer; // Timer for streaming the movie + MovieController m_mc; // MovieController instance + wxMediaCtrlPlayerControls m_interfaceflags; // Saved interface flags +#if !wxUSE_CREATEMOVIECONTROL + EventHandlerRef m_pEventHandlerRef; // Event handler to cleanup + friend class wxQTMediaEvtHandler; +#endif DECLARE_DYNAMIC_CLASS(wxQTMediaBackend) }; +#if !wxUSE_CREATEMOVIECONTROL +// helper to hijack background erasing for the QT window +class WXDLLIMPEXP_MEDIA wxQTMediaEvtHandler : public wxEvtHandler +{ +public: + wxQTMediaEvtHandler(wxQTMediaBackend *qtb) + { + m_qtb = qtb; + + qtb->m_ctrl->Connect(qtb->m_ctrl->GetId(), wxEVT_ERASE_BACKGROUND, + wxEraseEventHandler(wxQTMediaEvtHandler::OnEraseBackground), + NULL, this); + } + + void OnEraseBackground(wxEraseEvent& event); + +private: + wxQTMediaBackend *m_qtb; + + DECLARE_NO_COPY_CLASS(wxQTMediaEvtHandler) +}; + +// Window event handler +static pascal OSStatus wxQTMediaWindowEventHandler( + EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, void *inUserData); +DEFINE_ONE_SHOT_HANDLER_GETTER( wxQTMediaWindowEventHandler ); + +#endif + +//=========================================================================== +// IMPLEMENTATION +//=========================================================================== + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // @@ -146,74 +207,110 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend); -//Time between timer calls -#define MOVIE_DELAY 100 +//Time between timer calls - this is the Apple recommondation to the TCL +//team I believe +#define MOVIE_DELAY 20 -// -------------------------------------------------------------------------- -// wxQTTimer - Handle Asyncronous Playing -// -------------------------------------------------------------------------- -class _wxQTTimer : public wxTimer +//--------------------------------------------------------------------------- +// wxQTMediaLoadTimer +// +// QT, esp. QT for Windows is very picky about how you go about +// async loading. If you were to go through a Windows message loop +// or a MoviesTask or both and then check the movie load state +// it would still return 1000 (loading)... even (pre)prerolling doesn't +// help. However, making a load timer like this works +//--------------------------------------------------------------------------- +class wxQTMediaLoadTimer : public wxTimer { public: - _wxQTTimer(Movie movie, wxQTMediaBackend* parent) : - m_movie(movie), m_bPaused(false), m_parent(parent) - { - } + wxQTMediaLoadTimer(Movie movie, wxQTMediaBackend* parent) : + m_movie(movie), m_parent(parent) {} - ~_wxQTTimer() + void Notify() + { + //Note that the CreateMovieControl variety performs + //its own custom idleing +#if !wxUSE_CREATEMOVIECONTROL + ::MCIdle(m_parent->m_mc); +#endif + //kMovieLoadStatePlayable is not enough on MAC + //- it plays, but IsMovieDone might return true (!) + //sure we need to wait until kMovieLoadStatePlaythroughOK + if(::GetMovieLoadState(m_movie) >= 20000) { + m_parent->FinishLoad(); + delete this; + } } - bool GetPaused() {return m_bPaused;} - void SetPaused(bool bPaused) {m_bPaused = bPaused;} +protected: + Movie m_movie; //Our movie instance + wxQTMediaBackend* m_parent; //Backend pointer +}; + +// -------------------------------------------------------------------------- +// wxQTMediaPlayTimer - Handle Asyncronous Playing +// +// 1) Checks to see if the movie is done, and if not continues +// streaming the movie +// 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of +// the movie. +// -------------------------------------------------------------------------- +class wxQTMediaPlayTimer : public wxTimer +{ +public: + wxQTMediaPlayTimer(Movie movie, wxQTMediaBackend* parent) : + m_movie(movie), m_parent(parent) {} - //----------------------------------------------------------------------- - // _wxQTTimer::Notify - // - // 1) Checks to see if the movie is done, and if not continues - // streaming the movie - // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of - // the movie. - //----------------------------------------------------------------------- void Notify() - { - if (!m_bPaused) { - if(!IsMovieDone(m_movie)) - MoviesTask(m_movie, MOVIE_DELAY); - else - { - wxMediaEvent theEvent(wxEVT_MEDIA_STOP, - m_parent->m_ctrl->GetId()); - m_parent->m_ctrl->ProcessEvent(theEvent); + //Note that CreateMovieControl performs its own idleing +#if !wxUSE_CREATEMOVIECONTROL + // + // OK, a little explaining - basically originally + // we only called MoviesTask if the movie was actually + // playing (not paused or stopped)... this was before + // we realized MoviesTask actually handles repainting + // of the current frame - so if you were to resize + // or something it would previously not redraw that + // portion of the movie. + // + // So now we call MoviesTask always so that it repaints + // correctly. + // + ::MCIdle(m_parent->m_mc); +#endif - if(theEvent.IsAllowed()) + // + // Handle the stop event - if the movie has reached + // the end, notify our handler + // + if(::IsMovieDone(m_movie)) { - Stop(); + if ( m_parent->SendStopEvent() ) + { m_parent->Stop(); wxASSERT(::GetMoviesError() == noErr); - //send the event to our child - wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, - m_parent->m_ctrl->GetId()); - m_parent->m_ctrl->ProcessEvent(theEvent); - } + m_parent->QueueFinishEvent(); } } } protected: Movie m_movie; //Our movie instance - bool m_bPaused; //Whether we are paused or not wxQTMediaBackend* m_parent; //Backend pointer }; + //--------------------------------------------------------------------------- // wxQTMediaBackend Constructor // // Sets m_timer to NULL signifying we havn't loaded anything yet //--------------------------------------------------------------------------- -wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL) +wxQTMediaBackend::wxQTMediaBackend() + : m_movie(NULL), m_bPlaying(false), m_timer(NULL) + , m_mc(NULL), m_interfaceflags(wxMEDIACTRLPLAYERCONTROLS_NONE) { } @@ -228,9 +325,20 @@ wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL) //--------------------------------------------------------------------------- wxQTMediaBackend::~wxQTMediaBackend() { - if(m_timer) + if(m_movie) Cleanup(); +#if !wxUSE_CREATEMOVIECONTROL + // Cleanup for moviecontroller + if(m_mc) + { + // destroy wxQTMediaEvtHandler we pushed on it + m_ctrl->PopEventHandler(true); + RemoveEventHandler((EventHandlerRef&)m_pEventHandlerRef); + ::DisposeMovieController(m_mc); + } +#endif + //Note that ExitMovies() is not necessary... ExitMovies(); } @@ -250,8 +358,8 @@ bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, const wxString& name) { //Don't bother in Native control mode -#if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 ) - if (!_wxIsQuickTime4Installed()) +#if !wxUSE_CREATEMOVIECONTROL + if (!IsQuickTime4Installed()) return false; #endif @@ -265,17 +373,9 @@ bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, // Since we don't have a child window like most other // backends, we don't need wxCLIP_CHILDREN // - if ( ! - -#if wxUSE_CREATEMOVIECONTROL - ctrl->wxWindow::Create(parent, id, pos, size, + if ( !ctrl->wxControl::Create(parent, id, pos, size, wxWindow::MacRemoveBordersFromStyle(style), - name) -#else - ctrl->wxControl::Create(parent, id, pos, size, - wxWindow::MacRemoveBordersFromStyle(style), validator, name) -#endif ) return false; @@ -283,10 +383,27 @@ bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, ctrl->SetValidator(validator); #endif - m_ctrl = ctrl; + m_ctrl = (wxMediaCtrl*)ctrl; return true; } +//--------------------------------------------------------------------------- +// wxQTMediaBackend::IsQuickTime4Installed +// +// Determines whether version 4 of QT is installed +// (Pretty much for classic only) +//--------------------------------------------------------------------------- +#if !wxUSE_CREATEMOVIECONTROL +Boolean wxQTMediaBackend::IsQuickTime4Installed() +{ + short error; + long result; + + error = Gestalt (gestaltQuickTime, &result); + return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0400); +} +#endif + //--------------------------------------------------------------------------- // wxQTMediaBackend::Load (file version) // @@ -298,7 +415,7 @@ bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, //--------------------------------------------------------------------------- bool wxQTMediaBackend::Load(const wxString& fileName) { - if(m_timer) + if(m_movie) Cleanup(); OSErr err = noErr; @@ -327,15 +444,52 @@ bool wxQTMediaBackend::Load(const wxString& fileName) newMovieActive, NULL); //wasChanged - CloseMovieFile (movieResFile); - - if (err != noErr) - return false; + //No ::GetMoviesStickyError() here because it returns -2009 + // a.k.a. invalid track on valid mpegs + if(err == noErr) + { + ::CloseMovieFile (movieResFile); + // Create movie controller/control +#if wxUSE_CREATEMOVIECONTROL + DoCreateMovieControl(); +#else + DoNewMovieController(); +#endif FinishLoad(); + return true; + } + else + { + return false; + } +} - return ::GetMoviesError() == noErr; +//--------------------------------------------------------------------------- +// wxQTMediaBackend::PPRMProc (static) +// +// Called when done PrePrerolling the movie. +// Note that in 99% of the cases this does nothing... +// Anyway we set up the loading timer here to tell us when the movie is done +//--------------------------------------------------------------------------- +#if !wxUSE_CREATEMOVIECONTROL +void wxQTMediaBackend::PPRMProc (Movie theMovie, + OSErr WXUNUSED_UNLESS_DEBUG(theErr), + void* theRefCon) +{ + wxASSERT( theMovie ); + wxASSERT( theRefCon ); + wxASSERT( theErr == noErr ); + + wxQTMediaBackend* pBE = (wxQTMediaBackend*) theRefCon; + + long lTime = ::GetMovieTime(theMovie,NULL); + Fixed rate = ::GetMoviePreferredRate(theMovie); + ::PrerollMovie(theMovie,lTime,rate); + pBE->m_timer = new wxQTMediaLoadTimer(pBE->m_movie, pBE); + pBE->m_timer->Start(MOVIE_DELAY); } +#endif //--------------------------------------------------------------------------- // wxQTMediaBackend::Load (URL Version) @@ -350,87 +504,93 @@ bool wxQTMediaBackend::Load(const wxString& fileName) //--------------------------------------------------------------------------- bool wxQTMediaBackend::Load(const wxURI& location) { - if(m_timer) + if(m_movie) Cleanup(); wxString theURI = location.BuildURI(); OSErr err = noErr; - Handle theHandle = NewHandleClear(theURI.length() + 1); + Handle theHandle = ::NewHandleClear(theURI.length() + 1); wxASSERT(theHandle); - BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1); + ::BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1); //create the movie from the handle that refers to the URI - err = NewMovieFromDataRef(&m_movie, newMovieActive, + err = ::NewMovieFromDataRef(&m_movie, newMovieActive | + newMovieAsyncOK + /*|newMovieIdleImportOK*/, NULL, theHandle, URLDataHandlerSubType); - DisposeHandle(theHandle); + ::DisposeHandle(theHandle); - if (err != noErr) - return false; + if (err == noErr) + { +#if wxUSE_CREATEMOVIECONTROL + // Movie control resets prerolling, so we must create first + DoCreateMovieControl(); - //preroll movie for streaming - //TODO:Async this using threads? - TimeValue timeNow; + // Setup timer to catch load event + m_timer = new wxQTMediaLoadTimer(m_movie, this); + m_timer->Start(MOVIE_DELAY); +#else + // Movie controller resets prerolling, so we must create first + DoNewMovieController(); + + long timeNow; Fixed playRate; - timeNow = GetMovieTime(m_movie, NULL); - playRate = GetMoviePreferredRate(m_movie); - PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL); - PrerollMovie(m_movie, timeNow, playRate); - SetMovieRate(m_movie, playRate); - FinishLoad(); + timeNow = ::GetMovieTime(m_movie, NULL); + wxASSERT(::GetMoviesError() == noErr); - return ::GetMoviesError() == noErr; + playRate = ::GetMoviePreferredRate(m_movie); + wxASSERT(::GetMoviesError() == noErr); + + // + // Note that the callback here is optional, + // but without it PrePrerollMovie can be buggy + // (see Apple ml). Also, some may wonder + // why we need this at all - this is because + // Apple docs say QuickTime streamed movies + // require it if you don't use a Movie Controller, + // which we don't by default. + // + ::PrePrerollMovie(m_movie, timeNow, playRate, + wxQTMediaBackend::PPRMProc, + (void*)this); +#endif + return true; + } + else + return false; } //--------------------------------------------------------------------------- -// wxQTMediaBackend::FinishLoad +// wxQTMediaBackend::DoCreateMovieControl +// +// Calls CreateMovieControl and performs setup related to it // -// 1) Create the movie timer -// 2) Get real size of movie for GetBestSize/sizers -// 3) See if there is video in the movie, and if so then either -// SetMovieGWorld if < 10.2 or use Native CreateMovieControl -// 4) Set the movie time scale to something usable so that seeking -// etc. will work correctly -// 5) Refresh parent window +// Note that we always hide the controller initially becuase when loading +// from a url it displays about a 40x40 box with the word loading... in it, +// but the box is outside the range of the control, which is bad (0,0 +// i believe), so we need to wait until finishload to actually display +// the movie controller in this instance //--------------------------------------------------------------------------- -void wxQTMediaBackend::FinishLoad() -{ - m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this); - wxASSERT(m_timer); - - //get the real size of the movie - Rect outRect; - ::GetMovieNaturalBoundsRect (m_movie, &outRect); - wxASSERT(::GetMoviesError() == noErr); - - m_bestSize.x = outRect.right - outRect.left; - m_bestSize.y = outRect.bottom - outRect.top; - - //reparent movie/*AudioMediaCharacteristic*/ - if(GetMovieIndTrackType(m_movie, 1, - VisualMediaCharacteristic, - movieTrackCharacteristic | - movieTrackEnabledOnly) != NULL) - { #if wxUSE_CREATEMOVIECONTROL +void wxQTMediaBackend::DoCreateMovieControl() +{ // //Native CreateMovieControl QT control (Thanks to Kevin Olliver's //wxQTMovie for some of this). // - #define GetControlPeer(whatever) ctrl->m_peer - wxMediaCtrl* ctrl = (wxMediaCtrl*) m_ctrl; Rect bounds = wxMacGetBoundsForControl(m_ctrl, m_ctrl->GetPosition(), m_ctrl->GetSize()); //Dispose of old control for new one - if (GetControlPeer(m_ctrl) && GetControlPeer(m_ctrl)->Ok() ) - GetControlPeer(m_ctrl)->Dispose(); + if (m_ctrl->m_peer && m_ctrl->m_peer->Ok() ) + m_ctrl->m_peer->Dispose(); //Options- //kMovieControlOptionXXX @@ -442,93 +602,207 @@ void wxQTMediaBackend::FinishLoad() //ManuallyIdled - app handles movie idling rather than internal timer event loop ::CreateMovieControl( (WindowRef) - ctrl->MacGetTopLevelWindowRef(), //parent + m_ctrl->MacGetTopLevelWindowRef(), //parent &bounds, //control bounds m_movie, //movie handle kMovieControlOptionHideController | kMovieControlOptionLocateTopLeft | kMovieControlOptionSetKeysEnabled -// | kMovieControlOptionManuallyIdled + // | kMovieControlOptionManuallyIdled , //flags - ctrl->m_peer->GetControlRefAddr() ); + m_ctrl->m_peer->GetControlRefAddr() ); - ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle()); -#else + ::EmbedControl(m_ctrl->m_peer->GetControlRef(), + (ControlRef)m_ctrl->GetParent()->GetHandle()); + // - //"Emulation" + // Setup MovieController for the new movie // - SetMovieGWorld(m_movie, - (CGrafPtr) - GetWindowPort( - (WindowRef) - m_ctrl->MacGetTopLevelWindowRef() - ), - nil); + long dataSize; + + //Get movie controller from our control + ::GetControlData( m_ctrl->m_peer->GetControlRef(), 0, + kMovieControlDataMovieController, + sizeof(MovieController), (Ptr)&m_mc, &dataSize ); + + // Setup a callback so we can tell when the user presses + // play on the player controls + ::MCSetActionFilterWithRefCon(m_mc, + wxQTMediaBackend::MCFilterProc, (long)this); +} #endif + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::DoNewMovieController +// +// Attaches movie to moviecontroller or creates moviecontroller +// if not created yet +//--------------------------------------------------------------------------- +#if !wxUSE_CREATEMOVIECONTROL +void wxQTMediaBackend::DoNewMovieController() +{ + if(!m_mc) + { + // Get top level window ref for some mac functions + WindowRef wrTLW = (WindowRef) m_ctrl->MacGetTopLevelWindowRef(); + + // MovieController not setup yet - + // so we need to create a new one. + // You have to pass a valid movie to + // NewMovieController, evidently + ::SetMovieGWorld(m_movie, + (CGrafPtr) GetWindowPort(wrTLW), + NULL); + wxASSERT(::GetMoviesError() == noErr); + + Rect bounds = wxMacGetBoundsForControl(m_ctrl, + m_ctrl->GetPosition(), + m_ctrl->GetSize()); + + m_mc = ::NewMovieController(m_movie, &bounds, mcTopLeftMovie | + //mcWithFrame | + mcNotVisible); + wxASSERT(::GetMoviesError() == noErr); + ::MCDoAction(m_mc, 32, (void*)true); //mcActionSetKeysEnabled + wxASSERT(::GetMoviesError() == noErr); + + // Setup a callback so we can tell when the user presses + // play on the player controls + ::MCSetActionFilterWithRefCon(m_mc, + wxQTMediaBackend::MCFilterProc, (long)this); + wxASSERT(::GetMoviesError() == noErr); + + //Part of a suggestion from Greg Hazel to repaint + //movie when idle + m_ctrl->PushEventHandler(new wxQTMediaEvtHandler(this)); + + // Event types to catch from the TLW + // for the moviecontroller + EventTypeSpec theEventTypes[] = { + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassWindow, kEventWindowUpdate }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated } + }; + + // Catch window messages - + // if we do not do this and if the user clicks the play + // button on the controller, for instance, nothing will happen... + InstallWindowEventHandler( wrTLW, + GetwxQTMediaWindowEventHandlerUPP(), + GetEventTypeCount( theEventTypes ), theEventTypes, + m_mc, (&(EventHandlerRef&)m_pEventHandlerRef) ); + } + else + { + // MovieController already created - + // Just change the movie in it and we're good to go + Point thePoint; + thePoint.h = thePoint.v = 0; + ::MCSetMovie(m_mc, m_movie, + (WindowRef)m_ctrl->MacGetTopLevelWindowRef(), + thePoint); + wxASSERT(::GetMoviesError() == noErr); } +} +#endif + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::FinishLoad +// +// Performs operations after a movie ready to play/loaded. +//--------------------------------------------------------------------------- +void wxQTMediaBackend::FinishLoad() +{ + // get the real size of the movie + DoLoadBestSize(); + + // Show the player controls if the user wants to + if(m_interfaceflags) + DoSetControllerVisible(m_interfaceflags); //we want millisecond precision ::SetMovieTimeScale(m_movie, 1000); wxASSERT(::GetMoviesError() == noErr); - // - //Here, if the parent of the control has a sizer - we - //tell it to recalculate the size of this control since - //the user opened a separate media file - // - m_ctrl->InvalidateBestSize(); - m_ctrl->GetParent()->Layout(); - m_ctrl->GetParent()->Refresh(); - m_ctrl->GetParent()->Update(); - - //send loaded event - wxMediaEvent theEvent(wxEVT_MEDIA_LOADED, - m_ctrl->GetId()); - m_ctrl->AddPendingEvent(theEvent); + // Start movie progress timer + m_timer = new wxQTMediaPlayTimer(m_movie, (wxQTMediaBackend*) this); + wxASSERT(m_timer); + m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); + + //send loaded event & refresh size + NotifyMovieLoaded(); +} + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::DoLoadBestSize +// +// Sets the best size of the control from the real size of the movie +//--------------------------------------------------------------------------- +void wxQTMediaBackend::DoLoadBestSize() +{ + //get the real size of the movie + Rect outRect; + ::GetMovieNaturalBoundsRect (m_movie, &outRect); + wxASSERT(::GetMoviesError() == noErr); + + //determine best size + m_bestSize.x = outRect.right - outRect.left; + m_bestSize.y = outRect.bottom - outRect.top; } //--------------------------------------------------------------------------- // wxQTMediaBackend::Play // -// 1) Start the QT movie -// 2) Start the movie loading timer +// Start the QT movie //--------------------------------------------------------------------------- bool wxQTMediaBackend::Play() { - ::StartMovie(m_movie); - m_timer->SetPaused(false); - m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); + Fixed fixRate = (Fixed) (wxQTMediaBackend::GetPlaybackRate() * 0x10000); + if(!fixRate) + fixRate = ::GetMoviePreferredRate(m_movie); + + wxASSERT(fixRate != 0); + + if(!m_bPlaying) + ::MCDoAction( m_mc, 8, // mcActionPlay + (void *) fixRate); + + m_bPlaying = true; return ::GetMoviesError() == noErr; } //--------------------------------------------------------------------------- // wxQTMediaBackend::Pause // -// 1) Stop the movie -// 2) Stop the movie timer +// Stop the movie //--------------------------------------------------------------------------- bool wxQTMediaBackend::Pause() { - ::StopMovie(m_movie); - m_timer->SetPaused(true); - m_timer->Stop(); + //Stop the movie A.K.A. ::StopMovie(m_movie); + if(m_bPlaying) + { + ::MCDoAction( m_mc, 8 /*mcActionPlay*/, + (void *) 0); + m_bPlaying = false; return ::GetMoviesError() == noErr; + } + return true; //already paused } //--------------------------------------------------------------------------- // wxQTMediaBackend::Stop // // 1) Stop the movie -// 2) Stop the movie timer -// 3) Seek to the beginning of the movie +// 2) Seek to the beginning of the movie //--------------------------------------------------------------------------- bool wxQTMediaBackend::Stop() { - m_timer->SetPaused(false); - m_timer->Stop(); - - ::StopMovie(m_movie); - if(::GetMoviesError() != noErr) + if(!wxQTMediaBackend::Pause()) return false; ::GoToBeginningOfMovie(m_movie); @@ -604,12 +878,12 @@ wxLongLong wxQTMediaBackend::GetPosition() //--------------------------------------------------------------------------- double wxQTMediaBackend::GetVolume() { - short sVolume = GetMovieVolume(m_movie); + short sVolume = ::GetMovieVolume(m_movie); if(sVolume & (128 << 8)) //negative - no sound return 0.0; - return (sVolume & (127 << 8)) ? 1.0 : ((double)(sVolume & 255)) / 255.0; + return sVolume/256.0; } //--------------------------------------------------------------------------- @@ -629,8 +903,7 @@ double wxQTMediaBackend::GetVolume() //--------------------------------------------------------------------------- bool wxQTMediaBackend::SetVolume(double dVolume) { - short sVolume = (short) (dVolume >= .9999 ? 1 << 8 : (dVolume * 255) ); - SetMovieVolume(m_movie, sVolume); + ::SetMovieVolume(m_movie, (short) (dVolume * 256)); return true; } @@ -652,12 +925,13 @@ wxLongLong wxQTMediaBackend::GetDuration() //--------------------------------------------------------------------------- wxMediaState wxQTMediaBackend::GetState() { - if ( !m_timer || (m_timer->IsRunning() == false && - m_timer->GetPaused() == false) ) - return wxMEDIASTATE_STOPPED; - - if( m_timer->IsRunning() ) + // Could use + // GetMovieActive/IsMovieDone/SetMovieActive + // combo if implemented that way + if (m_bPlaying == true) return wxMEDIASTATE_PLAYING; + else if ( !m_movie || wxQTMediaBackend::GetPosition() == 0) + return wxMEDIASTATE_STOPPED; else return wxMEDIASTATE_PAUSED; } @@ -670,15 +944,63 @@ wxMediaState wxQTMediaBackend::GetState() //--------------------------------------------------------------------------- void wxQTMediaBackend::Cleanup() { + m_bPlaying = false; + if(m_timer) + { delete m_timer; m_timer = NULL; + } + // Stop the movie + // Apple samples with CreateMovieControl typically + // install a event handler and do this on the dispose + // event, but we do it here for simplicity + // (It might keep playing for several seconds after + // control destruction if not) + wxQTMediaBackend::Pause(); + + // + // Dispose of control or remove movie from MovieController + // #if wxUSE_CREATEMOVIECONTROL - DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef()); + if (m_ctrl->m_peer && m_ctrl->m_peer->Ok() ) + m_ctrl->m_peer->Dispose(); +#else + Point thePoint; + thePoint.h = thePoint.v = 0; + ::MCSetVisible(m_mc, false); + ::MCSetMovie(m_mc, NULL, NULL, thePoint); #endif - StopMovie(m_movie); - DisposeMovie(m_movie); + ::DisposeMovie(m_movie); +} + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::MCFilterProc (static) +// +// Callback for when the movie controller recieves a message +//--------------------------------------------------------------------------- +Boolean wxQTMediaBackend::MCFilterProc( + MovieController WXUNUSED(theController), + short action, + void * WXUNUSED(params), + long refCon) +{ + if(action != 1) //don't process idle events + { + wxQTMediaBackend* pThis = (wxQTMediaBackend*)refCon; + + switch(action) + { + case 8: //play button triggered - MC will set movie to opposite state + //of current - playing ? paused : playing + pThis->m_bPlaying = !(pThis->m_bPlaying); + break; + default: + break; + } + } + return 0; } //--------------------------------------------------------------------------- @@ -702,14 +1024,10 @@ void wxQTMediaBackend::Move(int x, int y, int w, int h) #if !wxUSE_CREATEMOVIECONTROL if(m_timer) { - if ( m_ctrl ) - { m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y); - } - Rect theRect = {y, x, y+h, x+w}; - ::SetMovieBox(m_movie, &theRect); + ::MCSetControllerBoundsRect(m_mc, &theRect); wxASSERT(::GetMoviesError() == noErr); } #else @@ -724,6 +1042,125 @@ void wxQTMediaBackend::Move(int x, int y, int w, int h) #endif } +//--------------------------------------------------------------------------- +// wxQTMediaBackend::DoSetControllerVisible +// +// Utility function that takes care of showing the moviecontroller +// and showing/hiding the particular controls on it +//--------------------------------------------------------------------------- +void wxQTMediaBackend::DoSetControllerVisible(wxMediaCtrlPlayerControls flags) +{ + ::MCSetVisible(m_mc, TRUE); + + // + // Take care of subcontrols + // + if(::GetMoviesError() == noErr) + { + long mcFlags = 0; + ::MCDoAction(m_mc, 39/*mcActionGetFlags*/, (void*)&mcFlags); + + if(::GetMoviesError() == noErr) + { + mcFlags |= ( //(1<<0)/*mcFlagSuppressMovieFrame*/ | + (1<<3)/*mcFlagsUseWindowPalette*/ + | ((flags & wxMEDIACTRLPLAYERCONTROLS_STEP) + ? 0 : (1<<1)/*mcFlagSuppressStepButtons*/) + | ((flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME) + ? 0 : (1<<2)/*mcFlagSuppressSpeakerButton*/) + // | (1<<4) /*mcFlagDontInvalidate*/ //if we take care of repainting ourselves + ); + ::MCDoAction(m_mc, 38/*mcActionSetFlags*/, (void*)mcFlags); + } + } + + // + //Adjust height and width of best size for movie controller + //if the user wants it shown + // + m_bestSize.x = m_bestSize.x > wxMCWIDTH ? m_bestSize.x : wxMCWIDTH; + m_bestSize.y += wxMCHEIGHT; +} + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::ShowPlayerControls +// +// Shows/Hides subcontrols on the media control +//--------------------------------------------------------------------------- +bool wxQTMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags) +{ + if(!m_mc) + return false; //no movie controller... + + bool bSizeChanged = false; + + //if the controller is visible and we want to hide it do so + if(m_interfaceflags && !flags) + { + bSizeChanged = true; + DoLoadBestSize(); + ::MCSetVisible(m_mc, FALSE); + } + else if(!m_interfaceflags && flags) //show controller if hidden + { + bSizeChanged = true; + DoSetControllerVisible(flags); + } + + //readjust parent sizers + if(bSizeChanged) + { + NotifyMovieSizeChanged(); + + //remember state in case of loading new media + m_interfaceflags = flags; + } + + return ::GetMoviesError() == noErr; +} + +//--------------------------------------------------------------------------- +// wxQTMediaBackend::OnEraseBackground +// +// Suggestion from Greg Hazel to repaint the movie when idle +// (on pause also) +//--------------------------------------------------------------------------- +#if !wxUSE_CREATEMOVIECONTROL +void wxQTMediaEvtHandler::OnEraseBackground(wxEraseEvent& evt) +{ + // Work around Nasty OSX drawing bug - + // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00311.html + WindowRef wrTLW = + (WindowRef) m_qtb->m_ctrl->MacGetTopLevelWindowRef(); + + RgnHandle region = MCGetControllerBoundsRgn(m_qtb->m_mc); + MCInvalidate(m_qtb->m_mc, wrTLW, region); + MCIdle(m_qtb->m_mc); +} +#endif + +//--------------------------------------------------------------------------- +// wxQTMediaWindowEventHandler +// +// Event callback for the top level window of our control that passes +// messages to our moviecontroller so it can recieve mouse clicks etc. +//--------------------------------------------------------------------------- +#if !wxUSE_CREATEMOVIECONTROL +OSStatus wxQTMediaWindowEventHandler(EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, void *inUserData) +{ + EventRecord theEvent; + ConvertEventRefToEventRecord( inEvent, &theEvent ); + OSStatus err; + err = ::MCIsPlayerEvent( (MovieController) inUserData, &theEvent ); + + // pass on to other event handlers if not handled- i.e. wx + if(err) + return noErr; + else + return eventNotHandledErr; +} +#endif //in source file that contains stuff you don't directly use #include "wx/html/forcelnk.h" diff --git a/src/msw/mediactrl.cpp b/src/msw/mediactrl.cpp index 6e4b4538a4..7020198882 100644 --- a/src/msw/mediactrl.cpp +++ b/src/msw/mediactrl.cpp @@ -15,8 +15,6 @@ dynamically loadable...), they have nothing to do with each other and this file is huge and also separate the standard contents from our code itself - - extract ~1000 lines of wxActiveX code in its own file, why does it have - to be here?? */ //=========================================================================== @@ -75,34 +73,6 @@ LRESULT WXDLLIMPEXP_CORE APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, // BACKEND DECLARATIONS //=========================================================================== -// ---------------------------------------------------------------------------- -// common backend base class used by all other backends -// ---------------------------------------------------------------------------- - -class WXDLLIMPEXP_MEDIA wxMediaBackendCommonBase : public wxMediaBackend -{ -public: - // add a pending wxMediaEvent of the given type - void QueueEvent(wxEventType evtType); - - // notify that the movie playback is finished - void QueueFinishEvent() { QueueEvent(wxEVT_MEDIA_FINISHED); } - - // send the stop event and return true if it hasn't been vetoed - bool SendStopEvent(); - -protected: - // call this when the movie size has changed but not because it has just - // been loaded (in this case, call NotifyMovieLoaded() below) - void NotifyMovieSizeChanged(); - - // call this when the movie is fully loaded - void NotifyMovieLoaded(); - - - wxControl *m_ctrl; // parent control -}; - //--------------------------------------------------------------------------- // // wxAMMediaBackend @@ -110,49 +80,9 @@ protected: //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -// COM includes +// wxActiveXContainer - includes all the COM-specific stuff we need //--------------------------------------------------------------------------- -#include "wx/msw/ole/oleutils.h" //wxBasicString, IID etc. -#include "wx/msw/ole/uuid.h" //IID etc.. -#include -#include -#include -#include - -// -// These defines are from another ole header - but its not in the -// latest sdk. Also the ifndef DISPID_READYSTATE is here because at -// least on my machine with the latest sdk olectl.h defines these 3 -// -#ifndef DISPID_READYSTATE - #define DISPID_READYSTATE -525 - #define DISPID_READYSTATECHANGE -609 - #define DISPID_AMBIENT_TRANSFERPRIORITY -728 -#endif - -#define DISPID_AMBIENT_OFFLINEIFNOTCONNECTED -5501 -#define DISPID_AMBIENT_SILENT -5502 - -#ifndef DISPID_AMBIENT_CODEPAGE -# define DISPID_AMBIENT_CODEPAGE -725 -# define DISPID_AMBIENT_CHARSET -727 -#endif - -//--------------------------------------------------------------------------- -// COM compatability definitions -//--------------------------------------------------------------------------- -#ifndef STDMETHODCALLTYPE -#define STDMETHODCALLTYPE __stdcall -#endif -#ifndef STDMETHOD -#define STDMETHOD(funcname) virtual HRESULT STDMETHODCALLTYPE funcname -#endif -#ifndef PURE -#define PURE = 0 -#endif -#ifndef __RPC_FAR -#define __RPC_FAR FAR -#endif +#include "wx/msw/ole/activex.h" //--------------------------------------------------------------------------- // IIDS - used by CoCreateInstance and IUnknown::QueryInterface @@ -900,909 +830,6 @@ struct IBaseFilter : public IMediaFilter STDMETHOD(QueryVendorInfo)(LPWSTR *pVendorInfo) PURE; }; -//--------------------------------------------------------------------------- -// -// wxActiveX (Ryan Norton's version :)) -// wxActiveX is (C) 2003 Lindsay Mathieson -// -//--------------------------------------------------------------------------- -#define WX_DECLARE_AUTOOLE(wxAutoOleInterface, I) \ -class wxAutoOleInterface \ -{ \ - protected: \ - I *m_interface; \ -\ - public: \ - explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {} \ - wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL) \ - { QueryInterface(riid, pUnk); } \ - wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL) \ - { QueryInterface(riid, pDispatch); } \ - wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)\ - { CreateInstance(clsid, riid); }\ - wxAutoOleInterface(const wxAutoOleInterface& ti) : m_interface(NULL)\ - { operator = (ti); }\ -\ - wxAutoOleInterface& operator = (const wxAutoOleInterface& ti)\ - {\ - if (ti.m_interface)\ - ti.m_interface->AddRef();\ - Free();\ - m_interface = ti.m_interface;\ - return *this;\ - }\ -\ - wxAutoOleInterface& operator = (I *&ti)\ - {\ - Free();\ - m_interface = ti;\ - return *this;\ - }\ -\ - ~wxAutoOleInterface() { Free(); }\ -\ - inline void Free()\ - {\ - if (m_interface)\ - m_interface->Release();\ - m_interface = NULL;\ - }\ -\ - HRESULT QueryInterface(REFIID riid, IUnknown *pUnk)\ - {\ - Free();\ - wxASSERT(pUnk != NULL);\ - return pUnk->QueryInterface(riid, (void **) &m_interface);\ - }\ -\ - HRESULT CreateInstance(REFCLSID clsid, REFIID riid)\ - {\ - Free();\ - return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface);\ - }\ -\ - inline operator I *() const {return m_interface;}\ - inline I* operator ->() {return m_interface;}\ - inline I** GetRef() {return &m_interface;}\ - inline bool Ok() const {return m_interface != NULL;}\ -}; - -WX_DECLARE_AUTOOLE(wxAutoIDispatch, IDispatch) -WX_DECLARE_AUTOOLE(wxAutoIOleClientSite, IOleClientSite) -WX_DECLARE_AUTOOLE(wxAutoIUnknown, IUnknown) -WX_DECLARE_AUTOOLE(wxAutoIOleObject, IOleObject) -WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceObject, IOleInPlaceObject) -WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceActiveObject, IOleInPlaceActiveObject) -WX_DECLARE_AUTOOLE(wxAutoIOleDocumentView, IOleDocumentView) -WX_DECLARE_AUTOOLE(wxAutoIViewObject, IViewObject) -WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite) -WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument) -WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit) -WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink) - -class wxActiveX : public wxWindow -{ -public: - wxActiveX(wxWindow * parent, REFIID iid, IUnknown* pUnk); - virtual ~wxActiveX(); - - void OnSize(wxSizeEvent&); - void OnPaint(wxPaintEvent&); - void OnSetFocus(wxFocusEvent&); - void OnKillFocus(wxFocusEvent&); - -protected: - friend class FrameSite; - - wxAutoIDispatch m_Dispatch; - wxAutoIOleClientSite m_clientSite; - wxAutoIUnknown m_ActiveX; - wxAutoIOleObject m_oleObject; - wxAutoIOleInPlaceObject m_oleInPlaceObject; - wxAutoIOleInPlaceActiveObject m_oleInPlaceActiveObject; - wxAutoIOleDocumentView m_docView; - wxAutoIViewObject m_viewObject; - HWND m_oleObjectHWND; - bool m_bAmbientUserMode; - DWORD m_docAdviseCookie; - wxWindow* m_realparent; - - void CreateActiveX(REFIID, IUnknown*); -}; - -#define DECLARE_OLE_UNKNOWN(cls)\ - private:\ - class TAutoInitInt\ - {\ - public:\ - LONG l;\ - TAutoInitInt() : l(0) {}\ - };\ - TAutoInitInt refCount, lockCount;\ - static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\ - public:\ - LONG GetRefCount();\ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\ - ULONG STDMETHODCALLTYPE AddRef();\ - ULONG STDMETHODCALLTYPE Release();\ - ULONG STDMETHODCALLTYPE AddLock();\ - ULONG STDMETHODCALLTYPE ReleaseLock() - -#define DEFINE_OLE_TABLE(cls)\ - LONG cls::GetRefCount() {return refCount.l;}\ - HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\ - {\ - if (! ppvObject)\ - {\ - return E_FAIL;\ - };\ - const char *desc = NULL;\ - cls::_GetInterface(this, iid, ppvObject, desc);\ - if (! *ppvObject)\ - {\ - return E_NOINTERFACE;\ - };\ - ((IUnknown * )(*ppvObject))->AddRef();\ - return S_OK;\ - };\ - ULONG STDMETHODCALLTYPE cls::AddRef()\ - {\ - InterlockedIncrement(&refCount.l);\ - return refCount.l;\ - };\ - ULONG STDMETHODCALLTYPE cls::Release()\ - {\ - if (refCount.l > 0)\ - {\ - InterlockedDecrement(&refCount.l);\ - if (refCount.l == 0)\ - {\ - delete this;\ - return 0;\ - };\ - return refCount.l;\ - }\ - else\ - return 0;\ - }\ - ULONG STDMETHODCALLTYPE cls::AddLock()\ - {\ - InterlockedIncrement(&lockCount.l);\ - return lockCount.l;\ - };\ - ULONG STDMETHODCALLTYPE cls::ReleaseLock()\ - {\ - if (lockCount.l > 0)\ - {\ - InterlockedDecrement(&lockCount.l);\ - return lockCount.l;\ - }\ - else\ - return 0;\ - }\ - DEFINE_OLE_BASE(cls) - -#define DEFINE_OLE_BASE(cls)\ - void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\ - {\ - *_interface = NULL;\ - desc = NULL; - -#define OLE_INTERFACE(_iid, _type)\ - if (IsEqualIID(iid, _iid))\ - {\ - *_interface = (IUnknown *) (_type *) self;\ - desc = # _iid;\ - return;\ - } - -#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face) - -#define OLE_INTERFACE_CUSTOM(func)\ - if (func(self, iid, _interface, desc))\ - {\ - return;\ - } - -#define END_OLE_TABLE\ - } - - -class FrameSite : - public IOleClientSite, - public IOleInPlaceSiteEx, - public IOleInPlaceFrame, - public IOleItemContainer, - public IDispatch, - public IOleCommandTarget, - public IOleDocumentSite, - public IAdviseSink, - public IOleControlSite -{ -private: - DECLARE_OLE_UNKNOWN(FrameSite); - -public: - FrameSite(wxWindow * win, wxActiveX * win2) - { - m_window = win2; - m_bSupportsWindowlessActivation = true; - m_bInPlaceLocked = false; - m_bUIActive = false; - m_bInPlaceActive = false; - m_bWindowless = false; - - m_nAmbientLocale = 0; - m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT); - m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW); - m_bAmbientShowHatching = true; - m_bAmbientShowGrabHandles = true; - m_bAmbientAppearance = true; - - m_hDCBuffer = NULL; - m_hWndParent = (HWND)win->GetHWND(); - } - virtual ~FrameSite(){} - //***************************IDispatch***************************** - HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** , - unsigned int , LCID , - DISPID * ) - { return E_NOTIMPL; } - STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **) - { return E_NOTIMPL; } - HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *) - { return E_NOTIMPL; } - HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID, - WORD wFlags, DISPPARAMS *, - VARIANT * pVarResult, EXCEPINFO *, - unsigned int *) - { - if (!(wFlags & DISPATCH_PROPERTYGET)) - return S_OK; - - if (pVarResult == NULL) - return E_INVALIDARG; - - //The most common case is boolean, use as an initial type - V_VT(pVarResult) = VT_BOOL; - - switch (dispIdMember) - { - case DISPID_AMBIENT_MESSAGEREFLECT: - V_BOOL(pVarResult)= FALSE; - return S_OK; - - case DISPID_AMBIENT_DISPLAYASDEFAULT: - V_BOOL(pVarResult)= TRUE; - return S_OK; - - case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED: - V_BOOL(pVarResult) = TRUE; - return S_OK; - - case DISPID_AMBIENT_SILENT: - V_BOOL(pVarResult)= TRUE; - return S_OK; - - case DISPID_AMBIENT_APPEARANCE: - pVarResult->vt = VT_BOOL; - pVarResult->boolVal = m_bAmbientAppearance; - break; - - case DISPID_AMBIENT_FORECOLOR: - pVarResult->vt = VT_I4; - pVarResult->lVal = (long) m_clrAmbientForeColor; - break; - - case DISPID_AMBIENT_BACKCOLOR: - pVarResult->vt = VT_I4; - pVarResult->lVal = (long) m_clrAmbientBackColor; - break; - - case DISPID_AMBIENT_LOCALEID: - pVarResult->vt = VT_I4; - pVarResult->lVal = (long) m_nAmbientLocale; - break; - - case DISPID_AMBIENT_USERMODE: - pVarResult->vt = VT_BOOL; - pVarResult->boolVal = m_window->m_bAmbientUserMode; - break; - - case DISPID_AMBIENT_SHOWGRABHANDLES: - pVarResult->vt = VT_BOOL; - pVarResult->boolVal = m_bAmbientShowGrabHandles; - break; - - case DISPID_AMBIENT_SHOWHATCHING: - pVarResult->vt = VT_BOOL; - pVarResult->boolVal = m_bAmbientShowHatching; - break; - - default: - return DISP_E_MEMBERNOTFOUND; - } - - return S_OK; - } - - //**************************IOleWindow*************************** - HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd) - { - if (phwnd == NULL) - return E_INVALIDARG; - (*phwnd) = m_hWndParent; - return S_OK; - } - HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL) - {return S_OK;} - //**************************IOleInPlaceUIWindow***************** - HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder) - { - if (lprectBorder == NULL) - return E_INVALIDARG; - return INPLACE_E_NOTOOLSPACE; - } - HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) - { - if (pborderwidths == NULL) - return E_INVALIDARG; - return INPLACE_E_NOTOOLSPACE; - } - HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS) - {return S_OK;} - HRESULT STDMETHODCALLTYPE SetActiveObject( - IOleInPlaceActiveObject *pActiveObject, LPCOLESTR) - { - if (pActiveObject) - pActiveObject->AddRef(); - - m_window->m_oleInPlaceActiveObject = pActiveObject; - return S_OK; - } - - //********************IOleInPlaceFrame************************ - - STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;} - STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;} - STDMETHOD(RemoveMenus)(HMENU){return S_OK;} - STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;} - HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;} - HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD) - { - // TODO: send an event with this id - if (m_window->m_oleInPlaceActiveObject.Ok()) - m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg); - return S_FALSE; - } - - //*******************IOleInPlaceSite************************** - HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;} - HRESULT STDMETHODCALLTYPE OnInPlaceActivate() - { m_bInPlaceActive = true; return S_OK; } - HRESULT STDMETHODCALLTYPE OnUIActivate() - { m_bUIActive = true; return S_OK; } - HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame, - IOleInPlaceUIWindow **ppDoc, - LPRECT lprcPosRect, - LPRECT lprcClipRect, - LPOLEINPLACEFRAMEINFO lpFrameInfo) - { - if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || - lprcClipRect == NULL || lpFrameInfo == NULL) - { - if (ppFrame != NULL) - (*ppFrame) = NULL; - if (ppDoc != NULL) - (*ppDoc) = NULL; - return E_INVALIDARG; - } - - HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame); - if (! SUCCEEDED(hr)) - { - return E_UNEXPECTED; - }; - - hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc); - if (! SUCCEEDED(hr)) - { - (*ppFrame)->Release(); - *ppFrame = NULL; - return E_UNEXPECTED; - }; - - RECT rect; - ::GetClientRect(m_hWndParent, &rect); - if (lprcPosRect) - { - lprcPosRect->left = lprcPosRect->top = 0; - lprcPosRect->right = rect.right; - lprcPosRect->bottom = rect.bottom; - }; - if (lprcClipRect) - { - lprcClipRect->left = lprcClipRect->top = 0; - lprcClipRect->right = rect.right; - lprcClipRect->bottom = rect.bottom; - }; - - memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO)); - lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO); - lpFrameInfo->hwndFrame = m_hWndParent; - - return S_OK; - } - HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;} - HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL) - { m_bUIActive = false; return S_OK; } - HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() - { m_bInPlaceActive = false; return S_OK; } - HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;} - HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; } - HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect) - { - if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect) - { - m_window->m_oleInPlaceObject->SetObjectRects( - lprcPosRect, lprcPosRect); - } - return S_OK; - } - //*************************IOleInPlaceSiteEx*********************** - HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD) - { - OleLockRunning(m_window->m_ActiveX, TRUE, FALSE); - if (pfNoRedraw) - (*pfNoRedraw) = FALSE; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL) - { - OleLockRunning(m_window->m_ActiveX, FALSE, FALSE); - return S_OK; - } - STDMETHOD(RequestUIActivate)(){ return S_OK;} - //*************************IOleClientSite************************** - HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;} - const char *OleGetMonikerToStr(DWORD dwAssign) - { - switch (dwAssign) - { - case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE"; - case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN"; - case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN"; - case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER"; - default : return "Bad Enum"; - }; - }; - - const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker) - { - switch(dwWhichMoniker) - { - case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER"; - case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL"; - case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL"; - default : return "Bad Enum"; - }; - }; - STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;} - HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer) - { - if (ppContainer == NULL) - return E_INVALIDARG; - HRESULT hr = QueryInterface( - IID_IOleContainer, (void**)(ppContainer)); - wxASSERT(SUCCEEDED(hr)); - return hr; - } - HRESULT STDMETHODCALLTYPE ShowObject() - { - if (m_window->m_oleObjectHWND) - ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW); - return S_OK; - } - STDMETHOD(OnShowWindow)(BOOL){return S_OK;} - STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;} - //********************IParseDisplayName*************************** - HRESULT STDMETHODCALLTYPE ParseDisplayName( - IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;} - //********************IOleContainer******************************* - STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;} - HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;} - //********************IOleItemContainer*************************** - HRESULT STDMETHODCALLTYPE - #ifdef _UNICODE - GetObjectW - #else - GetObjectA - #endif - (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject) - { - if (pszItem == NULL || ppvObject == NULL) - return E_INVALIDARG; - *ppvObject = NULL; - return MK_E_NOOBJECT; - } - HRESULT STDMETHODCALLTYPE GetObjectStorage( - LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage) - { - if (pszItem == NULL || ppvStorage == NULL) - return E_INVALIDARG; - *ppvStorage = NULL; - return MK_E_NOOBJECT; - } - HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem) - { - if (pszItem == NULL) - return E_INVALIDARG; - return MK_E_NOOBJECT; - } - //***********************IOleControlSite***************************** - HRESULT STDMETHODCALLTYPE OnControlInfoChanged() - {return S_OK;} - HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock) - { - m_bInPlaceLocked = (fLock) ? true : false; - return S_OK; - } - HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **) - {return E_NOTIMPL;} - HRESULT STDMETHODCALLTYPE TransformCoords( - POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD) - { - if (pPtlHimetric == NULL || pPtfContainer == NULL) - return E_INVALIDARG; - return E_NOTIMPL; - } - HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD) - {return E_NOTIMPL;} - HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;} - HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;} - //**************************IOleCommandTarget*********************** - HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds, - OLECMD prgCmds[], OLECMDTEXT *) - { - if (prgCmds == NULL) return E_INVALIDARG; - for (ULONG nCmd = 0; nCmd < cCmds; nCmd++) - { - // unsupported by default - prgCmds[nCmd].cmdf = 0; - } - return OLECMDERR_E_UNKNOWNGROUP; - } - - HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD, - DWORD, VARIANTARG *, VARIANTARG *) - {return OLECMDERR_E_NOTSUPPORTED;} - - //**********************IAdviseSink************************************ - void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {} - void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {} - void STDMETHODCALLTYPE OnRename(IMoniker *){} - void STDMETHODCALLTYPE OnSave(){} - void STDMETHODCALLTYPE OnClose(){} - - //**********************IOleDocumentSite*************************** - HRESULT STDMETHODCALLTYPE ActivateMe( - IOleDocumentView __RPC_FAR *pViewToActivate) - { - wxAutoIOleInPlaceSite inPlaceSite( - IID_IOleInPlaceSite, (IDispatch *) this); - if (!inPlaceSite.Ok()) - return E_FAIL; - - if (pViewToActivate) - { - m_window->m_docView = pViewToActivate; - m_window->m_docView->SetInPlaceSite(inPlaceSite); - } - else - { - wxAutoIOleDocument oleDoc( - IID_IOleDocument, m_window->m_oleObject); - if (! oleDoc.Ok()) - return E_FAIL; - - HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, - 0, m_window->m_docView.GetRef()); - if (hr != S_OK) - return E_FAIL; - - m_window->m_docView->SetInPlaceSite(inPlaceSite); - }; - - m_window->m_docView->UIActivate(TRUE); - return S_OK; - }; - - -protected: - wxActiveX * m_window; - - HDC m_hDCBuffer; - HWND m_hWndParent; - - bool m_bSupportsWindowlessActivation; - bool m_bInPlaceLocked; - bool m_bInPlaceActive; - bool m_bUIActive; - bool m_bWindowless; - - LCID m_nAmbientLocale; - COLORREF m_clrAmbientForeColor; - COLORREF m_clrAmbientBackColor; - bool m_bAmbientShowHatching; - bool m_bAmbientShowGrabHandles; - bool m_bAmbientAppearance; -}; - -DEFINE_OLE_TABLE(FrameSite) - OLE_INTERFACE(IID_IUnknown, IOleClientSite) - OLE_IINTERFACE(IOleClientSite) - OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite) - OLE_IINTERFACE(IOleInPlaceSite) - OLE_IINTERFACE(IOleInPlaceSiteEx) - OLE_IINTERFACE(IOleInPlaceUIWindow) - OLE_IINTERFACE(IOleInPlaceFrame) - OLE_IINTERFACE(IParseDisplayName) - OLE_IINTERFACE(IOleContainer) - OLE_IINTERFACE(IOleItemContainer) - OLE_IINTERFACE(IDispatch) - OLE_IINTERFACE(IOleCommandTarget) - OLE_IINTERFACE(IOleDocumentSite) - OLE_IINTERFACE(IAdviseSink) - OLE_IINTERFACE(IOleControlSite) -END_OLE_TABLE; - - -wxActiveX::wxActiveX(wxWindow * parent, REFIID iid, IUnknown* pUnk) - : m_realparent(parent) -{ - m_bAmbientUserMode = true; - m_docAdviseCookie = 0; - CreateActiveX(iid, pUnk); -} - -wxActiveX::~wxActiveX() -{ - // disconnect connection points - if (m_oleInPlaceObject.Ok()) - { - m_oleInPlaceObject->InPlaceDeactivate(); - m_oleInPlaceObject->UIDeactivate(); - } - - if (m_oleObject.Ok()) - { - if (m_docAdviseCookie != 0) - m_oleObject->Unadvise(m_docAdviseCookie); - - m_oleObject->DoVerb( - OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL); - m_oleObject->Close(OLECLOSE_NOSAVE); - m_oleObject->SetClientSite(NULL); - } -} - -void wxActiveX::CreateActiveX(REFIID iid, IUnknown* pUnk) -{ - HRESULT hret; - hret = m_ActiveX.QueryInterface(iid, pUnk); - wxASSERT(SUCCEEDED(hret)); - - // FrameSite - FrameSite *frame = new FrameSite(m_realparent, this); - // oleClientSite - hret = m_clientSite.QueryInterface( - IID_IOleClientSite, (IDispatch *) frame); - wxASSERT(SUCCEEDED(hret)); - // adviseSink - wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame); - wxASSERT(adviseSink.Ok()); - - // Get Dispatch interface - hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX); - - // Get IOleObject interface - hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); - wxASSERT(SUCCEEDED(hret)); - - // get IViewObject Interface - hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); - wxASSERT(SUCCEEDED(hret)); - - // document advise - m_docAdviseCookie = 0; - hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie); - m_oleObject->SetHostNames(L"wxActiveXContainer", NULL); - OleSetContainedObject(m_oleObject, TRUE); - OleRun(m_oleObject); - - - // Get IOleInPlaceObject interface - hret = m_oleInPlaceObject.QueryInterface( - IID_IOleInPlaceObject, m_ActiveX); - wxASSERT(SUCCEEDED(hret)); - - // status - DWORD dwMiscStatus; - m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus); - wxASSERT(SUCCEEDED(hret)); - - // set client site first ? - if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) - m_oleObject->SetClientSite(m_clientSite); - - - // stream init - wxAutoIPersistStreamInit - pPersistStreamInit(IID_IPersistStreamInit, m_oleObject); - - if (pPersistStreamInit.Ok()) - { - hret = pPersistStreamInit->InitNew(); - } - - if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) - m_oleObject->SetClientSite(m_clientSite); - - - RECT posRect; - ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect); - - m_oleObjectHWND = 0; - - if (m_oleInPlaceObject.Ok()) - { - hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); - if (SUCCEEDED(hret)) - ::SetActiveWindow(m_oleObjectHWND); - } - - - if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) - { - if (posRect.right > 0 && posRect.bottom > 0 && - m_oleInPlaceObject.Ok()) - m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); - - hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, - m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect); - hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, - (HWND)m_realparent->GetHWND(), &posRect); - } - - if (! m_oleObjectHWND && m_oleInPlaceObject.Ok()) - { - hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); - } - - if (m_oleObjectHWND) - { - ::SetActiveWindow(m_oleObjectHWND); - ::ShowWindow(m_oleObjectHWND, SW_SHOW); - - this->AssociateHandle(m_oleObjectHWND); - this->Reparent(m_realparent); - - wxWindow* pWnd = m_realparent; - int id = m_realparent->GetId(); - - pWnd->Connect(id, wxEVT_SIZE, - wxSizeEventHandler(wxActiveX::OnSize), 0, this); - pWnd->Connect(id, wxEVT_SET_FOCUS, - wxFocusEventHandler(wxActiveX::OnSetFocus), 0, this); - pWnd->Connect(id, wxEVT_KILL_FOCUS, - wxFocusEventHandler(wxActiveX::OnKillFocus), 0, this); - } -} - -#define HIMETRIC_PER_INCH 2540 -#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) - -static void PixelsToHimetric(SIZEL &sz) -{ - static int logX = 0; - static int logY = 0; - - if (logY == 0) - { - // initaliase - HDC dc = GetDC(NULL); - logX = GetDeviceCaps(dc, LOGPIXELSX); - logY = GetDeviceCaps(dc, LOGPIXELSY); - ReleaseDC(NULL, dc); - }; - -#define HIMETRIC_INCH 2540 -#define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels)) - - sz.cx = CONVERT(sz.cx, logX); - sz.cy = CONVERT(sz.cy, logY); - -#undef CONVERT -#undef HIMETRIC_INCH -} - - -void wxActiveX::OnSize(wxSizeEvent& event) -{ - int w, h; - GetParent()->GetClientSize(&w, &h); - - RECT posRect; - posRect.left = 0; - posRect.top = 0; - posRect.right = w; - posRect.bottom = h; - - if (w <= 0 && h <= 0) - return; - - // extents are in HIMETRIC units - if (m_oleObject.Ok()) - { - SIZEL sz = {w, h}; - PixelsToHimetric(sz); - - SIZEL sz2; - - m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2); - if (sz2.cx != sz.cx || sz.cy != sz2.cy) - m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); - }; - - if (m_oleInPlaceObject.Ok()) - m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); - - event.Skip(); -} - -void wxActiveX::OnPaint(wxPaintEvent& WXUNUSED(event)) -{ - wxPaintDC dc(this); - // Draw only when control is windowless or deactivated - if (m_viewObject) - { - dc.BeginDrawing(); - int w, h; - GetParent()->GetSize(&w, &h); - RECT posRect; - posRect.left = 0; - posRect.top = 0; - posRect.right = w; - posRect.bottom = h; - - ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT); - RECTL *prcBounds = (RECTL *) &posRect; - m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, - (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0); - - dc.EndDrawing(); - } - -// We've got this one I think -// event.Skip(); -} - -void wxActiveX::OnSetFocus(wxFocusEvent& event) -{ - if (m_oleInPlaceActiveObject.Ok()) - m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE); - - event.Skip(); -} - -void wxActiveX::OnKillFocus(wxFocusEvent& event) -{ - if (m_oleInPlaceActiveObject.Ok()) - m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE); - - event.Skip(); -} //########################################################################### // @@ -1872,7 +899,7 @@ public: return total; } - wxActiveX* m_pAX; + wxActiveXContainer* m_pAX; IActiveMovie* m_pAM; IMediaPlayer* m_pMP; wxTimer* m_pTimer; @@ -2313,6 +1340,7 @@ public: wxQuickTimeLibrary m_lib; //DLL to load functions from ComponentInstance m_pMC; //Movie Controller + friend class wxQTMediaEvtHandler; DECLARE_DYNAMIC_CLASS(wxQTMediaBackend) }; @@ -2324,6 +1352,12 @@ public: { m_qtb = qtb; m_hwnd = hwnd; + + m_qtb->m_ctrl->Connect(m_qtb->m_ctrl->GetId(), + wxEVT_ERASE_BACKGROUND, + wxEraseEventHandler(wxQTMediaEvtHandler::OnEraseBackground), + NULL, this + ); } void OnEraseBackground(wxEraseEvent& event); @@ -2340,47 +1374,6 @@ private: // IMPLEMENTATION //=========================================================================== -// ---------------------------------------------------------------------------- -// wxMediaBackendCommonBase -// ---------------------------------------------------------------------------- - -void wxMediaBackendCommonBase::NotifyMovieSizeChanged() -{ - // our best size changed after opening a new file - m_ctrl->InvalidateBestSize(); - m_ctrl->SetSize(m_ctrl->GetSize()); - - // if the parent of the control has a sizer ask it to refresh our size - wxWindow * const parent = m_ctrl->GetParent(); - if ( parent->GetSizer() ) - { - m_ctrl->GetParent()->Layout(); - m_ctrl->GetParent()->Refresh(); - m_ctrl->GetParent()->Update(); - } -} - -void wxMediaBackendCommonBase::NotifyMovieLoaded() -{ - NotifyMovieSizeChanged(); - - // notify about movie being fully loaded - QueueEvent(wxEVT_MEDIA_LOADED); -} - -bool wxMediaBackendCommonBase::SendStopEvent() -{ - wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId()); - - return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed(); -} - -void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType) -{ - wxMediaEvent theEvent(evtType, m_ctrl->GetId()); - m_ctrl->AddPendingEvent(theEvent); -} - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // wxAMMediaBackend @@ -2697,8 +1690,8 @@ bool wxAMMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, // Now create the ActiveX container along with the media player // interface and query them // - m_ctrl = ctrl; - m_pAX = new wxActiveX(ctrl, + m_ctrl = wxStaticCast(ctrl, wxMediaCtrl); + m_pAX = new wxActiveXContainer(ctrl, m_pMP ? IID_IMediaPlayer : IID_IActiveMovie, m_pAM); @@ -3311,7 +2304,7 @@ bool wxMCIMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, validator, name) ) return false; - m_ctrl = ctrl; + m_ctrl = wxStaticCast(ctrl, wxMediaCtrl); return true; } @@ -3930,7 +2923,7 @@ bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, return false; - m_ctrl = ctrl; //assign the control to our member + m_ctrl = wxStaticCast(ctrl, wxMediaCtrl); // Create a port association for our window so we // can use it as a WindowRef diff --git a/src/msw/ole/activex.cpp b/src/msw/ole/activex.cpp new file mode 100644 index 0000000000..8dea8ef980 --- /dev/null +++ b/src/msw/ole/activex.cpp @@ -0,0 +1,824 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: msw/ole/activex.cpp +// Purpose: wxActiveXContainer implementation +// Author: Ryan Norton , Lindsay Mathieson +// Modified by: +// Created: 11/07/04 +// RCS-ID: $Id$ +// Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +//=========================================================================== +// DECLARATIONS +//=========================================================================== + +//--------------------------------------------------------------------------- +// WX include +//--------------------------------------------------------------------------- +#include "wx/wxprec.h" + +#include "wx/msw/ole/activex.h" + + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +// wxActiveXContainer +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#define DECLARE_OLE_UNKNOWN(cls)\ + private:\ + class TAutoInitInt\ + {\ + public:\ + LONG l;\ + TAutoInitInt() : l(0) {}\ + };\ + TAutoInitInt refCount, lockCount;\ + static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\ + public:\ + LONG GetRefCount();\ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\ + ULONG STDMETHODCALLTYPE AddRef();\ + ULONG STDMETHODCALLTYPE Release();\ + ULONG STDMETHODCALLTYPE AddLock();\ + ULONG STDMETHODCALLTYPE ReleaseLock() + +#define DEFINE_OLE_TABLE(cls)\ + LONG cls::GetRefCount() {return refCount.l;}\ + HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\ + {\ + if (! ppvObject)\ + {\ + return E_FAIL;\ + };\ + const char *desc = NULL;\ + cls::_GetInterface(this, iid, ppvObject, desc);\ + if (! *ppvObject)\ + {\ + return E_NOINTERFACE;\ + };\ + ((IUnknown * )(*ppvObject))->AddRef();\ + return S_OK;\ + };\ + ULONG STDMETHODCALLTYPE cls::AddRef()\ + {\ + InterlockedIncrement(&refCount.l);\ + return refCount.l;\ + };\ + ULONG STDMETHODCALLTYPE cls::Release()\ + {\ + if (refCount.l > 0)\ + {\ + InterlockedDecrement(&refCount.l);\ + if (refCount.l == 0)\ + {\ + delete this;\ + return 0;\ + };\ + return refCount.l;\ + }\ + else\ + return 0;\ + }\ + ULONG STDMETHODCALLTYPE cls::AddLock()\ + {\ + InterlockedIncrement(&lockCount.l);\ + return lockCount.l;\ + };\ + ULONG STDMETHODCALLTYPE cls::ReleaseLock()\ + {\ + if (lockCount.l > 0)\ + {\ + InterlockedDecrement(&lockCount.l);\ + return lockCount.l;\ + }\ + else\ + return 0;\ + }\ + DEFINE_OLE_BASE(cls) + +#define DEFINE_OLE_BASE(cls)\ + void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\ + {\ + *_interface = NULL;\ + desc = NULL; + +#define OLE_INTERFACE(_iid, _type)\ + if (IsEqualIID(iid, _iid))\ + {\ + *_interface = (IUnknown *) (_type *) self;\ + desc = # _iid;\ + return;\ + } + +#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face) + +#define OLE_INTERFACE_CUSTOM(func)\ + if (func(self, iid, _interface, desc))\ + {\ + return;\ + } + +#define END_OLE_TABLE\ + } + + +class FrameSite : + public IOleClientSite, + public IOleInPlaceSiteEx, + public IOleInPlaceFrame, + public IOleItemContainer, + public IDispatch, + public IOleCommandTarget, + public IOleDocumentSite, + public IAdviseSink, + public IOleControlSite +{ +private: + DECLARE_OLE_UNKNOWN(FrameSite); + +public: + FrameSite(wxWindow * win, wxActiveXContainer * win2) + { + m_window = win2; + m_bSupportsWindowlessActivation = true; + m_bInPlaceLocked = false; + m_bUIActive = false; + m_bInPlaceActive = false; + m_bWindowless = false; + + m_nAmbientLocale = 0; + m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT); + m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW); + m_bAmbientShowHatching = true; + m_bAmbientShowGrabHandles = true; + m_bAmbientAppearance = true; + + m_hDCBuffer = NULL; + m_hWndParent = (HWND)win->GetHWND(); + } + virtual ~FrameSite(){} + //***************************IDispatch***************************** + HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** , + unsigned int , LCID , + DISPID * ) + { return E_NOTIMPL; } + STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **) + { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *) + { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID, + WORD wFlags, DISPPARAMS *, + VARIANT * pVarResult, EXCEPINFO *, + unsigned int *) + { + if (!(wFlags & DISPATCH_PROPERTYGET)) + return S_OK; + + if (pVarResult == NULL) + return E_INVALIDARG; + + //The most common case is boolean, use as an initial type + V_VT(pVarResult) = VT_BOOL; + + switch (dispIdMember) + { + case DISPID_AMBIENT_MESSAGEREFLECT: + V_BOOL(pVarResult)= FALSE; + return S_OK; + + case DISPID_AMBIENT_DISPLAYASDEFAULT: + V_BOOL(pVarResult)= TRUE; + return S_OK; + + case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED: + V_BOOL(pVarResult) = TRUE; + return S_OK; + + case DISPID_AMBIENT_SILENT: + V_BOOL(pVarResult)= TRUE; + return S_OK; + + case DISPID_AMBIENT_APPEARANCE: + pVarResult->vt = VT_BOOL; + pVarResult->boolVal = m_bAmbientAppearance; + break; + + case DISPID_AMBIENT_FORECOLOR: + pVarResult->vt = VT_I4; + pVarResult->lVal = (long) m_clrAmbientForeColor; + break; + + case DISPID_AMBIENT_BACKCOLOR: + pVarResult->vt = VT_I4; + pVarResult->lVal = (long) m_clrAmbientBackColor; + break; + + case DISPID_AMBIENT_LOCALEID: + pVarResult->vt = VT_I4; + pVarResult->lVal = (long) m_nAmbientLocale; + break; + + case DISPID_AMBIENT_USERMODE: + pVarResult->vt = VT_BOOL; + pVarResult->boolVal = m_window->m_bAmbientUserMode; + break; + + case DISPID_AMBIENT_SHOWGRABHANDLES: + pVarResult->vt = VT_BOOL; + pVarResult->boolVal = m_bAmbientShowGrabHandles; + break; + + case DISPID_AMBIENT_SHOWHATCHING: + pVarResult->vt = VT_BOOL; + pVarResult->boolVal = m_bAmbientShowHatching; + break; + + default: + return DISP_E_MEMBERNOTFOUND; + } + + return S_OK; + } + + //**************************IOleWindow*************************** + HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd) + { + if (phwnd == NULL) + return E_INVALIDARG; + (*phwnd) = m_hWndParent; + return S_OK; + } + HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL) + {return S_OK;} + //**************************IOleInPlaceUIWindow***************** + HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder) + { + if (lprectBorder == NULL) + return E_INVALIDARG; + return INPLACE_E_NOTOOLSPACE; + } + HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) + { + if (pborderwidths == NULL) + return E_INVALIDARG; + return INPLACE_E_NOTOOLSPACE; + } + HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS) + {return S_OK;} + HRESULT STDMETHODCALLTYPE SetActiveObject( + IOleInPlaceActiveObject *pActiveObject, LPCOLESTR) + { + if (pActiveObject) + pActiveObject->AddRef(); + + m_window->m_oleInPlaceActiveObject = pActiveObject; + return S_OK; + } + + //********************IOleInPlaceFrame************************ + + STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;} + STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;} + STDMETHOD(RemoveMenus)(HMENU){return S_OK;} + STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;} + HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;} + HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD) + { + // TODO: send an event with this id + if (m_window->m_oleInPlaceActiveObject.Ok()) + m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg); + return S_FALSE; + } + + //*******************IOleInPlaceSite************************** + HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;} + HRESULT STDMETHODCALLTYPE OnInPlaceActivate() + { m_bInPlaceActive = true; return S_OK; } + HRESULT STDMETHODCALLTYPE OnUIActivate() + { m_bUIActive = true; return S_OK; } + HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame, + IOleInPlaceUIWindow **ppDoc, + LPRECT lprcPosRect, + LPRECT lprcClipRect, + LPOLEINPLACEFRAMEINFO lpFrameInfo) + { + if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || + lprcClipRect == NULL || lpFrameInfo == NULL) + { + if (ppFrame != NULL) + (*ppFrame) = NULL; + if (ppDoc != NULL) + (*ppDoc) = NULL; + return E_INVALIDARG; + } + + HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame); + if (! SUCCEEDED(hr)) + { + return E_UNEXPECTED; + }; + + hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc); + if (! SUCCEEDED(hr)) + { + (*ppFrame)->Release(); + *ppFrame = NULL; + return E_UNEXPECTED; + }; + + RECT rect; + ::GetClientRect(m_hWndParent, &rect); + if (lprcPosRect) + { + lprcPosRect->left = lprcPosRect->top = 0; + lprcPosRect->right = rect.right; + lprcPosRect->bottom = rect.bottom; + }; + if (lprcClipRect) + { + lprcClipRect->left = lprcClipRect->top = 0; + lprcClipRect->right = rect.right; + lprcClipRect->bottom = rect.bottom; + }; + + memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO)); + lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO); + lpFrameInfo->hwndFrame = m_hWndParent; + + return S_OK; + } + HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;} + HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL) + { m_bUIActive = false; return S_OK; } + HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() + { m_bInPlaceActive = false; return S_OK; } + HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;} + HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; } + HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect) + { + if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect) + { + m_window->m_oleInPlaceObject->SetObjectRects( + lprcPosRect, lprcPosRect); + } + return S_OK; + } + //*************************IOleInPlaceSiteEx*********************** + HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD) + { + OleLockRunning(m_window->m_ActiveX, TRUE, FALSE); + if (pfNoRedraw) + (*pfNoRedraw) = FALSE; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL) + { + OleLockRunning(m_window->m_ActiveX, FALSE, FALSE); + return S_OK; + } + STDMETHOD(RequestUIActivate)(){ return S_OK;} + //*************************IOleClientSite************************** + HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;} + const char *OleGetMonikerToStr(DWORD dwAssign) + { + switch (dwAssign) + { + case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE"; + case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN"; + case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN"; + case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER"; + default : return "Bad Enum"; + }; + }; + + const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker) + { + switch(dwWhichMoniker) + { + case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER"; + case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL"; + case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL"; + default : return "Bad Enum"; + }; + }; + STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;} + HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer) + { + if (ppContainer == NULL) + return E_INVALIDARG; + HRESULT hr = QueryInterface( + IID_IOleContainer, (void**)(ppContainer)); + wxASSERT(SUCCEEDED(hr)); + return hr; + } + HRESULT STDMETHODCALLTYPE ShowObject() + { + if (m_window->m_oleObjectHWND) + ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW); + return S_OK; + } + STDMETHOD(OnShowWindow)(BOOL){return S_OK;} + STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;} + //********************IParseDisplayName*************************** + HRESULT STDMETHODCALLTYPE ParseDisplayName( + IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;} + //********************IOleContainer******************************* + STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;} + HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;} + //********************IOleItemContainer*************************** + HRESULT STDMETHODCALLTYPE + #ifdef _UNICODE + GetObjectW + #else + GetObjectA + #endif + (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject) + { + if (pszItem == NULL || ppvObject == NULL) + return E_INVALIDARG; + *ppvObject = NULL; + return MK_E_NOOBJECT; + } + HRESULT STDMETHODCALLTYPE GetObjectStorage( + LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage) + { + if (pszItem == NULL || ppvStorage == NULL) + return E_INVALIDARG; + *ppvStorage = NULL; + return MK_E_NOOBJECT; + } + HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem) + { + if (pszItem == NULL) + return E_INVALIDARG; + return MK_E_NOOBJECT; + } + //***********************IOleControlSite***************************** + HRESULT STDMETHODCALLTYPE OnControlInfoChanged() + {return S_OK;} + HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock) + { + m_bInPlaceLocked = (fLock) ? true : false; + return S_OK; + } + HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **) + {return E_NOTIMPL;} + HRESULT STDMETHODCALLTYPE TransformCoords( + POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD) + { + if (pPtlHimetric == NULL || pPtfContainer == NULL) + return E_INVALIDARG; + return E_NOTIMPL; + } + HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD) + {return E_NOTIMPL;} + HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;} + HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;} + //**************************IOleCommandTarget*********************** + HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds, + OLECMD prgCmds[], OLECMDTEXT *) + { + if (prgCmds == NULL) return E_INVALIDARG; + for (ULONG nCmd = 0; nCmd < cCmds; nCmd++) + { + // unsupported by default + prgCmds[nCmd].cmdf = 0; + } + return OLECMDERR_E_UNKNOWNGROUP; + } + + HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD, + DWORD, VARIANTARG *, VARIANTARG *) + {return OLECMDERR_E_NOTSUPPORTED;} + + //**********************IAdviseSink************************************ + void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {} + void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {} + void STDMETHODCALLTYPE OnRename(IMoniker *){} + void STDMETHODCALLTYPE OnSave(){} + void STDMETHODCALLTYPE OnClose(){} + + //**********************IOleDocumentSite*************************** + HRESULT STDMETHODCALLTYPE ActivateMe( + IOleDocumentView __RPC_FAR *pViewToActivate) + { + wxAutoIOleInPlaceSite inPlaceSite( + IID_IOleInPlaceSite, (IDispatch *) this); + if (!inPlaceSite.Ok()) + return E_FAIL; + + if (pViewToActivate) + { + m_window->m_docView = pViewToActivate; + m_window->m_docView->SetInPlaceSite(inPlaceSite); + } + else + { + wxAutoIOleDocument oleDoc( + IID_IOleDocument, m_window->m_oleObject); + if (! oleDoc.Ok()) + return E_FAIL; + + HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, + 0, m_window->m_docView.GetRef()); + if (hr != S_OK) + return E_FAIL; + + m_window->m_docView->SetInPlaceSite(inPlaceSite); + }; + + m_window->m_docView->UIActivate(TRUE); + return S_OK; + }; + + +protected: + wxActiveXContainer * m_window; + + HDC m_hDCBuffer; + HWND m_hWndParent; + + bool m_bSupportsWindowlessActivation; + bool m_bInPlaceLocked; + bool m_bInPlaceActive; + bool m_bUIActive; + bool m_bWindowless; + + LCID m_nAmbientLocale; + COLORREF m_clrAmbientForeColor; + COLORREF m_clrAmbientBackColor; + bool m_bAmbientShowHatching; + bool m_bAmbientShowGrabHandles; + bool m_bAmbientAppearance; +}; + +DEFINE_OLE_TABLE(FrameSite) + OLE_INTERFACE(IID_IUnknown, IOleClientSite) + OLE_IINTERFACE(IOleClientSite) + OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite) + OLE_IINTERFACE(IOleInPlaceSite) + OLE_IINTERFACE(IOleInPlaceSiteEx) + OLE_IINTERFACE(IOleInPlaceUIWindow) + OLE_IINTERFACE(IOleInPlaceFrame) + OLE_IINTERFACE(IParseDisplayName) + OLE_IINTERFACE(IOleContainer) + OLE_IINTERFACE(IOleItemContainer) + OLE_IINTERFACE(IDispatch) + OLE_IINTERFACE(IOleCommandTarget) + OLE_IINTERFACE(IOleDocumentSite) + OLE_IINTERFACE(IAdviseSink) + OLE_IINTERFACE(IOleControlSite) +END_OLE_TABLE; + + +wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk) + : m_realparent(parent) +{ + m_bAmbientUserMode = true; + m_docAdviseCookie = 0; + CreateActiveX(iid, pUnk); +} + +wxActiveXContainer::~wxActiveXContainer() +{ + // disconnect connection points + if (m_oleInPlaceObject.Ok()) + { + m_oleInPlaceObject->InPlaceDeactivate(); + m_oleInPlaceObject->UIDeactivate(); + } + + if (m_oleObject.Ok()) + { + if (m_docAdviseCookie != 0) + m_oleObject->Unadvise(m_docAdviseCookie); + + m_oleObject->DoVerb( + OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL); + m_oleObject->Close(OLECLOSE_NOSAVE); + m_oleObject->SetClientSite(NULL); + } +} + +void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk) +{ + HRESULT hret; + hret = m_ActiveX.QueryInterface(iid, pUnk); + wxASSERT(SUCCEEDED(hret)); + + // FrameSite + FrameSite *frame = new FrameSite(m_realparent, this); + // oleClientSite + hret = m_clientSite.QueryInterface( + IID_IOleClientSite, (IDispatch *) frame); + wxASSERT(SUCCEEDED(hret)); + // adviseSink + wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame); + wxASSERT(adviseSink.Ok()); + + // Get Dispatch interface + hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX); + + // Get IOleObject interface + hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); + wxASSERT(SUCCEEDED(hret)); + + // get IViewObject Interface + hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); + wxASSERT(SUCCEEDED(hret)); + + // document advise + m_docAdviseCookie = 0; + hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie); + m_oleObject->SetHostNames(L"wxActiveXContainer", NULL); + OleSetContainedObject(m_oleObject, TRUE); + OleRun(m_oleObject); + + + // Get IOleInPlaceObject interface + hret = m_oleInPlaceObject.QueryInterface( + IID_IOleInPlaceObject, m_ActiveX); + wxASSERT(SUCCEEDED(hret)); + + // status + DWORD dwMiscStatus; + m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus); + wxASSERT(SUCCEEDED(hret)); + + // set client site first ? + if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) + m_oleObject->SetClientSite(m_clientSite); + + + // stream init + wxAutoIPersistStreamInit + pPersistStreamInit(IID_IPersistStreamInit, m_oleObject); + + if (pPersistStreamInit.Ok()) + { + hret = pPersistStreamInit->InitNew(); + } + + if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) + m_oleObject->SetClientSite(m_clientSite); + + + RECT posRect; + ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect); + + m_oleObjectHWND = 0; + + if (m_oleInPlaceObject.Ok()) + { + hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); + if (SUCCEEDED(hret)) + ::SetActiveWindow(m_oleObjectHWND); + } + + + if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) + { + if (posRect.right > 0 && posRect.bottom > 0 && + m_oleInPlaceObject.Ok()) + m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); + + hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, + m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect); + hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, + (HWND)m_realparent->GetHWND(), &posRect); + } + + if (! m_oleObjectHWND && m_oleInPlaceObject.Ok()) + { + hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); + } + + if (m_oleObjectHWND) + { + ::SetActiveWindow(m_oleObjectHWND); + ::ShowWindow(m_oleObjectHWND, SW_SHOW); + + this->AssociateHandle(m_oleObjectHWND); + this->Reparent(m_realparent); + + wxWindow* pWnd = m_realparent; + int id = m_realparent->GetId(); + + pWnd->Connect(id, wxEVT_SIZE, + wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this); + pWnd->Connect(id, wxEVT_SET_FOCUS, + wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this); + pWnd->Connect(id, wxEVT_KILL_FOCUS, + wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this); + } +} + +#define HIMETRIC_PER_INCH 2540 +#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) + +static void PixelsToHimetric(SIZEL &sz) +{ + static int logX = 0; + static int logY = 0; + + if (logY == 0) + { + // initaliase + HDC dc = GetDC(NULL); + logX = GetDeviceCaps(dc, LOGPIXELSX); + logY = GetDeviceCaps(dc, LOGPIXELSY); + ReleaseDC(NULL, dc); + }; + +#define HIMETRIC_INCH 2540 +#define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels)) + + sz.cx = CONVERT(sz.cx, logX); + sz.cy = CONVERT(sz.cy, logY); + +#undef CONVERT +#undef HIMETRIC_INCH +} + + +void wxActiveXContainer::OnSize(wxSizeEvent& event) +{ + int w, h; + GetParent()->GetClientSize(&w, &h); + + RECT posRect; + posRect.left = 0; + posRect.top = 0; + posRect.right = w; + posRect.bottom = h; + + if (w <= 0 && h <= 0) + return; + + // extents are in HIMETRIC units + if (m_oleObject.Ok()) + { + SIZEL sz = {w, h}; + PixelsToHimetric(sz); + + SIZEL sz2; + + m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2); + if (sz2.cx != sz.cx || sz.cy != sz2.cy) + m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); + }; + + if (m_oleInPlaceObject.Ok()) + m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); + + event.Skip(); +} + +void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + // Draw only when control is windowless or deactivated + if (m_viewObject) + { + dc.BeginDrawing(); + int w, h; + GetParent()->GetSize(&w, &h); + RECT posRect; + posRect.left = 0; + posRect.top = 0; + posRect.right = w; + posRect.bottom = h; + + ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT); + RECTL *prcBounds = (RECTL *) &posRect; + m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, + (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0); + + dc.EndDrawing(); + } + +// We've got this one I think +// event.Skip(); +} + +void wxActiveXContainer::OnSetFocus(wxFocusEvent& event) +{ + if (m_oleInPlaceActiveObject.Ok()) + m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE); + + event.Skip(); +} + +void wxActiveXContainer::OnKillFocus(wxFocusEvent& event) +{ + if (m_oleInPlaceActiveObject.Ok()) + m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE); + + event.Skip(); +} diff --git a/src/wxWindows.dsp b/src/wxWindows.dsp index 1a92e2d3f0..8b76cef745 100644 --- a/src/wxWindows.dsp +++ b/src/wxWindows.dsp @@ -1435,6 +1435,10 @@ SOURCE=.\msw\ole\access.cpp # End Source File # Begin Source File +SOURCE=.\msw\ole\activex.cpp +# End Source File +# Begin Source File + SOURCE=.\msw\ole\automtn.cpp # End Source File # Begin Source File @@ -3491,6 +3495,10 @@ SOURCE=..\include\wx\msw\ole\access.h # End Source File # Begin Source File +SOURCE=..\include\wx\msw\ole\activex.h +# End Source File +# Begin Source File + SOURCE=..\include\wx\msw\ole\automtn.h # End Source File # Begin Source File -- 2.47.2