Ryan's cumulative wxActiveX and media control patch (1427775)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37461 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-02-10 19:37:40 +00:00
parent dcae64c221
commit 557002cf81
19 changed files with 6828 additions and 1099 deletions

View File

@@ -39,6 +39,7 @@
@echo USE_THREADS=$(USE_THREADS) >>$(BUILD_CFG_FILE)
@echo USE_GUI=$(USE_GUI) >>$(BUILD_CFG_FILE)
@echo USE_HTML=$(USE_HTML) >>$(BUILD_CFG_FILE)
@echo USE_MEDIA=$(USE_MEDIA) >>$(BUILD_CFG_FILE)
@echo USE_ODBC=$(USE_ODBC) >>$(BUILD_CFG_FILE)
@echo USE_OPENGL=$(USE_OPENGL) >>$(BUILD_CFG_FILE)
@echo USE_QA=$(USE_QA) >>$(BUILD_CFG_FILE)

View File

@@ -180,6 +180,14 @@ Acts according to BUILD by default.
</description>
</option>
<option name="USE_MEDIA">
<values>0,1</values>
<default-value>1</default-value>
<description>
Build multimedia library (USE_GUI must be 1)?
</description>
</option>
<option name="USE_XRC">
<values>0,1</values>
<default-value>1</default-value>
@@ -403,6 +411,7 @@ Set the version of your Mingw installation here.
<set var="RUNTIME_LIBS">dynamic</set>
<set var="OFFICIAL_BUILD">0</set>
<set var="USE_HTML">1</set>
<set var="USE_MEDIA">1</set>
<set var="USE_XRC">1</set>
<set var="USE_OPENGL">1</set>
<set var="USE_ODBC">1</set>

View File

@@ -2657,7 +2657,8 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
</set>
<set var="MEDIA_MSW_SRC" hints="files">
src/msw/mediactrl.cpp
src/msw/mediactrl_am.cpp
src/msw/mediactrl_wmp10.cpp
src/msw/ole/activex.cpp
</set>
<set var="MEDIA_MSW_HDR" hints="files">

View File

@@ -102,7 +102,7 @@
<!-- ================================================================= -->
<dll id="mediadll" template="wx_dll"
cond="SHARED=='1' and USE_GUI=='1' and MONOLITHIC=='0'">
cond="SHARED=='1' and USE_MEDIA=='1' and USE_GUI=='1' and MONOLITHIC=='0'">
<define>WXUSINGDLL</define>
<define>WXMAKINGDLL_MEDIA</define>
<sources>$(MEDIA_SRC)</sources>
@@ -112,7 +112,7 @@
</dll>
<lib id="medialib" template="wx_lib"
cond="SHARED=='0' and USE_GUI=='1' and MONOLITHIC=='0'">
cond="SHARED=='0' and USE_MEDIA=='1' and USE_GUI=='1' and MONOLITHIC=='0'">
<sources>$(MEDIA_SRC)</sources>
<msvc-headers>$(MEDIA_HDR)</msvc-headers>
</lib>

View File

@@ -422,6 +422,7 @@ if test $DEBUG_CONFIGURE = 1; then
DEFAULT_wxUSE_TEXTFILE=no
DEFAULT_wxUSE_SOUND=no
DEFAULT_wxUSE_MEDIACTRL=no
DEFAULT_wxUSE_GSTREAMER8=no
DEFAULT_wxUSE_INTL=no
DEFAULT_wxUSE_CONFIG=no
DEFAULT_wxUSE_FONTMAP=no
@@ -624,6 +625,7 @@ else
DEFAULT_wxUSE_TEXTFILE=yes
DEFAULT_wxUSE_SOUND=yes
DEFAULT_wxUSE_MEDIACTRL=no
DEFAULT_wxUSE_GSTREAMER8=no
DEFAULT_wxUSE_INTL=yes
DEFAULT_wxUSE_CONFIG=yes
DEFAULT_wxUSE_FONTMAP=yes
@@ -935,6 +937,7 @@ WX_ARG_ENABLE(timer, [ --enable-timer use wxTimer class], wxUS
WX_ARG_ENABLE(unicode, [ --enable-unicode compile wxString with Unicode support], wxUSE_UNICODE)
WX_ARG_ENABLE(sound, [ --enable-sound use wxSound class], wxUSE_SOUND)
WX_ARG_ENABLE(mediactrl, [ --enable-mediactrl use wxMediaCtrl class], wxUSE_MEDIACTRL)
WX_ARG_ENABLE(gstreamer8, [ --enable-gstreamer8 force GStreamer 0.8 instead of 0.10 with the wxMediaCtrl class on unix], wxUSE_GSTREAMER8)
WX_ARG_ENABLE(wxprintfv, [ --enable-wxprintfv use wxWidgets implementation of vprintf()], wxUSE_EXPERIMENTAL_PRINTF)
WX_ARG_ENABLE(zipstream, [ --enable-zipstream use wxZip streams], wxUSE_ZIPSTREAM)
@@ -6754,6 +6757,8 @@ dnl ---------------------------------------------------------------------------
dnl wxMediaCtrl
dnl ---------------------------------------------------------------------------
USE_MEDIA=0
if test "$wxUSE_MEDIACTRL" = "yes"; then
dnl -----------------------------------------------------------------------
dnl GStreamer
@@ -6762,77 +6767,57 @@ if test "$wxUSE_MEDIACTRL" = "yes"; then
wxUSE_GSTREAMER="yes"
dnl -------------------------------------------------------------------
dnl Test for gstreamer module from pkg-config
dnl -------------------------------------------------------------------
PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.8,
[
CPPFLAGS="$GSTREAMER_CFLAGS $CPPFLAGS"
LIBS="$LIBS $GSTREAMER_LIBS -lgstplay-0.8"
],
[
AC_MSG_WARN([GStreamer installation not found])
wxUSE_GSTREAMER="no"
])
dnl -------------------------------------------------------------------
dnl Perform a check for a GStreamer element using gst-inspect
dnl Thomas Vander Stichele <thomas at apestaart dot org>
dnl Last modification: 25/01/2005
dnl Test for at least 0.8 gstreamer module from pkg-config
dnl Even totem doesn't accept 0.9 evidently.
dnl
dnl AM_GST_ELEMENT_CHECK(ELEMENT-NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND)
dnl So, we first check to see if 0.10 if available - if not we
dnl try the older 0.8 version
dnl -------------------------------------------------------------------
AC_DEFUN([AM_GST_ELEMENT_CHECK],
[
if test "x$GST_INSPECT" == "x"; then
AC_CHECK_PROG(GST_INSPECT, gst-inspect, gst-inspect, [])
fi
GST_VERSION_MAJOR=0
GST_VERSION_MINOR=10
GST_VERSION_RELEASE=0
GSTREAMER_REQ=$GST_VERSION_MAJOR.$GST_VERSION_MINOR.$GST_VERSION_RELEASE
GST_MAJORMINOR=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
if test "x$GST_INSPECT" != "x"; then
AC_MSG_CHECKING(GStreamer element $1)
if [ $GST_INSPECT $1 > /dev/null 2> /dev/null ]; then
AC_MSG_RESULT(found.)
$2
else
AC_MSG_RESULT(not found.)
$3
fi
fi
])
dnl -------------------------------------------------------------------
dnl Test for x video sink (video useless without)
dnl -------------------------------------------------------------------
AM_GST_ELEMENT_CHECK(xvimagesink,[],
if test "$wxUSE_GSTREAMER8" = "no"; then
PKG_CHECK_MODULES(GST, gstreamer-$GST_MAJORMINOR
gstreamer-plugins-base-$GST_MAJORMINOR
gconf-2.0,
[
wxUSE_GSTREAMER="no"
AC_MSG_WARN([x video sink not found - cannot use GStreamer])
])
dnl -------------------------------------------------------------------
dnl Check for gstplay-0.8 lib and corresponding x overlay header
dnl -------------------------------------------------------------------
AC_CHECK_HEADER(gst/xoverlay/xoverlay.h, [],
[
wxUSE_GSTREAMER="no"
AC_MSG_WARN([xoverlay header not found, cannot use GStreamer])
CPPFLAGS="$GST_CFLAGS $CPPFLAGS"
LIBS="$LIBS $GST_LIBS -lgstinterfaces-$GST_MAJORMINOR"
],
[#include <gst/gst.h>])
AC_MSG_CHECKING([for gstplay 0.8])
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],gstplay-0.8)
if test "$ac_find_libraries" = "" ; then
AC_MSG_RESULT([no])
wxUSE_GSTREAMER="no"
[
GST_VERSION_MINOR=8
])
else
AC_MSG_RESULT([yes])
GST_VERSION_MINOR=8
fi
GSTREAMER_REQ=$GST_VERSION_MAJOR.$GST_VERSION_MINOR.$GST_VERSION_RELEASE
GST_MAJORMINOR=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
if test x$GST_VERSION_MINOR = x8; then
PKG_CHECK_MODULES(GST, gstreamer-$GST_MAJORMINOR
gstreamer-interfaces-$GST_MAJORMINOR
gstreamer-gconf-$GST_MAJORMINOR,
[
CPPFLAGS="$GST_CFLAGS $CPPFLAGS"
LIBS="$LIBS $GST_LIBS"
],
[
AC_MSG_WARN([Proper GStreamer .8/.10 installation not found])
wxUSE_GSTREAMER="no"
])
fi
if test "$wxUSE_GSTREAMER" = "yes"; then
AC_DEFINE(wxUSE_GSTREAMER)
AC_MSG_RESULT([GStreamer detection successful])
fi
fi
USE_MEDIA=1
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS mediaplayer"
AC_DEFINE(wxUSE_MEDIACTRL)
fi

