00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "shockwavegraph.h"
00024 #include "resource.h"
00025 #include "..\..\DSUtil\DSUtil.h"
00026
00027 CShockwaveGraph::CShockwaveGraph(HWND hParent, HRESULT& hr)
00028 : m_fs(State_Stopped)
00029 {
00030 hr = S_OK;
00031
00032 if(!m_wndWindowFrame.Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
00033 CRect(0, 0, 0, 0), CWnd::FromHandle(hParent), 0, NULL))
00034 {
00035 hr = E_FAIL;
00036 return;
00037 }
00038
00039 if(!m_wndDestFrame.Create(NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
00040 CRect(0, 0, 0, 0), &m_wndWindowFrame, 0))
00041 {
00042 hr = E_FAIL;
00043 return;
00044 }
00045 }
00046
00047 CShockwaveGraph::~CShockwaveGraph()
00048 {
00049 m_wndDestFrame.DestroyWindow();
00050 m_wndWindowFrame.DestroyWindow();
00051 }
00052
00053
00054 STDMETHODIMP CShockwaveGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
00055 {
00056 try {m_wndDestFrame.LoadMovie(0, CString(lpcwstrFile));}
00057 catch(CException* e) {e->Delete(); return E_FAIL;}
00058 return S_OK;
00059 }
00060
00061
00062 STDMETHODIMP CShockwaveGraph::Run()
00063 {
00064 try {if(m_fs != State_Running) m_wndDestFrame.Play();}
00065 catch(CException* e) {e->Delete(); return E_FAIL;}
00066 m_fs = State_Running;
00067 m_wndWindowFrame.EnableWindow();
00068
00069 return S_OK;
00070 }
00071 STDMETHODIMP CShockwaveGraph::Pause()
00072 {
00073 try {if(m_fs == State_Running) m_wndDestFrame.Stop();}
00074 catch(CException* e) {e->Delete(); return E_FAIL;}
00075 m_fs = State_Paused;
00076 return S_OK;
00077 }
00078 STDMETHODIMP CShockwaveGraph::Stop()
00079 {
00080 try {m_wndDestFrame.Stop();}
00081 catch(CException* e) {e->Delete(); return E_FAIL;}
00082 m_fs = State_Stopped;
00083 return S_OK;
00084 }
00085 STDMETHODIMP CShockwaveGraph::GetState(LONG msTimeout, OAFilterState* pfs)
00086 {
00087 OAFilterState fs = m_fs;
00088
00089 try
00090 {
00091 if(m_wndDestFrame.IsPlaying() && m_fs == State_Stopped) m_fs = State_Running;
00092 else if(!m_wndDestFrame.IsPlaying() && m_fs == State_Running) m_fs = State_Stopped;
00093 fs = m_fs;
00094 }
00095 catch(CException* e)
00096 {
00097 e->Delete();
00098 return E_FAIL;
00099 }
00100
00101 return pfs ? *pfs = fs, S_OK : E_POINTER;
00102 }
00103
00104
00105 STDMETHODIMP CShockwaveGraph::IsFormatSupported(const GUID* pFormat)
00106 {
00107 return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_FRAME ? S_OK : S_FALSE;
00108 }
00109 STDMETHODIMP CShockwaveGraph::GetTimeFormat(GUID* pFormat)
00110 {
00111 return pFormat ? *pFormat = TIME_FORMAT_FRAME, S_OK : E_POINTER;
00112 }
00113 STDMETHODIMP CShockwaveGraph::GetDuration(LONGLONG* pDuration)
00114 {
00115 CheckPointer(pDuration, E_POINTER);
00116 *pDuration = 0;
00117 try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pDuration = m_wndDestFrame.get_TotalFrames();}
00118 catch(CException* e) {e->Delete(); return E_FAIL;}
00119 return S_OK;
00120 }
00121 STDMETHODIMP CShockwaveGraph::GetCurrentPosition(LONGLONG* pCurrent)
00122 {
00123 CheckPointer(pCurrent, E_POINTER);
00124 *pCurrent = 0;
00125 try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pCurrent = m_wndDestFrame.get_FrameNum();}
00126 catch(CException* e) {e->Delete(); return E_FAIL;}
00127 return S_OK;
00128 }
00129 STDMETHODIMP CShockwaveGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
00130 {
00131 if(dwCurrentFlags&AM_SEEKING_AbsolutePositioning)
00132 {
00133 m_wndDestFrame.put_FrameNum(*pCurrent);
00134
00135 if(m_fs == State_Running && !m_wndDestFrame.IsPlaying())
00136 m_wndDestFrame.Play();
00137 else if((m_fs == State_Paused || m_fs == State_Stopped) && m_wndDestFrame.IsPlaying())
00138 m_wndDestFrame.Stop();
00139
00140 m_wndDestFrame.put_Quality(1);
00141
00142 return S_OK;
00143 }
00144
00145 return E_INVALIDARG;
00146 }
00147
00148
00149 STDMETHODIMP CShockwaveGraph::put_Visible(long Visible)
00150 {
00151 if(IsWindow(m_wndDestFrame.m_hWnd))
00152 m_wndDestFrame.ShowWindow(Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE);
00153 return S_OK;
00154 }
00155 STDMETHODIMP CShockwaveGraph::get_Visible(long* pVisible)
00156 {
00157 return pVisible ? *pVisible = (m_wndDestFrame.IsWindowVisible() ? OATRUE : OAFALSE), S_OK : E_POINTER;
00158 }
00159 STDMETHODIMP CShockwaveGraph::SetWindowPosition(long Left, long Top, long Width, long Height)
00160 {
00161 if(IsWindow(m_wndWindowFrame.m_hWnd))
00162 m_wndWindowFrame.MoveWindow(Left, Top, Width, Height);
00163
00164 return S_OK;
00165 }
00166
00167
00168 STDMETHODIMP CShockwaveGraph::SetDestinationPosition(long Left, long Top, long Width, long Height)
00169 {
00170 if(IsWindow(m_wndDestFrame.m_hWnd))
00171 m_wndDestFrame.MoveWindow(Left, Top, Width, Height);
00172
00173 return S_OK;
00174 }
00175 STDMETHODIMP CShockwaveGraph::GetVideoSize(long* pWidth, long* pHeight)
00176 {
00177 if(!pWidth || !pHeight) return E_POINTER;
00178
00179 CRect r;
00180 m_wndWindowFrame.GetWindowRect(r);
00181 if(!r.IsRectEmpty())
00182 {
00183 *pWidth = r.Width();
00184 *pHeight = r.Height();
00185 }
00186 else
00187 {
00188
00189 *pWidth = 384;
00190 *pHeight = 288;
00191
00192 NotifyEvent(EC_BG_AUDIO_CHANGED, 2, 0);
00193 }
00194
00195 return S_OK;
00196 }
00197
00198 #include <math.h>
00199
00200
00201 STDMETHODIMP CShockwaveGraph::put_Volume(long lVolume)
00202 {
00203 lVolume = (lVolume == -10000) ? 0 : (int)pow(10.0, ((double)lVolume)/5000+2);
00204 lVolume = lVolume*0x10000/100;
00205 lVolume = max(min(lVolume, 0xffff), 0);
00206 waveOutSetVolume(0, (lVolume<<16)|lVolume);
00207
00208 return S_OK;
00209 }
00210 STDMETHODIMP CShockwaveGraph::get_Volume(long* plVolume)
00211 {
00212 CheckPointer(plVolume, E_POINTER);
00213
00214 waveOutGetVolume(0, (DWORD*)plVolume);
00215 *plVolume = (*plVolume&0xffff + ((*plVolume>>16)&0xffff)) / 2;
00216 *plVolume = *plVolume*100/0x10000;
00217 *plVolume = (int)((log10(1.0*(*plVolume))-2)*5000);
00218 *plVolume = max(min(*plVolume, 0), -10000);
00219
00220 return S_OK;
00221 }
00222
00223
00224 STDMETHODIMP CShockwaveGraph::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent)
00225 {
00226 *pllTotal = 100;
00227 *pllCurrent = m_wndDestFrame.PercentLoaded();
00228 return S_OK;
00229 }
00230
00231
00232 STDMETHODIMP_(engine_t) CShockwaveGraph::GetEngine() {return ShockWave;}