View File

@@ -0,0 +1,236 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: activexcontainer.tex
%% Purpose: wxActiveXContainer docs
%% Author: Ryan Norton <wxprojects@comcast.net>
%% Modified by:
%% Created: 01/30/2005
%% RCS-ID: $Id$
%% Copyright: (c) Ryan Norton
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxActiveXContainer}}\label{wxactivexcontainer}
wxActiveXContainer is a host for an activex control on Windows (and
as such is a platform-specific class). Note that the HWND that the class
contains is the actual HWND of the activex control so using dynamic events
and connecting to wxEVT\_SIZE, for example, will recieve the actual size
message sent to the control.
It is somewhat similar to the ATL class CAxWindow in operation.
The size of the activex control's content is generally gauranteed to be that
of the client size of the parent of this wxActiveXContainer.
You can also process activex events through wxEVT\_ACTIVEX or the
corresponding message map macro EVT\_ACTIVEX.
\wxheading{See also}
\helpref{wxActiveXEvent}{wxactivexevent}
\wxheading{Derived from}
\helpref{wxControl}{wxcontrol}
\wxheading{Include files}
<wx/msw/ole/activex.h>
\wxheading{Example}
This is an example of how to use the Adobe Acrobat Reader ActiveX control to read PDF files
(requires Acrobat Reader 4 and up). Controls like this are typically found and dumped from
OLEVIEW.exe that is distributed with Microsoft Visual C++. This example also demonstrates
how to create a backend for \helpref{wxMediaCtrl}{wxmediactrl}.
\begin{verbatim}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxPDFMediaBackend
//
// http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/iac/IACOverview.pdf
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "wx/mediactrl.h" // wxMediaBackendCommonBase
#include "wx/msw/ole/activex.h" // wxActiveXContainer
#include "wx/msw/ole/automtn.h" // wxAutomationObject
const IID DIID__DPdf = {0xCA8A9781,0x280D,0x11CF,{0xA2,0x4D,0x44,0x45,0x53,0x54,0x00,0x00}};
const IID DIID__DPdfEvents = {0xCA8A9782,0x280D,0x11CF,{0xA2,0x4D,0x44,0x45,0x53,0x54,0x00,0x00}};
const CLSID CLSID_Pdf = {0xCA8A9780,0x280D,0x11CF,{0xA2,0x4D,0x44,0x45,0x53,0x54,0x00,0x00}};
class WXDLLIMPEXP_MEDIA wxPDFMediaBackend : public wxMediaBackendCommonBase
{
public:
wxPDFMediaBackend() : m_pAX(NULL) {}
virtual ~wxPDFMediaBackend()
{
if(m_pAX)
{
m_pAX->DissociateHandle();
delete m_pAX;
}
}
virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxValidator& validator,
const wxString& name)
{
IDispatch* pDispatch;
if( ::CoCreateInstance(CLSID_Pdf, NULL,
CLSCTX_INPROC_SERVER,
DIID__DPdf, (void**)&pDispatch) != 0 )
return false;
m_PDF.SetDispatchPtr(pDispatch); // wxAutomationObject will release itself
if ( !ctrl->wxControl::Create(parent, id, pos, size,
(style & ~wxBORDER_MASK) | wxBORDER_NONE,
validator, name) )
return false;
m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
m_pAX = new wxActiveXContainer(ctrl,
DIID__DPdf,
pDispatch);
wxPDFMediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);
return true;
}
virtual bool Play()
{
return true;
}
virtual bool Pause()
{
return true;
}
virtual bool Stop()
{
return true;
}
virtual bool Load(const wxString& fileName)
{
if(m_PDF.CallMethod(wxT("LoadFile"), fileName).GetBool())
{
m_PDF.CallMethod(wxT("setCurrentPage"), wxVariant((long)0));
NotifyMovieLoaded(); // initial refresh
wxSizeEvent event;
m_pAX->OnSize(event);
return true;
}
return false;
}
virtual bool Load(const wxURI& location)
{
return m_PDF.CallMethod(wxT("LoadFile"), location.BuildUnescapedURI()).GetBool();
}
virtual bool Load(const wxURI& WXUNUSED(location),
const wxURI& WXUNUSED(proxy))
{
return false;
}
virtual wxMediaState GetState()
{
return wxMEDIASTATE_STOPPED;
}
virtual bool SetPosition(wxLongLong where)
{
m_PDF.CallMethod(wxT("setCurrentPage"), wxVariant((long)where.GetValue()));
return true;
}
virtual wxLongLong GetPosition()
{
return 0;
}
virtual wxLongLong GetDuration()
{
return 0;
}
virtual void Move(int WXUNUSED(x), int WXUNUSED(y),
int WXUNUSED(w), int WXUNUSED(h))
{
}
wxSize GetVideoSize() const
{
return wxDefaultSize;
}
virtual double GetPlaybackRate()
{
return 0;
}
virtual bool SetPlaybackRate(double)
{
return false;
}
virtual double GetVolume()
{
return 0;
}
virtual bool SetVolume(double)
{
return false;
}
virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags)
{
if(flags)
{
m_PDF.CallMethod(wxT("setShowToolbar"), true);
m_PDF.CallMethod(wxT("setShowScrollbars"), true);
}
else
{
m_PDF.CallMethod(wxT("setShowToolbar"), false);
m_PDF.CallMethod(wxT("setShowScrollbars"), false);
}
return true;
}
wxActiveXContainer* m_pAX;
wxAutomationObject m_PDF;
DECLARE_DYNAMIC_CLASS(wxPDFMediaBackend)
};
IMPLEMENT_DYNAMIC_CLASS(wxPDFMediaBackend, wxMediaBackend);
\end{verbatim}
Put this in one of your existant source files and then create a wxMediaCtrl with
\begin{verbatim}
//[this] is the parent window, "myfile.pdf" is the PDF file to open
wxMediaCtrl* mymediactrl = new wxMediaCtrl(this, wxT("myfile.pdf"), wxID_ANY,
wxDefaultPosition, wxSize(300,300),
0, wxT("wxPDFMediaBackend"));
\end{verbatim}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxActiveXContainer::wxActiveXContainer}\label{wxactivexcontainerwxactivexcontainer}
\func{}{wxActiveXContainer}{
\param{wxWindow* }{parent},
\param{REFIID }{iid},
\param{IUnknown* }{pUnk},
}
Creates this activex container.
\docparam{parent}{parent of this control. Must not be NULL.}
\docparam{iid}{COM IID of pUnk to query. Must be a valid interface to an activex control.}
\docparam{pUnk}{Interface of activex control}

View File

@@ -0,0 +1,75 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: activexevt.tex
%% Purpose: wxActiveXEvent docs
%% Author: Ryan Norton <wxprojects@comcast.net>
%% Modified by:
%% Created: 01/30/2005
%% RCS-ID: $Id$
%% Copyright: (c) Ryan Norton
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxActiveXEvent}}\label{wxactivexevent}
An event class for handling activex events passed from
\helpref{wxActiveXContainer}{wxactivexcontainer}. ActiveX events are basically
a function call with the parameters passed through an array of wxVariants along
with a return value that is a wxVariant itself. What type the parameters or
return value are depends on the context (i.e. what the .idl specifies).
Note that unlike the third party wxActiveX function names are not supported.
\wxheading{Derived from}
\helpref{wxCommandEvent}{wxcommandevent}
\wxheading{Include files}
<wx/msw/ole/activex.h>
\wxheading{Event table macros}
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf EVT\_ACTIVEX(func)}}{
Sent when the activex control hosted by \helpref{wxActiveXContainer}{wxactivexcontainer}
recieves an activex event.}
\end{twocollist}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxActiveXEvent::ParamCount}\label{wxactivexeventparamcount}
\constfunc{int}{ParamCount}{\void}
Obtains the number of parameters passed through the activex event.
\membersection{wxActiveXEvent::ParamType}\label{wxactivexeventparamtype}
\constfunc{wxString}{ParamType}{\param{int }{idx}}
Obtains the param type of the param number idx specifies as a string.
\membersection{wxActiveXEvent::ParamName}\label{wxactivexeventparamname}
\constfunc{wxString}{ParamName}{\param{int }{idx}}
Obtains the param name of the param number idx specifies as a string.
\membersection{wxActiveXEvent::operator[]}\label{wxactivexeventoparray}
\func{wxVariant&}{operator[]}{\param{int }{idx}}
Obtains the actual parameter value specified by idx.
\membersection{wxActiveXEvent::GetDispatchId}\label{wxactivexeventgetdispatchid}
\constfunc{DISPID}{GetDispatchId}{\param{int }{idx}}
Returns the dispatch id of this activex event. This is the numeric value from
the .idl file specified by the id().

View File

@@ -8,6 +8,8 @@
\input accel.tex
\input accessible.tex
\input activevt.tex
\input activexcontainer.tex
\input activexevt.tex
\input app.tex
\input archive.tex
\input array.tex

View File

@@ -18,6 +18,10 @@ wxMediaCtrl uses native backends to render media, for example on Windows
there is a ActiveMovie/DirectShow backend, and on Macintosh there is a
QuickTime backend.
\wxheading{See also}
\helpref{wxMediaEvent}{wxmediaevent}
\wxheading{Derived from}
\helpref{wxControl}{wxcontrol}
@@ -28,6 +32,7 @@ QuickTime backend.
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{Rendering media}\label{renderingmediawxmediactrl}
Depending upon the backend, wxMediaCtrl can render
@@ -48,6 +53,7 @@ capabilities of the backend. For example, QuickTime cannot set
the playback rate of certain streaming media - while DirectShow is
slightly more flexible in that regard.
\membersection{Operation}\label{operationwxmediactrl}
When wxMediaCtrl plays a file, it plays until the stop position
@@ -86,6 +92,50 @@ because some streams are not seekable, and when stop is called
on them they return to the beginning, thus wxMediaCtrl tries
to keep consistant for all types of media.
Note that when changing the state of the media through Play()
and other methods, the media may not actually be in the
wxMEDIASTATE\_PLAYING, for example. If you are relying on the
media being in certain state catch the event relevant to the state.
See \helpref{wxMediaEvent}{wxmediaevent} for the kinds of events
that you can catch.
\membersection{Video size}\label{videosizewxmediactrl}
By default, wxMediaCtrl will scale the size of the video to the
requested amount passed to either it's constructor or Create().
After calling Load or performing an equivilant operation, you
can subsequently obtain the "real" size of the video (if there
is any) by calling GetBestSize(). Note that the actual result
on the display will be slightly different when ShowPlayerControls
is activated and the actual video size will be less then
specified due to the extra controls provided by the native toolkit.
In addition, the backend may modify GetBestSize() to include the
size of the extra controls - so if you want the real size of the
video just disable ShowPlayerControls().
The idea with setting GetBestSize to the size of the video is
that GetBestSize is a wxWindow-derived function that is called
when sizers on a window recalculate. What this means is that
if you use sizers by default the video will show in it's
original size without any extra assistance needed from the user.
\membersection{Player controls}\label{playercontrolswxmediactrl}
Normally, when you use wxMediaCtrl it is just a window for the video to
play in. However, some toolkits have their own media player interface.
For example, QuickTime generally has a bar below the video with a slider.
A special feature available to wxMediaCtrl, you can use the toolkit's interface instead of
making your own by using the \helpref{ShowPlayerControls()}{wxmediactrlshowplayercontrols}
function. There are several options for the flags parameter, with
the two general flags being wxMEDIACTRLPLAYERCONTROLS\_NONE which turns off
the native interface, and wxMEDIACTRLPLAYERCONTROLS\_DEFAULT which lets
wxMediaCtrl decide what native controls on the interface. Be sure to review
the caveats outlined in \helpref{Video size}{videosizewxmediactrl} before
doing so.
\membersection{Choosing a backend}\label{choosingbackendwxmediactrl}
Generally, you should almost certainly leave this part up to
@@ -99,17 +149,48 @@ The following are valid backend identifiers -
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxMEDIABACKEND\_DIRECTSHOW}}{
Use ActiveMovie/DirectShow. Requires wxUSE\_DIRECTSHOW to be
enabled, requires linkage with the static library strmiids.lib,
and is available on Windows Only.}
Use ActiveMovie/DirectShow. Uses the native ActiveMovie
(I.E. DirectShow) control. Default backend on Windows and
supported by nearly all Windows versions, even some
Windows CE versions. May display a windows media player
logo while inactive. }
\twocolitem{{\bf wxMEDIABACKEND\_QUICKTIME}}{
Use QuickTime. Windows and Mac Only. NOTE: On Mac Systems lower than OSX 10.2 this defaults to emulating window positioning and suffers from several bugs, including not working correctly embedded in a wxNotebook. }
\twocolitem{{\bf wxMEDIABACKEND\_MCI}}{
Use Media Command Interface. Windows Only. }
Use QuickTime. Mac Only.
WARNING: May not working correctly embedded in a wxNotebook.
}
\twocolitem{{\bf wxMEDIABACKEND\_GSTREAMER}}{
Use GStreamer. Unix Only. }
Use GStreamer. Unix Only. Requires GStreamer 0.8 along
with at the very least the xvimagesink, xoverlay, and
gst-play modules of gstreamer to function. You need the correct
modules to play the relavant files, for example the mad module
to play mp3s, etc.}
\twocolitem{{\bf wxMEDIABACKEND\_WMP10}}{
Uses Windows Media Player 10 (Windows only) - works on mobile
machines with Windows Media Player 10 and desktop machines with
either Windows Media Player 9 or 10
}
\end{twocollist}
Note that other backends such as wxMEDIABACKEND\_MCI can now be
found at wxCode.
\membersection{Creating a backend}\label{creatingabackendwxmediactrl}
Creating a backend for wxMediaCtrl is a rather simple process. Simply derive
from wxMediaBackendCommonBase and implement the methods you want. The methods
in wxMediaBackend correspond to those in wxMediaCtrl except for CreateControl
which does the actual creation of the control, in cases where a custom control
is not needed you may simply call wxControl::Create.
You need to make sure to use the DECLARE\_CLASS and IMPLEMENT\_CLASS macros.
The only real tricky part is that you need to make sure the file in compiled
in, which if there are just backends in there will not happen and you may need
to use a force link hack (see http://www.wxwidgets.org/wiki/index.php/RTTI).
This is a rather simple example of how to create a backend in the
\helpref{wxActiveXContainer}{wxactivexcontainer} documentation.
\membersection{wxMediaCtrl::wxMediaCtrl}\label{wxmediactrlwxmediactrl}
\func{}{wxMediaCtrl}{\void}
@@ -173,25 +254,38 @@ wxMediaCtrl figure it out.}
\docparam{name}{Window name.}
\membersection{wxMediaCtrl::Length}\label{wxmediactrlgetduration}
\membersection{wxMediaCtrl::GetBestSize}\label{wxmediactrlgetbestsize}
\func{wxFileOffset}{GetDuration}{\void}
\func{wxSize}{GetBestSize}{\void}
Obtains the length - the total amount of time the movie has in milliseconds.
Obtains the best size relative to the original/natural size of the
video, if there is any. See \helpref{Video size}{videosizewxmediactrl}
for more information.
\membersection{wxMediaCtrl::Tell}\label{wxmediactrlgetposition}
\membersection{wxMediaCtrl::GetPlaybackRate}\label{wxmediactrlgetplaybackrate}
\func{wxFileOffset}{GetPosition}{\void}
\func{double}{GetPlaybackrate}{\void}
Obtains the current position in time within the movie in milliseconds.
Obtains the playback rate, or speed of the media. \tt{1.0} represents normal
speed, while \tt{2.0} represents twice the normal speed of the media, for
example. Not supported on the GStreamer (Unix) backend.
Returns 0 on failure.
\membersection{wxMediaCtrl::GetVolume}\label{wxmediactrlgetvolume}
\func{double}{GetVolume}{\void}
Gets the volume of the media from a 0.0 to 1.0 range. Note that due to rounding
and other errors this may not be the exact value sent to SetVolume.
\membersection{wxMediaCtrl::GetState}\label{wxmediactrlgetstate}
\func{wxMediaCtrlState}{GetState}{\void}
Obtains the state the playback of the movie is in -
Obtains the state the playback of the media is in -
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
@@ -201,6 +295,13 @@ Obtains the state the playback of the movie is in -
\end{twocollist}
\membersection{wxMediaCtrl::Length}\label{wxmediactrllength}
\func{wxFileOffset}{Length}{\void}
Obtains the length - the total amount of time the movie has in milliseconds.
\membersection{wxMediaCtrl::Load}\label{wxmediactrlload}
\func{bool}{Load}{\param{const wxString\& }{fileName}}
@@ -210,9 +311,31 @@ Loads the file that \tt{fileName} refers to. Returns false if loading fails.
\membersection{wxMediaCtrl::Load}\label{wxmediactrlloaduri}
\func{bool}{Load}{\param{const wxURI\& }{location}}
\func{bool}{Load}{\param{const wxURI\& }{uri}}
Loads the location that \tt{uri} refers to. Note that this is very implementation-dependant, although HTTP URI/URLs are generally supported, for example. Returns false if loading fails.
\membersection{wxMediaCtrl::Load}\label{wxmediactrlloaduriwithproxy}
\func{bool}{Load}{\param{const wxURI\& }{uri}, \param{const wxURI\& }{proxy}}
Loads the location that \tt{uri} refers to with the proxy \tt{proxy}. Not implemented on most backends so it should be called with caution. Returns false if loading fails.
\membersection{wxMediaCtrl::LoadURI}\label{wxmediactrlloaduriliteral}
\func{bool}{LoadURI}{\param{const wxURI\& }{uri}}
Same as \helpref{Load}{wxmediactrlloaduri}. Kept for wxPython compatability.
\membersection{wxMediaCtrl::LoadURIWithProxy}\label{wxmediactrlloaduriwithproxyliteral}
\func{bool}{LoadURIWithProxy}{\param{const wxURI\& }{uri}, \param{const wxURI\& }{proxy}}
Same as \helpref{Load}{wxmediactrlloaduriwithproxy}. Kept for wxPython compatability.
Loads the url that \tt{location} refers to. Returns false if loading fails.
\membersection{wxMediaCtrl::Pause}\label{wxmediactrlpause}
@@ -235,54 +358,65 @@ Resumes playback of the movie.
Seeks to a position within the movie.
\membersection{wxMediaCtrl::Stop}\label{wxmediactrlstop}
\membersection{wxMediaCtrl::SetPlaybackRate}\label{wxmediactrlsetplaybackrate}
\func{bool}{Stop}{\void}
\func{bool}{SetPlaybackRate}{\param{double }{dRate}}
Stops the media.
See \helpref{Operation}{operationwxmediactrl} for an overview of how stopping works.
Sets the playback rate, or speed of the media, to that referred by \tt{dRate}.
\tt{1.0} represents normal speed, while \tt{2.0} represents twice the normal
speed of the media, for example. Not supported on the GStreamer (Unix) backend.
Returns true if successful.
\membersection{wxMediaCtrl::SetVolume}\label{wxmediactrlsetvolume}
\func{bool}{SetVolume}{\param{double }{dVolume}}
Sets the volume of the media from a 0.0 to 1.0 range.
\membersection{wxMediaCtrl::GetVolume}\label{wxmediactrlgetvolume}
\func{double}{GetVolume}{\void}
Gets the volume of the media from a 0.0 to 1.0 range.
\membersection{wxMediaCtrl::GetPlaybackRate}\label{wxmediactrlgetplaybackrate}
\func{double}{GetPlaybackrate}{\void}
Gets the playback rate of the media; for example 2.0 is double speed.
Not implemented on MCI or GStreamer.
\membersection{wxMediaCtrl::SetPlaybackRate}\label{wxmediactrlsetplaybackrate}
\func{bool}{SetPlaybackrate}{\param{double }{dVolume}}
Sets the rate that the media plays; for example 0.5 is half speed.
Sets the volume of the media from a 0.0 to 1.0 range to that referred
by \tt{dVolume}. \tt{1.0} represents full volume, while \tt{0.5}
represents half (50 percent) volume, for example. Note that this may not be
exact due to conversion and rounding errors, although setting the volume to
full or none is always exact. Returns true if successful.
\membersection{wxMediaCtrl::ShowPlayerControls}\label{wxmediactrlshowplayercontrols}
\func{bool}{ShowPlayerControls}{\param{wxMediaCtrlPlayerControls }{flags}}
\func{bool}{ShowPlayerControls}{\param{wxMediaCtrlPlayerControls }{flags = wxMEDIACTRLPLAYERCONTROLS\_DEFAULT}}
Normally, when you use wxMediaCtrl it is just a window for the video to
play in. However, platforms generally have their own media player interface,
like quicktime has a bar below the video with a slider etc.. If you want that native
interface instead of making your own use this function. There are several options
for the flags parameter, however you can look at the mediactrl header for these.
The two general flags are wxMEDIACTRLPLAYERCONTROLS\_NONE which turns off the
native interface, and wxMEDIACTRLPLAYERCONTROLS\_DEFAULT which lets wxMediaCtrl
decide what native controls on the interface.
A special feature to wxMediaCtrl. Applications using native toolkits such as
QuickTime usually have a scrollbar, play button, and more provided to
them by the toolkit. By default wxMediaCtrl does not do this. However, on
the directshow and quicktime backends you can show or hide the native controls
provided by the underlying toolkit at will using ShowPlayerControls. Simply
calling the function with default parameters tells wxMediaCtrl to use the
default controls provided by the toolkit. The function takes a
\tt{wxMediaCtrlPlayerControls} enumeration as follows:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxMEDIACTRLPLAYERCONTROLS\_NONE}}{No controls. return wxMediaCtrl to it's default state.}
\twocolitem{{\bf wxMEDIACTRLPLAYERCONTROLS\_STEP}}{Step controls like fastfoward, step one frame etc.}
\twocolitem{{\bf wxMEDIACTRLPLAYERCONTROLS\_VOLUME}}{Volume controls like the speaker icon, volume slider, etc.}
\twocolitem{{\bf wxMEDIACTRLPLAYERCONTROLS\_DEFAULT}}{Default controls for the toolkit. Currently a typedef for wxMEDIACTRLPLAYERCONTROLS\_STEP and wxMEDIACTRLPLAYERCONTROLS\_VOLUME.}
\end{twocollist}
For more see \helpref{Player controls}{playercontrolswxmediactrl}. Currently
only implemented on the QuickTime and DirectShow backends. The function
returns true on success.
\membersection{wxMediaCtrl::Stop}\label{wxmediactrlstop}
\func{bool}{Stop}{\void}
Stops the media.
See \helpref{Operation}{operationwxmediactrl} for an overview of how
stopping works.
\membersection{wxMediaCtrl::Tell}\label{wxmediactrlgetposition}
\func{wxFileOffset}{Tell}{\void}
Obtains the current position in time within the movie in milliseconds.

View File

@@ -25,10 +25,26 @@ Event \helpref{wxMediaCtrl}{wxmediactrl} uses.
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf EVT\_MEDIA\_LOADED(func)}}{Sent when a media has loaded enough data that it can start playing.}
\twocolitem{{\bf EVT\_MEDIA\_LOADED(func)}}{
Sent when a media has loaded enough data that it can start playing.}
\twocolitem{{\bf EVT\_MEDIA\_STOP(func)}}{
Triggerred right before the media stops. You can Veto this event to prevent it from stopping, causing it to continue playing - even if it has reached that end of the media. }
\twocolitem{{\bf EVT\_MEDIA\_FINISHED(func)}}{Sent when a media has finished playing in a \helpref{wxMediaCtrl}{wxmediactrl}. Note that if you connect to this event and don't skip it, it will override the looping behaviour of the media control.}
Send when a media has switched to the wxMEDIASTATE\_STOPPED state.
You may be able to Veto this event to prevent it from stopping,
causing it to continue playing - even if it has reached that end of the media
(note that this may not have the desired effect - if you want to loop the
media, for example, catch the EVT\_MEDIA\_FINISHED and play there instead). }
\twocolitem{{\bf EVT\_MEDIA\_FINISHED(func)}}{
Sent when a media has finished playing in a \helpref{wxMediaCtrl}{wxmediactrl}.
}
\twocolitem{{\bf EVT\_MEDIA\_STATECHANGED(func)}}{
Send when a media has switched its state (from any media state).
}
\twocolitem{{\bf EVT\_MEDIA\_PLAY(func)}}{
Send when a media has switched to the wxMEDIASTATE\_PLAYING state.
}
\twocolitem{{\bf EVT\_MEDIA\_PAUSE(func)}}{
Send when a media has switched to the wxMEDIASTATE\_PAUSED state.
}
\end{twocollist}
\latexignore{\rtfignore{\wxheading{Members}}}

View File

@@ -22,6 +22,9 @@
// ----------------------------------------------------------------------------
// Pre-compiled header stuff
// ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "mediactrl.h"
#endif
#include "wx/defs.h"
@@ -71,7 +74,8 @@ enum wxMediaCtrlPlayerControls
#define wxMEDIABACKEND_MCI wxT("wxMCIMediaBackend")
#define wxMEDIABACKEND_QUICKTIME wxT("wxQTMediaBackend")
#define wxMEDIABACKEND_GSTREAMER wxT("wxGStreamerMediaBackend")
#define wxMEDIABACKEND_REALPLAYER wxT("wxRealPlayerMediaBackend")
#define wxMEDIABACKEND_WMP10 wxT("wxWMP10MediaBackend")
// ----------------------------------------------------------------------------
//
@@ -190,14 +194,17 @@ public:
wxFileOffset Tell(); //FIXME: This should be const
wxFileOffset Length(); //FIXME: This should be const
#if wxABI_VERSION >= 20601 /* 2.6.1+ only */
double GetPlaybackRate(); //All but MCI & GStreamer
bool SetPlaybackRate(double dRate); //All but MCI & GStreamer
#endif
#if wxABI_VERSION >= 20602 /* 2.6.2+ only */
bool Load(const wxURI& location);
bool Load(const wxURI& location, const wxURI& proxy);
wxFileOffset GetDownloadProgress();
wxFileOffset GetDownloadTotal();
wxFileOffset GetDownloadProgress(); // DirectShow only
wxFileOffset GetDownloadTotal(); // DirectShow only
double GetVolume();
bool SetVolume(double dVolume);
@@ -210,7 +217,7 @@ public:
{ return Load(wxURI(fileName)); }
bool LoadURIWithProxy(const wxString& fileName, const wxString& proxy)
{ return Load(wxURI(fileName), wxURI(proxy)); }
#endif
protected:
static wxClassInfo* NextBackend();
@@ -324,12 +331,10 @@ public:
//Event ID to give to our events
#define wxMEDIA_FINISHED_ID 13000
#define wxMEDIA_STOP_ID 13001
#define wxMEDIA_LOADED_ID 13002
//Define our event types - we need to call DEFINE_EVENT_TYPE(EVT) later
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_FINISHED, wxMEDIA_FINISHED_ID)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_STOP, wxMEDIA_STOP_ID)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_LOADED, wxMEDIA_LOADED_ID)
//Function type(s) our events need
typedef void (wxEvtHandler::*wxMediaEventFunction)(wxMediaEvent&);
@@ -340,7 +345,24 @@ typedef void (wxEvtHandler::*wxMediaEventFunction)(wxMediaEvent&);
//Macro for usage with message maps
#define EVT_MEDIA_FINISHED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_FINISHED, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
#define EVT_MEDIA_STOP(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_STOP, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
#define EVT_MEDIA_LOADED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_LOADED, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
#if wxABI_VERSION >= 20602 /* 2.6.2+ only */
# define wxMEDIA_LOADED_ID 13002
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_LOADED, wxMEDIA_LOADED_ID)
# define EVT_MEDIA_LOADED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_LOADED, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
#endif
#if wxABI_VERSION >= 20603 /* 2.6.3+ only */
# define wxMEDIA_STATECHANGED_ID 13003
# define wxMEDIA_PLAY_ID 13004
# define wxMEDIA_PAUSE_ID 13005
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_STATECHANGED, wxMEDIA_STATECHANGED_ID)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_PLAY, wxMEDIA_PLAY_ID)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_MEDIA_PAUSE, wxMEDIA_PAUSE_ID)
# define EVT_MEDIA_STATECHANGED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_STATECHANGED, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
# define EVT_MEDIA_PLAY(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_PLAY, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
# define EVT_MEDIA_PAUSE(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MEDIA_PAUSE, winid, wxID_ANY, wxMediaEventHandler(fn), (wxObject *) NULL ),
#endif
// ----------------------------------------------------------------------------
// common backend base class used by many other backends
@@ -353,11 +375,26 @@ public:
void QueueEvent(wxEventType evtType);
// notify that the movie playback is finished
void QueueFinishEvent() { QueueEvent(wxEVT_MEDIA_FINISHED); }
void QueueFinishEvent()
{
#if wxABI_VERSION >= 20603 /* 2.6.3+ only */
QueueEvent(wxEVT_MEDIA_STATECHANGED);
#endif
QueueEvent(wxEVT_MEDIA_FINISHED);
}
// send the stop event and return true if it hasn't been vetoed
bool SendStopEvent();
// Queue pause event
void QueuePlayEvent();
// Queue pause event
void QueuePauseEvent();
// Queue stop event (no veto)
void QueueStopEvent();
protected:
// call this when the movie size has changed but not because it has just
// been loaded (in this case, call NotifyMovieLoaded() below)

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/ole/activex.h
// Name: wx/activex.h
// Purpose: wxActiveXContainer class
// Author: Ryan Norton <wxprojects@comcast.net>
// Modified by:
@@ -42,6 +42,7 @@
// WX includes
//---------------------------------------------------------------------------
#include "wx/window.h"
#include "wx/variant.h"
//---------------------------------------------------------------------------
// MSW COM includes
@@ -150,10 +151,6 @@ 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
{
@@ -168,6 +165,7 @@ public:
protected:
friend class FrameSite;
friend class wxActiveXEvents;
wxAutoIDispatch m_Dispatch;
wxAutoIOleClientSite m_clientSite;
@@ -185,4 +183,50 @@ protected:
void CreateActiveX(REFIID, IUnknown*);
};
// Events
class wxActiveXEvent : public wxCommandEvent
{
private:
friend class wxActiveXEvents;
wxVariant m_params;
DISPID m_dispid;
public:
virtual wxEvent *Clone() const
{ return new wxActiveXEvent(*this); }
int ParamCount() const
{ return m_params.GetCount(); }
wxString ParamType(int idx) const
{
wxASSERT(idx >= 0 && idx < m_params.GetCount());
return m_params[idx].GetType();
}
wxString ParamName(int idx) const
{
wxASSERT(idx >= 0 && idx < m_params.GetCount());
return m_params[idx].GetName();
}
wxVariant& operator[] (int idx)
{
wxASSERT(idx >= 0 && idx < ParamCount());
return m_params[idx];
}
DISPID GetDispatchId() const
{ return m_dispid; }
};
#define wxACTIVEX_ID 14001
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_MEDIA, wxEVT_ACTIVEX, wxACTIVEX_ID)
typedef void (wxEvtHandler::*wxActiveXEventFunction)(wxActiveXEvent&);
#define EVT_ACTIVEX(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_ACTIVEX, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
#define wxActiveXEventHandler(func) \
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxActiveXEventFunction, &func)
#endif // _WX_MSW_OLE_ACTIVEXCONTAINER_H_

View File

@@ -29,11 +29,7 @@
// 1) Certain backends can't play the same media file at the same time (MCI,
// Cocoa NSMovieView-Quicktime).
// 2) Positioning on Mac Carbon is messed up if put in a sub-control like a
// Notebook (like this sample does) on OS versions < 10.2.
// 3) On unix the video may not work - it only checks for a few video
// sinks - xvimagesink, ximagesink and whatever gnome preferences has -
// if gnome preferences is not available or you have a different video
// sink then those two (such as sdlvideosink) then you'll get black video
// Notebook (like this sample does).
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// ============================================================================
@@ -116,6 +112,8 @@ enum
// wxID_EXIT, [built-in to wxWidgets]
// Control event IDs
wxID_SLIDER,
wxID_PBSLIDER,
wxID_VOLSLIDER,
wxID_NOTEBOOK,
wxID_MEDIACTRL,
wxID_BUTTONNEXT,
@@ -179,9 +177,6 @@ public:
void OnSelectBackend(wxCommandEvent& event);
// Notebook event handlers
void OnPageChange(wxNotebookEvent& event);
// Key event handlers
void OnKeyDown(wxKeyEvent& event);
@@ -198,9 +193,6 @@ public:
void OnClose(wxCloseEvent& event);
private:
// Rebuild base status string (see Implementation)
void ResetStatus();
// Common open file code
void OpenFile(bool bNewPage);
void OpenURL(bool bNewPage);
@@ -208,7 +200,6 @@ private:
void DoPlayFile(const wxString& path);
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
// Maybe I should use more accessors, but for simplicity
@@ -232,8 +223,13 @@ class wxMediaPlayerNotebookPage : public wxPanel
// Slider event handlers
void OnBeginSeek(wxScrollEvent& event);
void OnEndSeek(wxScrollEvent& event);
void OnPBChange(wxScrollEvent& event);
void OnVolChange(wxScrollEvent& event);
// Media event handlers
void OnMediaPlay(wxMediaEvent& event);
void OnMediaPause(wxMediaEvent& event);
void OnMediaStop(wxMediaEvent& event);
void OnMediaFinished(wxMediaEvent& event);
public:
@@ -248,6 +244,8 @@ public:
wxMediaCtrl* m_mediactrl; //Our media control
class wxMediaPlayerListCtrl* m_playlist; //Our playlist
wxSlider* m_slider; //The slider below our media control
wxSlider* m_pbSlider; //Lower-left slider for adjusting speed
wxSlider* m_volSlider; //Lower-right slider for adjusting volume
int m_nLoops; //Number of times media has looped
bool m_bLoop; //Whether we are looping or not
bool m_bIsBeingDragged; //Whether the user is dragging the scroll bar
@@ -411,6 +409,9 @@ IMPLEMENT_APP(wxMediaPlayerApp)
// ----------------------------------------------------------------------------
bool wxMediaPlayerApp::OnInit()
{
// SetAppName() lets wxConfig and others know where to write
SetAppName(wxT("wxMediaPlayer"));
wxMediaPlayerFrame *frame =
new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample"));
frame->Show(true);
@@ -440,8 +441,8 @@ bool wxMediaPlayerApp::OnInit()
{
frame->AddToPlayList((parser.GetParam (paramNr)));
}
wxCommandEvent emptyevt;
frame->OnNext(emptyevt);
wxCommandEvent theEvent(wxEVT_COMMAND_MENU_SELECTED, wxID_NEXT);
frame->AddPendingEvent(theEvent);
}
#endif
@@ -660,12 +661,6 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title)
this->Connect(wxID_SELECTBACKEND, wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend));
//
// Notebook events
//
this->Connect(wxID_NOTEBOOK, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
wxNotebookEventHandler(wxMediaPlayerFrame::OnPageChange));
//
// Key events
//
@@ -702,13 +697,13 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title)
// it properly loads the playlist for each page without
// conflicting (loading the same data) with the other ones.
//
wxConfigBase* conf = wxConfigBase::Get();
wxConfig conf;
wxString key, outstring;
for(int i = 0; ; ++i)
{
key.clear();
key << i;
if(!conf->Read(key, &outstring))
if(!conf.Read(key, &outstring))
break;
page->m_playlist->AddToPlayList(outstring);
}
@@ -717,7 +712,7 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title)
// Create a timer to update our status bar
//
m_timer = new wxMediaPlayerTimer(this);
m_timer->Start(100);
m_timer->Start(500);
}
// ----------------------------------------------------------------------------
@@ -728,6 +723,9 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title)
// ----------------------------------------------------------------------------
wxMediaPlayerFrame::~wxMediaPlayerFrame()
{
// Shut down our timer
delete m_timer;
//
// Here we save our info to the registry or whatever
// mechanism the OS uses.
@@ -751,19 +749,17 @@ wxMediaPlayerFrame::~wxMediaPlayerFrame()
wxMediaPlayerListCtrl* playlist =
((wxMediaPlayerNotebookPage*)m_notebook->GetPage(0))->m_playlist;
wxConfigBase* conf = wxConfigBase::Get();
conf->DeleteAll();
wxConfig conf;
conf.DeleteAll();
for(int i = 0; i < playlist->GetItemCount(); ++i)
{
wxString* pData = (wxString*) playlist->GetItemData(i);
wxString s;
s << i;
conf->Write(s, *(pData));
conf.Write(s, *(pData));
delete pData;
}
delete m_timer;
}
// ----------------------------------------------------------------------------
@@ -785,38 +781,6 @@ void wxMediaPlayerFrame::AddToPlayList(const wxString& szString)
currentpage->m_playlist->AddToPlayList(szString);
}
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::ResetStatus
//
// Here we just make a simple status string with some useful info about
// the media that we won't change later - such as the length of the media.
//
// We then append some other info that changes in wxMediaPlayerTimer::Notify, then
// set the status bar to this text.
//
// In real applications, you'd want to find a better way to do this,
// such as static text controls (wxStaticText).
//
// We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
// we divide by 1000).
//
// We also reset our loop counter here.
// ----------------------------------------------------------------------------
void wxMediaPlayerFrame::ResetStatus()
{
wxMediaCtrl* currentMediaCtrl =
((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl;
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)),
currentMediaCtrl->GetPlaybackRate()
);
}
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::OnQuit
//
@@ -838,10 +802,25 @@ void wxMediaPlayerFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString msg;
msg.Printf( wxT("This is a test of wxMediaCtrl.\n")
wxT("Welcome to %s"), wxVERSION_STRING);
msg.Printf( wxT("This is a test of wxMediaCtrl.\n\n")
wxMessageBox(msg, wxT("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this);
wxT("Intructions:\n")
wxT("The top slider shows the current the current position, ")
wxT("which you can change by dragging and releasing it.\n")
wxT("The gauge (progress bar) shows the progress in ")
wxT("downloading data of the current file - it may always be ")
wxT("Empty due to lack of support from the current backend.\n")
wxT("The lower-left slider controls the volume and the lower-")
wxT("right slider controls the playback rate/speed of the ")
wxT("media\n\n")
wxT("Currently using: %s"), wxVERSION_STRING);
wxMessageBox(msg, wxT("About wxMediaCtrl test"),
wxOK | wxICON_INFORMATION, this);
}
// ----------------------------------------------------------------------------
@@ -995,17 +974,11 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path)
{
if( !currentpage->m_mediactrl->Pause() )
wxMessageBox(wxT("Couldn't pause movie!"));
else
currentpage->m_playlist->SetItem(
currentpage->m_nLastFileId, 0, wxT("||"));
}
else
{
if( !currentpage->m_mediactrl->Play() )
wxMessageBox(wxT("Couldn't play movie!"));
else
currentpage->m_playlist->SetItem(
currentpage->m_nLastFileId, 0, wxT(">"));
}
}
else
@@ -1075,18 +1048,9 @@ void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt))
currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT(">"));
}
currentpage->m_playlist->SetItem(currentpage->m_nLastFileId,
2, wxString::Format(wxT("%u"),
(unsigned) currentpage->m_mediactrl->Length() / 1000)
);
ResetStatus();
currentpage->m_slider->SetRange(0,
(int)(currentpage->m_mediactrl->Length() / 1000));
currentpage->m_gauge->SetRange((int)(currentpage->m_mediactrl->Length() / 1000));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::OnSelectBackend
//
@@ -1408,7 +1372,7 @@ void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event))
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::OnVolumeDown
//
// Lowers the volume of the media control by 10%
// Lowers the volume of the media control by 5%
// ----------------------------------------------------------------------------
void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event))
{
@@ -1416,13 +1380,13 @@ void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event))
(wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
double dVolume = currentpage->m_mediactrl->GetVolume();
currentpage->m_mediactrl->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1);
currentpage->m_mediactrl->SetVolume(dVolume < 0.05 ? 0.0 : dVolume - .05);
}
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::OnVolumeUp
//
// Increases the volume of the media control by 10%
// Increases the volume of the media control by 5%
// ----------------------------------------------------------------------------
void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event))
{
@@ -1430,17 +1394,7 @@ void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event))
(wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
double dVolume = currentpage->m_mediactrl->GetVolume();
currentpage->m_mediactrl->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1);
}
// ----------------------------------------------------------------------------
// wxMediaPlayerFrame::OnPageChange
//
// Called when the user changes the current notebook page shown
// ----------------------------------------------------------------------------
void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event))
{
ResetStatus();
currentpage->m_mediactrl->SetVolume(dVolume > 0.95 ? 1.0 : dVolume + .05);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1452,42 +1406,94 @@ void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event))
// ----------------------------------------------------------------------------
// wxMediaPlayerTimer::Notify
//
// 1) Update our slider with the position were are in in the media
// 2) Update our status bar with the base text from wxMediaPlayerFrame::ResetStatus,
// append some non-static (changing) info to it, then set the
// status bar text to that result
// 1) Updates media information on the status bar
// 2) Sets the max/min length of the slider and guage
//
// Note that the reason we continually do this and don't cache it is because
// some backends such as GStreamer are dynamic change values all the time
// and often don't have things like duration or video size available
// until the media is actually being played
// ----------------------------------------------------------------------------
void wxMediaPlayerTimer::Notify()
{
wxMediaPlayerNotebookPage* currentpage =
(wxMediaPlayerNotebookPage*) m_frame->m_notebook->GetCurrentPage();
wxMediaCtrl* currentMediaCtrl = currentpage->m_mediactrl;
if(currentpage)
{
// if the slider is being dragged then update it with the song position
// Number of minutes/seconds total
wxLongLong llLength = currentpage->m_mediactrl->Length();
int nMinutes = (int) (llLength / 60000).GetValue();
int nSeconds = (int) ((llLength % 60000)/1000).GetValue();
// Duration string (i.e. MM:SS)
wxString sDuration;
sDuration.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
// Number of minutes/seconds total
wxLongLong llTell = currentpage->m_mediactrl->Tell();
nMinutes = (int) (llTell / 60000).GetValue();
nSeconds = (int) ((llTell % 60000)/1000).GetValue();
// Position string (i.e. MM:SS)
wxString sPosition;
sPosition.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
// Set the third item in the listctrl entry to the duration string
if(currentpage->m_nLastFileId >= 0)
currentpage->m_playlist->SetItem(
currentpage->m_nLastFileId, 2, sDuration);
// Setup the slider and gauge min/max values
currentpage->m_slider->SetRange(0, (int)(llLength / 1000).GetValue());
currentpage->m_gauge->SetRange(100);
// if the slider is not being dragged then update it with the song position
if(currentpage->IsBeingDragged() == false)
currentpage->m_slider->SetValue((long)(llTell / 1000).GetValue());
// Update the gauge with the download progress
wxLongLong llDownloadProgress =
currentpage->m_mediactrl->GetDownloadProgress();
wxLongLong llDownloadTotal =
currentpage->m_mediactrl->GetDownloadTotal();
if(llDownloadTotal.GetValue() != 0)
{
long lPosition = (long)( currentpage->m_mediactrl->Tell() / 1000 );
currentpage->m_slider->SetValue(lPosition);
currentpage->m_gauge->SetValue(
(int) ((llDownloadProgress * 100) / llDownloadTotal).GetValue()
);
}
// update guage with value from slider
currentpage->m_gauge->SetValue(currentpage->m_slider->GetValue());
// GetBestSize holds the original video size
wxSize videoSize = currentMediaCtrl->GetBestSize();
// Now the big part - set the status bar text to
// hold various metadata about the media
#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(),
currentpage->m_slider->GetValue(),
wxT("Size(x,y):%i,%i ")
wxT("Position:%s/%s Speed:%1.1fx ")
wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
videoSize.x,
videoSize.y,
sPosition.c_str(),
sDuration.c_str(),
currentMediaCtrl->GetPlaybackRate(),
wxGetMediaStateText(currentpage->m_mediactrl->GetState()),
currentpage->m_nLoops,
(int)currentpage->m_mediactrl->GetDownloadProgress(),
(int)currentpage->m_mediactrl->GetDownloadTotal(),
(int)llDownloadProgress.GetValue(),
(int)llDownloadTotal.GetValue(),
(int)(currentpage->m_mediactrl->GetVolume() * 100)));
#endif // wxUSE_STATUSBAR
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxMediaPlayerNotebookPage
@@ -1510,7 +1516,6 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
m_bIsBeingDragged(false),
m_parentFrame(parentFrame)
{
//
// Layout
//
@@ -1539,7 +1544,8 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL, wxEmptyString,
wxDefaultPosition, wxDefaultSize, 0,
//you could specify a macrod backend here like
//wxMEDIABACKEND_QUICKTIME);
// wxMEDIABACKEND_WMP10);
// wxT("wxPDFMediaBackend"));
szBackend);
//you could change the cursor here like
// m_mediactrl->SetCursor(wxCURSOR_BLANK);
@@ -1571,8 +1577,8 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
// > - Currently Playing
// [] - Stopped
// || - Paused
// (( - Volume Down 10%
// )) - Volume Up 10%
// (( - Volume Down 5%
// )) - Volume Up 5%
//
// Column two is the name of the file
//
@@ -1615,7 +1621,7 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
vertsizer->Add(m_vdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
vertsizer->Add(m_vuButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
horsizer1->Add(vertsizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
//
@@ -1628,7 +1634,6 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
wxSL_HORIZONTAL );
sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
//
// Create the gauge
//
@@ -1637,6 +1642,26 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
wxGA_HORIZONTAL | wxGA_SMOOTH);
sizer->Add(m_gauge, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
//
// Create the speed/volume sliders
//
wxBoxSizer* horsizer3 = new wxBoxSizer(wxHORIZONTAL);
m_volSlider = new wxSlider(this, wxID_VOLSLIDER, 100, // init
0, // start
100, // end
wxDefaultPosition, wxSize(250,20),
wxSL_HORIZONTAL );
horsizer3->Add(m_volSlider, 1, wxALL, 5);
m_pbSlider = new wxSlider(this, wxID_PBSLIDER, 4, // init
1, // start
16, // end
wxDefaultPosition, wxSize(250,20),
wxSL_HORIZONTAL );
horsizer3->Add(m_pbSlider, 1, wxALL, 5);
sizer->Add(horsizer3, 1, wxCENTRE | wxALL, 5);
//
// ListCtrl events
//
@@ -1651,10 +1676,20 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF
wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek));
this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBRELEASE,
wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek));
this->Connect(wxID_PBSLIDER, wxEVT_SCROLL_THUMBRELEASE,
wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange));
this->Connect(wxID_VOLSLIDER, wxEVT_SCROLL_THUMBRELEASE,
wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange));
//
// Media Control events
//
this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PLAY,
wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay));
this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PAUSE,
wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause));
this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_STOP,
wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop));
this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_FINISHED,
wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished));
this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_LOADED,
@@ -1724,9 +1759,67 @@ bool wxMediaPlayerNotebookPage::IsBeingDragged()
}
// ----------------------------------------------------------------------------
// OnMediaFinished
// wxMediaPlayerNotebookPage::OnVolChange
//
// Called when the media stops playing.
// Called when the user is done dragging the volume-changing slider
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent& WXUNUSED(event))
{
if( m_mediactrl->SetVolume(
m_volSlider->GetValue() / 100.0
) == false )
wxMessageBox(wxT("Couldn't set volume!"));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerNotebookPage::OnPBChange
//
// Called when the user is done dragging the speed-changing slider
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent& WXUNUSED(event))
{
if( m_mediactrl->SetPlaybackRate(
m_pbSlider->GetValue() * .25
) == false )
wxMessageBox(wxT("Couldn't set playbackrate!"));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerNotebookPage::OnMediaPlay
//
// Called when the media plays.
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent& WXUNUSED(event))
{
m_playlist->SetItem(m_nLastFileId, 0, wxT(">"));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerNotebookPage::OnMediaPause
//
// Called when the media is paused.
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent& WXUNUSED(event))
{
m_playlist->SetItem(m_nLastFileId, 0, wxT("||"));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerNotebookPage::OnMediaStop
//
// Called when the media stops.
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent& WXUNUSED(event))
{
m_playlist->SetItem(m_nLastFileId, 0, wxT("[]"));
}
// ----------------------------------------------------------------------------
// wxMediaPlayerNotebookPage::OnMediaFinished
//
// Called when the media finishes playing.
// Here we loop it if the user wants to (has been selected from file menu)
// ----------------------------------------------------------------------------
void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event))

View File

@@ -9,6 +9,8 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// TODO: Platform specific backend defaults?
//===========================================================================
// Definitions
//===========================================================================
@@ -17,6 +19,10 @@
// Pre-compiled header stuff
//---------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "mediactrl.h"
#endif
#include "wx/wxprec.h"
#ifdef __BORLANDC__
@@ -44,12 +50,15 @@
// RTTI and Event implementations
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IMPLEMENT_CLASS(wxMediaCtrl, wxControl)
IMPLEMENT_CLASS(wxMediaBackend, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent)
DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED)
DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED)
DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP)
IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
DEFINE_EVENT_TYPE(wxEVT_MEDIA_STATECHANGED)
DEFINE_EVENT_TYPE(wxEVT_MEDIA_PLAY)
DEFINE_EVENT_TYPE(wxEVT_MEDIA_PAUSE)
IMPLEMENT_CLASS(wxMediaBackend, wxObject);
IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED);
DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
@@ -228,7 +237,7 @@ bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
}
//---------------------------------------------------------------------------
// wxMediaCtrl::NextBackend
// wxMediaCtrl::NextBackend (static)
//
//
// Search through the RTTI hashmap one at a
@@ -239,8 +248,7 @@ bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
// STL isn't compatible with and will have a compilation error
// on a wxNode, however, wxHashTable::compatibility_iterator is
// incompatible with the old 2.4 stable version - but since
// we're in 2.5 only we don't need to worry about this
// static
// we're in 2.5+ only we don't need to worry about the new version
//---------------------------------------------------------------------------
wxClassInfo* wxMediaCtrl::NextBackend()
{
@@ -507,9 +515,37 @@ void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
m_ctrl->AddPendingEvent(theEvent);
}
#include "wx/html/forcelnk.h"
FORCE_LINK(basewxmediabackends)
void wxMediaBackendCommonBase::QueuePlayEvent()
{
QueueEvent(wxEVT_MEDIA_STATECHANGED);
QueueEvent(wxEVT_MEDIA_PLAY);
}
void wxMediaBackendCommonBase::QueuePauseEvent()
{
QueueEvent(wxEVT_MEDIA_STATECHANGED);
QueueEvent(wxEVT_MEDIA_PAUSE);
}
void wxMediaBackendCommonBase::QueueStopEvent()
{
QueueEvent(wxEVT_MEDIA_STATECHANGED);
QueueEvent(wxEVT_MEDIA_STOP);
}
//
// Force link default backends in -
// see http://wiki.wxwidgets.org/wiki.pl?RTTI
//
#include "wx/html/forcelnk.h"
#ifdef __WXMSW__ // MSW has huge backends so we do it seperately
FORCE_LINK(wxmediabackend_am);
FORCE_LINK(wxmediabackend_wmp10);
#else
FORCE_LINK(basewxmediabackends);
#endif
//---------------------------------------------------------------------------
// End of compilation guard and of file
//---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

2269
src/msw/mediactrl_am.cpp Normal file

File diff suppressed because it is too large Load Diff

1521
src/msw/mediactrl_wmp10.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/ole/activex.cpp
// Name: msw/ole/activex.cpp
// Purpose: wxActiveXContainer implementation
// Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
// Modified by:
@@ -25,15 +25,25 @@
#include "wx/dcclient.h"
#include "wx/math.h"
// I don't know why members of tagVARIANT aren't found when compiling
// with Wine
#ifndef __WINE__
#include "wx/msw/ole/activex.h"
// autointerfaces that we only use here
WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo, IProvideClassInfo)
WX_DECLARE_AUTOOLE(wxAutoITypeInfo, ITypeInfo)
WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint, IConnectionPoint)
WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer, IConnectionPointContainer)
DEFINE_EVENT_TYPE(wxEVT_ACTIVEX);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxActiveXContainer
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Ole class helpers (sort of MFC-like) from wxActiveX
#define DECLARE_OLE_UNKNOWN(cls)\
private:\
class TAutoInitInt\
@@ -59,21 +69,21 @@
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)\
@@ -83,7 +93,7 @@
{\
delete this;\
return 0;\
}\
};\
return refCount.l;\
}\
else\
@@ -93,7 +103,7 @@
{\
InterlockedIncrement(&lockCount.l);\
return lockCount.l;\
}\
};\
ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
{\
if (lockCount.l > 0)\
@@ -131,7 +141,52 @@
#define END_OLE_TABLE\
}
// ============================================================================
// implementation
// ============================================================================
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PixelsToHimetric
//
// Utility to convert from pixels to the himetric values in some COM methods
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#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) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
sz.cx = CONVERT(sz.cx, logX);
sz.cy = CONVERT(sz.cy, logY);
#undef CONVERT
#undef HIMETRIC_INCH
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// FrameSite
//
// Handles the actual wxActiveX container implementation
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class FrameSite :
public IOleClientSite,
public IOleInPlaceSiteEx,
@@ -207,7 +262,7 @@ public:
case DISPID_AMBIENT_SILENT:
V_BOOL(pVarResult)= TRUE;
return S_OK;
#ifndef __WINE__
case DISPID_AMBIENT_APPEARANCE:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_bAmbientAppearance;
@@ -242,7 +297,7 @@ public:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_bAmbientShowHatching;
break;
#endif
default:
return DISP_E_MEMBERNOTFOUND;
}
@@ -326,7 +381,7 @@ public:
if (! SUCCEEDED(hr))
{
return E_UNEXPECTED;
}
};
hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
if (! SUCCEEDED(hr))
@@ -334,7 +389,7 @@ public:
(*ppFrame)->Release();
*ppFrame = NULL;
return E_UNEXPECTED;
}
};
RECT rect;
::GetClientRect(m_hWndParent, &rect);
@@ -343,13 +398,13 @@ public:
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);
@@ -368,8 +423,18 @@ public:
{
if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
{
//
// Result of several hours and days of bug hunting -
// this is called by an object when it wants to resize
// itself to something different then our parent window -
// don't let it :)
//
// m_window->m_oleInPlaceObject->SetObjectRects(
// lprcPosRect, lprcPosRect);
RECT rcClient;
::GetClientRect(m_hWndParent, &rcClient);
m_window->m_oleInPlaceObject->SetObjectRects(
lprcPosRect, lprcPosRect);
&rcClient, &rcClient);
}
return S_OK;
}
@@ -419,8 +484,8 @@ public:
case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
default : return "Bad Enum";
}
}
};
};
const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
{
@@ -430,8 +495,8 @@ public:
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)
{
@@ -458,7 +523,7 @@ public:
HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
//********************IOleItemContainer***************************
HRESULT STDMETHODCALLTYPE
#if defined(__WXWINCE__)
#ifdef __WXWINCE__
GetObject
#elif defined(_UNICODE)
GetObjectW
@@ -558,11 +623,11 @@ public:
return E_FAIL;
m_window->m_docView->SetInPlaceSite(inPlaceSite);
}
};
m_window->m_docView->UIActivate(TRUE);
return S_OK;
}
};
protected:
@@ -601,10 +666,135 @@ DEFINE_OLE_TABLE(FrameSite)
OLE_IINTERFACE(IOleDocumentSite)
OLE_IINTERFACE(IAdviseSink)
OLE_IINTERFACE(IOleControlSite)
END_OLE_TABLE
END_OLE_TABLE;
wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxActiveXEvents
//
// Handles and sends activex events received from the ActiveX control
// to the appropriate wxEvtHandler
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class wxActiveXEvents : public IDispatch
{
private:
DECLARE_OLE_UNKNOWN(wxActiveXEvents);
wxActiveXContainer *m_activeX;
IID m_customId;
bool m_haveCustomId;
friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
public:
wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_haveCustomId(true), m_customId(iid) {}
virtual ~wxActiveXEvents()
{
}
// IDispatch
STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfoCount(unsigned int*)
{
return E_NOTIMPL;
}
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID WXUNUSED(riid),
LCID WXUNUSED(lcid),
WORD wFlags, DISPPARAMS * pDispParams,
VARIANT * WXUNUSED(pVarResult), EXCEPINFO * WXUNUSED(pExcepInfo),
unsigned int * WXUNUSED(puArgErr))
{
if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
return E_NOTIMPL;
wxASSERT(m_activeX);
// ActiveX Event
// Dispatch Event
wxActiveXEvent event;
event.SetEventType(wxEVT_ACTIVEX);
event.m_params.NullList();
event.m_dispid = dispIdMember;
// arguments
if (pDispParams)
{
for (DWORD i = pDispParams->cArgs; i > 0; i--)
{
VARIANTARG& va = pDispParams->rgvarg[i-1];
wxVariant vx;
// vx.SetName(px.name);
wxConvertOleToVariant(va, vx);
event.m_params.Append(vx);
}
}
// process the events from the activex method
m_activeX->ProcessEvent(event);
for (DWORD i = 0; i < pDispParams->cArgs; i++)
{
VARIANTARG& va = pDispParams->rgvarg[i];
wxVariant& vx =
event.m_params[pDispParams->cArgs - i - 1];
wxConvertVariantToOle(vx, va);
}
if(event.GetSkipped())
return DISP_E_MEMBERNOTFOUND;
return S_OK;
}
};
bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
{
if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
{
// WXOLE_TRACE("Found Custom Dispatch Interface");
*_interface = (IUnknown *) (IDispatch *) self;
desc = "Custom Dispatch Interface";
return true;
};
return false;
}
DEFINE_OLE_TABLE(wxActiveXEvents)
OLE_IINTERFACE(IUnknown)
OLE_INTERFACE(IID_IDispatch, IDispatch)
OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
END_OLE_TABLE;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxActiveXContainer
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//---------------------------------------------------------------------------
// wxActiveXContainer Constructor
//
// Initializes members and creates the native ActiveX container
//---------------------------------------------------------------------------
wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
REFIID iid, IUnknown* pUnk)
: m_realparent(parent)
{
m_bAmbientUserMode = true;
@@ -612,6 +802,12 @@ wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown*
CreateActiveX(iid, pUnk);
}
//---------------------------------------------------------------------------
// wxActiveXContainer Destructor
//
// Destroys members (the FrameSite et al. are destroyed implicitly
// through COM ref counting)
//---------------------------------------------------------------------------
wxActiveXContainer::~wxActiveXContainer()
{
// disconnect connection points
@@ -633,6 +829,14 @@ wxActiveXContainer::~wxActiveXContainer()
}
}
//---------------------------------------------------------------------------
// wxActiveXContainer::CreateActiveX
//
// Actually creates the ActiveX container through the FrameSite
// and sets up ActiveX events
//
// TODO: Document this more
//---------------------------------------------------------------------------
void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
{
HRESULT hret;
@@ -652,6 +856,111 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
// Get Dispatch interface
hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
//
// SETUP TYPEINFO AND ACTIVEX EVENTS
//
// get type info via class info
wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
wxASSERT(classInfo.Ok());
// type info
wxAutoITypeInfo typeInfo;
hret = classInfo->GetClassInfo(typeInfo.GetRef());
wxASSERT(typeInfo.Ok());
// TYPEATTR
TYPEATTR *ta = NULL;
hret = typeInfo->GetTypeAttr(&ta);
wxASSERT(ta);
// this should be a TKIND_COCLASS
wxASSERT(ta->typekind == TKIND_COCLASS);
// iterate contained interfaces
for (int i = 0; i < ta->cImplTypes; i++)
{
HREFTYPE rt = 0;
// get dispatch type info handle
hret = typeInfo->GetRefTypeOfImplType(i, &rt);
if (! SUCCEEDED(hret))
continue;
// get dispatch type info interface
wxAutoITypeInfo ti;
hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
if (! ti.Ok())
continue;
// check if default event sink
bool defInterface = false;
bool defEventSink = false;
int impTypeFlags = 0;
typeInfo->GetImplTypeFlags(i, &impTypeFlags);
if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
{
if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
{
// WXOLE_TRACEOUT("Default Event Sink");
defEventSink = true;
if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
{
// WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
defEventSink = false;
wxFAIL_MSG(wxT("Default event sink is in vtable!"));
}
}
else
{
// WXOLE_TRACEOUT("Default Interface");
defInterface = true;
}
}
// wxAutoOleInterface<> assumes a ref has already been added
// TYPEATTR
TYPEATTR *ta = NULL;
hret = ti->GetTypeAttr(&ta);
wxASSERT(ta);
if (ta->typekind == TKIND_DISPATCH)
{
// WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
if (defEventSink)
{
wxAutoIConnectionPoint cp;
DWORD adviseCookie = 0;
wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
wxASSERT( cpContainer.Ok());
HRESULT hret =
cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
wxASSERT ( SUCCEEDED(hret));
IDispatch* disp;
frame->QueryInterface(IID_IDispatch, (void**)&disp);
hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
&adviseCookie);
wxASSERT_MSG( SUCCEEDED(hret),
wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), hret)
);
}
}
ti->ReleaseTypeAttr(ta);
}
// free
typeInfo->ReleaseTypeAttr(ta);
//
// END
//
// Get IOleObject interface
hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
wxASSERT(SUCCEEDED(hret));
@@ -663,6 +972,8 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
// document advise
m_docAdviseCookie = 0;
hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
// TODO:Needed?
// hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
OleSetContainedObject(m_oleObject, TRUE);
OleRun(m_oleObject);
@@ -739,6 +1050,8 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
pWnd->Connect(id, wxEVT_SIZE,
wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
// this->Connect(GetId(), wxEVT_PAINT,
// wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
pWnd->Connect(id, wxEVT_SET_FOCUS,
wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
pWnd->Connect(id, wxEVT_KILL_FOCUS,
@@ -746,34 +1059,12 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
}
}
#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) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
sz.cx = CONVERT(sz.cx, logX);
sz.cy = CONVERT(sz.cy, logY);
#undef CONVERT
#undef HIMETRIC_INCH
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnSize
//
// Called when the parent is resized - we need to do this to actually
// move the ActiveX control to where the parent is
//---------------------------------------------------------------------------
void wxActiveXContainer::OnSize(wxSizeEvent& event)
{
int w, h;
@@ -791,6 +1082,9 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
// extents are in HIMETRIC units
if (m_oleObject.Ok())
{
m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
SIZEL sz = {w, h};
PixelsToHimetric(sz);
@@ -799,7 +1093,10 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
if (sz2.cx != sz.cx || sz.cy != sz2.cy)
m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
};
m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
}
if (m_oleInPlaceObject.Ok())
m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
@@ -807,12 +1104,39 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
event.Skip();
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnPaint
//
// Called when the parent is resized - repaints the ActiveX control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
// Draw only when control is windowless or deactivated
if (m_viewObject)
{
#if 0
dc.BeginDrawing();
RECT rcClient;
::GetClientRect((HWND)GetHandle(), &rcClient);
HBITMAP hBitmap = CreateCompatibleBitmap((HDC)dc.GetHDC(),
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top);
HDC hdcCompatible = ::CreateCompatibleDC((HDC)dc.GetHDC());
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcCompatible, hBitmap);
m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
hdcCompatible, (RECTL *) &rcClient, (RECTL *) &rcClient, NULL, 0);
::BitBlt((HDC)dc.GetHDC(), 0, 0, rcClient.right, rcClient.bottom, hdcCompatible, 0, 0, SRCCOPY);
::SelectObject(hdcCompatible, hBitmapOld);
::DeleteObject(hBitmap);
::DeleteDC(hdcCompatible);
dc.EndDrawing();
#else
dc.BeginDrawing();
int w, h;
GetParent()->GetSize(&w, &h);
RECT posRect;
@@ -821,20 +1145,21 @@ void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
posRect.right = w;
posRect.bottom = h;
#if defined(_WIN32_WCE) && _WIN32_WCE < 400
::InvalidateRect(m_oleObjectHWND, NULL, false);
#else
::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
#endif
RECTL *prcBounds = (RECTL *) &posRect;
m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
(HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
}
// We've got this one I think
// event.Skip();
dc.EndDrawing();
#endif
}
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnSetFocus
//
// Called when the focus is set on the parent - activates the activex control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
@@ -843,6 +1168,12 @@ void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
event.Skip();
}
//---------------------------------------------------------------------------
// wxActiveXContainer::OnKillFocus
//
// Called when the focus is killed on the parent -
// deactivates the activex control
//---------------------------------------------------------------------------
void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
@@ -850,3 +1181,6 @@ void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
event.Skip();
}
#endif
// __WINE__

File diff suppressed because it is too large Load Diff