-/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG (www.casparcg.com).\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-* Author: Nicklas P Andersson\r
-*/\r
-\r
-#include "../stdafx.h"\r
-\r
-#include "FlashAxContainer.h"\r
-#include "../interop/TimerHelper.h"\r
-\r
-#include <common/log.h>\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (push, 2) // TODO\r
-#endif\r
-\r
-using namespace ATL;\r
-\r
-namespace caspar { namespace flash {\r
-\r
-CComBSTR FlashAxContainer::flashGUID_(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}"));\r
-\r
-_ATL_FUNC_INFO fnInfoFlashCallEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };\r
-_ATL_FUNC_INFO fnInfoReadyStateChangeEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };\r
-\r
-FlashAxContainer::FlashAxContainer() : bInPlaceActive_(FALSE), pTimerHelper(0), bInvalidRect_(false), bReadyToRender_(false), bHasNewTiming_(false), m_lpDD4(0), timerCount_(0), bIsEmpty_(true)\r
-{\r
-}\r
-FlashAxContainer::~FlashAxContainer()\r
-{ \r
- if(m_lpDD4)\r
- {\r
- m_lpDD4->Release();\r
- m_lpDD4 = nullptr;\r
- }\r
-\r
- if(pTimerHelper != 0)\r
- delete pTimerHelper;\r
-}\r
-\r
-\r
-/////////\r
-// IObjectWithSite\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)\r
-{\r
- ATLTRACE(_T("IObjectWithSite::SetSite\n"));\r
- HRESULT hr = IObjectWithSiteImpl<FlashAxContainer>::SetSite(pUnkSite);\r
-\r
- if (SUCCEEDED(hr) && m_spUnkSite)\r
- {\r
- // Look for "outer" IServiceProvider\r
- hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices);\r
- ATLASSERT( !hr && _T("No ServiceProvider!") );\r
- }\r
-\r
- if (pUnkSite == NULL)\r
- m_spServices.Release();\r
-\r
- return hr;\r
-}\r
-\r
-/////////\r
-// IOleClientSite\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject()\r
-{\r
- ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk)\r
-{\r
-/* if(*ppmk != NULL) {\r
- if(m_spMyMoniker == NULL) {\r
- ATL::CComObject<MyMoniker>* pMoniker = NULL;\r
- HRESULT hr = ATL::CComObject<MyMoniker>::CreateInstance(&pMoniker);\r
- if(SUCCEEDED(hr))\r
- m_spMyMoniker = pMoniker;\r
- }\r
-\r
- if(m_spMyMoniker != NULL) {\r
- *ppmk = m_spMyMoniker;\r
- (*ppmk)->AddRef();\r
- return S_OK;\r
- }\r
- }\r
-*/ if(ppmk != NULL)\r
- *ppmk = NULL;\r
- return E_FAIL;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetContainer(IOleContainer** ppContainer)\r
-{\r
- ATLTRACE(_T("IOleClientSite::GetContainer\n"));\r
- (*ppContainer) = NULL;\r
- return E_NOINTERFACE;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowObject()\r
-{\r
- ATLTRACE(_T("IOleClientSite::ShowObject\n"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnShowWindow(BOOL fShow)\r
-{\r
- ATLTRACE(_T("IOleClientSite::OnShowWindow"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout()\r
-{\r
- ATLTRACE(_T("IOleClientSite::RequestNewObjectLayout"));\r
- return S_OK;\r
-}\r
-\r
-/////////\r
-// IOleInPlaceSite\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::GetWindow\n"));\r
- (*pHwnd) = NULL;//GetApplication()->GetMainWindow()->getHwnd();\r
- return E_FAIL;\r
-}\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::ContextSensitiveHelp(BOOL fEnterMode)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::ContextSensitiveHelp"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::CanInPlaceActivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::CanInPlaceActivate\n"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::OnInPlaceActivate"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIActivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::OnUIActivate\n"));\r
- bUIActive_ = TRUE;\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::GetWindowContext\n"));\r
- if (ppFrame != NULL)\r
- *ppFrame = NULL;\r
- if (ppDoc != NULL)\r
- *ppDoc = NULL;\r
-\r
- if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL)\r
- return E_POINTER;\r
-\r
- pFrameInfo->fMDIApp = FALSE;\r
- pFrameInfo->haccel = NULL;\r
- pFrameInfo->cAccelEntries = 0;\r
- pFrameInfo->hwndFrame = NULL;\r
-\r
- lprcPosRect->top = m_rcPos.top;\r
- lprcPosRect->left = m_rcPos.left;\r
- lprcPosRect->right = m_rcPos.right;\r
- lprcPosRect->bottom = m_rcPos.bottom;\r
-\r
- lprcClipRect->top = m_rcPos.top;\r
- lprcClipRect->left = m_rcPos.left;\r
- lprcClipRect->right = m_rcPos.right;\r
- lprcClipRect->bottom = m_rcPos.bottom;\r
-\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::Scroll(SIZE scrollExtant)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::Scroll"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIDeactivate(BOOL fUndoable)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::OnUIDeactivate\n"));\r
- bUIActive_ = FALSE;\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::OnInPlaceDeactivate\n"));\r
- bInPlaceActive_ = FALSE;\r
- m_spInPlaceObjectWindowless.Release();\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::DiscardUndoState()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::DiscardUndoState"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::DeactivateAndUndo()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::DeactivateAndUndo"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSite::OnPosRectChange"));\r
- return S_OK;\r
-}\r
-\r
-\r
-//////////\r
-// IOleInPlaceSiteEx\r
-//////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags)\r
-{\r
- // should only be called once the first time control is inplace-activated\r
- ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceActivateEx\n"));\r
- ATLASSERT(bInPlaceActive_ == FALSE);\r
- ATLASSERT(m_spInPlaceObjectWindowless == NULL);\r
-\r
- bInPlaceActive_ = TRUE;\r
- OleLockRunning(m_spOleObject, TRUE, FALSE);\r
- HRESULT hr = E_FAIL;\r
- if (dwFlags & ACTIVATE_WINDOWLESS)\r
- {\r
- hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless);\r
-\r
- if (m_spInPlaceObjectWindowless != NULL)\r
- m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
- }\r
-\r
- return (m_spInPlaceObjectWindowless != NULL) ? S_OK : E_FAIL;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivateEx(BOOL fNoRedraw)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceDeactivateEx\n"));\r
- bInPlaceActive_ = FALSE;\r
- m_spInPlaceObjectWindowless.Release();\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteEx::RequestUIActivate\n"));\r
- return S_OK;\r
-}\r
-\r
-\r
-//////////////\r
-// IOleInPlaceSiteWindowless\r
-//////////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n"));\r
- return S_OK;\r
-// return S_FALSE;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetCapture()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::GetCapture\n"));\r
- return bCapture_ ? S_OK : S_FALSE;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::SetCapture(BOOL fCapture)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::SetCapture\n"));\r
- bCapture_ = fCapture;\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetFocus()\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::GetFocus\n"));\r
- return bHaveFocus_ ? S_OK : S_FALSE;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::SetFocus(BOOL fGotFocus)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::SetFocus\n"));\r
- bHaveFocus_ = fGotFocus;\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::GetDC"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::ReleaseDC(HDC hDC)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::ReleaseDC"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRect(LPCRECT pRect, BOOL fErase)\r
-{\r
-// ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRect\n"));\r
- \r
- bInvalidRect_ = true;\r
-\r
-/* //Keep a list of dirty rectangles in order to be able to redraw only them\r
- if(pRect != NULL) {\r
- bDirtyRects_.push_back(DirtyRect(*pRect, fErase != 0));\r
- }\r
- else {\r
- bDirtyRects_.push_back(DirtyRect(true));\r
- }\r
-*/ return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRgn(HRGN hRGN, BOOL fErase)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRng\n"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::ScrollRect"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::AdjustRect(LPRECT prc)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::AdjustRect"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)\r
-{\r
- ATLTRACE(_T("IOleInPlaceSiteWindowless::OnDefWindowMessage"));\r
- return S_OK;\r
-}\r
-\r
-/////////\r
-// IOleControlSite\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged()\r
-{\r
- ATLTRACE(_T("IOleControlSite::OnControlInfoChanged"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::LockInPlaceActive(BOOL fLock)\r
-{\r
- ATLTRACE(_T("IOleControlSite::LockInPlaceActive"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetExtendedControl(IDispatch** ppDisp)\r
-{\r
- ATLTRACE(_T("IOleControlSite::GetExtendedControl"));\r
-\r
- if (ppDisp == NULL)\r
- return E_POINTER;\r
- return m_spOleObject.QueryInterface(ppDisp);\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)\r
-{\r
- ATLTRACE(_T("IOleControlSite::TransformCoords"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::TranslateAccelerator(LPMSG lpMsg, DWORD grfModifiers)\r
-{\r
- ATLTRACE(_T("IOleControlSite::TranslateAccelerator"));\r
- return S_FALSE;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::OnFocus(BOOL fGotFocus)\r
-{\r
- bHaveFocus_ = fGotFocus;\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame()\r
-{\r
- ATLTRACE(_T("IOleControlSite::ShowPropertyFrame"));\r
- return S_OK;\r
-}\r
-\r
-\r
-/////////\r
-// IAdviseSink\r
-/////////\r
-void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed)\r
-{\r
- ATLTRACE(_T("IAdviseSink::OnDataChange\n"));\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnViewChange(DWORD dwAspect, LONG lindex)\r
-{\r
- ATLTRACE(_T("IAdviseSink::OnViewChange\n"));\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnRename(IMoniker* pmk)\r
-{\r
- ATLTRACE(_T("IAdviseSink::OnRename\n"));\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnSave()\r
-{\r
- ATLTRACE(_T("IAdviseSink::OnSave\n"));\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnClose()\r
-{\r
- ATLTRACE(_T("IAdviseSink::OnClose\n"));\r
-}\r
-\r
-\r
-//DirectDraw GUIDS\r
-\r
-DEFINE_GUID2(CLSID_DirectDraw,0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35);\r
-DEFINE_GUID2(CLSID_DirectDraw7,0x3c305196,0x50db,0x11d3,0x9c,0xfe,0x00,0xc0,0x4f,0xd9,0x30,0xc5);\r
-\r
-DEFINE_GUID2(IID_IDirectDraw,0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);\r
-DEFINE_GUID2(IID_IDirectDraw3,0x618f8ad4,0x8b7a,0x11d0,0x8f,0xcc,0x0,0xc0,0x4f,0xd9,0x18,0x9d);\r
-DEFINE_GUID2(IID_IDirectDraw4,0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5);\r
-DEFINE_GUID2(IID_IDirectDraw7,0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);\r
-\r
-/////////\r
-// IServiceProvider\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj) \r
-{\r
-// ATLTRACE(_T("IServiceProvider::QueryService\n"));\r
- //the flashcontrol asks for an interface {618F8AD4-8B7A-11D0-8FCC-00C04FD9189D}, this is IID for a DirectDraw3 object\r
-\r
- ATLASSERT(ppvObj != NULL);\r
- if (ppvObj == NULL)\r
- return E_POINTER;\r
- *ppvObj = NULL;\r
- \r
- HRESULT hr;\r
- // Author: Makarov Igor\r
- // Transparent Flash Control in Plain C++ \r
- // http://www.codeproject.com/KB/COM/flashcontrol.aspx \r
- if (IsEqualGUID(rsid, IID_IDirectDraw3))\r
- {\r
- if (!m_lpDD4)\r
- {\r
- m_lpDD4 = new IDirectDraw4Ptr;\r
- hr = m_lpDD4->CreateInstance(CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER); \r
- if (FAILED(hr))\r
- {\r
- delete m_lpDD4;\r
- m_lpDD4 = NULL;\r
- CASPAR_LOG(info) << print_() << " DirectDraw not installed. Running without DirectDraw.";\r
- return E_NOINTERFACE;\r
- }\r
- }\r
- if (m_lpDD4 && m_lpDD4->GetInterfacePtr())\r
- {\r
- *ppvObj = m_lpDD4->GetInterfacePtr();\r
- m_lpDD4->AddRef();\r
- return S_OK;\r
- }\r
- }\r
-\r
- //TODO: The fullscreen-consumer requires that ths does NOT return an ITimerService\r
- hr = QueryInterface(riid, ppvObj);//E_NOINTERFACE;\r
-\r
- return hr;\r
-}\r
-\r
-\r
-/////////\r
-// ITimerService\r
-/////////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)\r
-{\r
- ATLTRACE(_T("ITimerService::CreateTimer\n"));\r
- if(pTimerHelper != 0)\r
- {\r
- delete pTimerHelper;\r
- pTimerHelper = 0;\r
- }\r
- pTimerHelper = new TimerHelper();\r
- return QueryInterface(__uuidof(ITimer), (void**) ppNewTimer);\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetNamedTimer(REFGUID rguidName, ITimer **ppTimer)\r
-{\r
- ATLTRACE(_T("ITimerService::GetNamedTimer"));\r
- if(ppTimer == NULL)\r
- return E_POINTER;\r
- else\r
- *ppTimer = NULL;\r
-\r
- return E_FAIL;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer)\r
-{\r
- ATLTRACE(_T("ITimerService::SetNamedTimerReference"));\r
- return S_OK;\r
-}\r
-\r
-//////\r
-// ITimer\r
-//////\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie)\r
-{\r
- ATLTRACE(_T("Timer::Advise\n"));\r
-\r
- if(pdwCookie == 0)\r
- return E_POINTER;\r
-\r
- if(pTimerHelper != 0)\r
- {\r
- pTimerHelper->Setup(vtimeMin.ulVal, vtimeInterval.ulVal, pTimerSink);\r
- *pdwCookie = pTimerHelper->ID;\r
- bHasNewTiming_ = true;\r
-\r
- return S_OK;\r
- }\r
- else\r
- return E_OUTOFMEMORY;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::Unadvise(/* [in] */ DWORD dwCookie)\r
-{\r
- ATLTRACE(_T("Timer::Unadvice\n"));\r
- if(pTimerHelper != 0)\r
- {\r
- pTimerHelper->pTimerSink = 0;\r
- return S_OK;\r
- }\r
- else\r
- return E_FAIL;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::Freeze(/* [in] */ BOOL fFreeze)\r
-{\r
- ATLTRACE(_T("Timer::Freeze\n"));\r
- return S_OK;\r
-}\r
-\r
-HRESULT STDMETHODCALLTYPE FlashAxContainer::GetTime(/* [out] */ VARIANT *pvtime)\r
-{\r
- ATLTRACE(_T("Timer::GetTime\n"));\r
- if(pvtime == 0)\r
- return E_POINTER;\r
-\r
-// return E_NOTIMPL;\r
- pvtime->lVal = 0;\r
- return S_OK;\r
-}\r
-\r
-double FlashAxContainer::GetFPS() {\r
- if(pTimerHelper != 0 && pTimerHelper->interval > 0)\r
- return (1000.0 / static_cast<double>(pTimerHelper->interval));\r
- \r
- return 0.0;\r
-}\r
-\r
-bool FlashAxContainer::IsReadyToRender() const {\r
- return bReadyToRender_;\r
-}\r
-\r
-void FlashAxContainer::EnterFullscreen()\r
-{\r
- if(m_spInPlaceObjectWindowless != 0)\r
- {\r
- LRESULT result;\r
- m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1), &result);\r
- m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(1, 1), &result);\r
- }\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnFlashCall(BSTR request)\r
-{\r
- std::wstring str(request);\r
- if(str.find(TEXT("DisplayedTemplate")) != std::wstring::npos)\r
- {\r
- ATLTRACE(_T("ShockwaveFlash::DisplayedTemplate\n"));\r
- bReadyToRender_ = true;\r
- }\r
- else if(str.find(TEXT("OnCommand")) != std::wstring::npos) {\r
- //this is how templatehost 1.8 reports that a command has been received\r
- CASPAR_LOG(debug) << print_() << L" [command] " << str;\r
- bCallSuccessful_ = true;\r
- }\r
- else if(str.find(TEXT("Activity")) != std::wstring::npos)\r
- {\r
- CASPAR_LOG(debug) << print_() << L" [activity] " << str;\r
-\r
- //this is how templatehost 1.7 reports that a command has been received\r
- if(str.find(TEXT("Command recieved")) != std::wstring::npos)\r
- bCallSuccessful_ = true;\r
-\r
- /*if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
- std::wstring::size_type pos = str.find(TEXT('@'));\r
- if(pos != std::wstring::npos)\r
- pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
- }*/\r
- }\r
- else if(str.find(TEXT("OnNotify")) != std::wstring::npos)\r
- {\r
- CASPAR_LOG(info) << print_() << L" [notification] " << str;\r
-\r
- //if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
- // std::wstring::size_type pos = str.find(TEXT('@'));\r
- // if(pos != std::wstring::npos)\r
- // pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
- //}\r
- }\r
- else if(str.find(TEXT("IsEmpty")) != std::wstring::npos)\r
- {\r
- CASPAR_LOG(trace) << print_() << L" Empty.";\r
- ATLTRACE(_T("ShockwaveFlash::IsEmpty\n"));\r
- bIsEmpty_ = true;\r
- }\r
- else if(str.find(TEXT("OnError")) != std::wstring::npos)\r
- {\r
- CASPAR_LOG(error) << print_() << L" [error] " << str;\r
- }\r
- else if(str.find(TEXT("OnDebug")) != std::wstring::npos)\r
- {\r
- CASPAR_LOG(debug) << print_() << L" [debug] " << str;\r
- }\r
- //else if(str.find(TEXT("OnTemplateDescription")) != std::wstring::npos)\r
- //{\r
- // CASPAR_LOG(error) << print_() << L" TemplateDescription: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
- //}\r
- //else if(str.find(TEXT("OnGetInfo")) != std::wstring::npos)\r
- //{\r
- // CASPAR_LOG(error) << print_() << L" Info: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
- //}\r
- //else\r
- //{\r
- // CASPAR_LOG(error) << print_() << L" Unknown: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
- //}\r
-\r
- CComPtr<IShockwaveFlash> spFlash;\r
- HRESULT hr = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
- if(hr == S_OK && spFlash)\r
- {\r
- hr = spFlash->SetReturnValue(TEXT("<null/>"));\r
- }\r
-}\r
-\r
-void STDMETHODCALLTYPE FlashAxContainer::OnReadyStateChange(long newState)\r
-{\r
- if(newState == 4)\r
- {\r
- bReadyToRender_ = true;\r
- }\r
- else\r
- bReadyToRender_ = false;\r
-}\r
-\r
-void FlashAxContainer::DestroyAxControl()\r
-{\r
- GetControllingUnknown()->AddRef();\r
-\r
- if ((!m_spViewObject) == false)\r
- m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);\r
-\r
- if ((!m_spOleObject) == false)\r
- {\r
- DispEventUnadvise(m_spOleObject, &DIID__IShockwaveFlashEvents);\r
- m_spOleObject->Unadvise(m_dwOleObject);\r
- m_spOleObject->Close(OLECLOSE_NOSAVE);\r
- m_spOleObject->SetClientSite(NULL);\r
- }\r
-\r
- if ((!m_spUnknown) == false)\r
- {\r
- CComPtr<IObjectWithSite> spSite;\r
- m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
- if (spSite != NULL)\r
- spSite->SetSite(NULL);\r
- }\r
-\r
- if ((!m_spViewObject) == false)\r
- m_spViewObject.Release();\r
-\r
- if ((!m_spInPlaceObjectWindowless) == false)\r
- m_spInPlaceObjectWindowless.Release();\r
-\r
- if ((!m_spOleObject) == false)\r
- m_spOleObject.Release();\r
-\r
- if ((!m_spUnknown) == false)\r
- m_spUnknown.Release();\r
-}\r
-\r
-bool FlashAxContainer::CheckForFlashSupport()\r
-{\r
- CLSID clsid;\r
- return SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID_, &clsid));\r
-}\r
-\r
-HRESULT FlashAxContainer::CreateAxControl()\r
-{\r
- CLSID clsid;\r
- HRESULT hr = CLSIDFromString((LPOLESTR)flashGUID_, &clsid); \r
- if(SUCCEEDED(hr))\r
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)&m_spUnknown);\r
-\r
-//Start ActivateAx\r
- if(SUCCEEDED(hr))\r
- {\r
- m_spUnknown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);\r
- if(m_spOleObject)\r
- {\r
- m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);\r
- if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
- {\r
- CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
- m_spOleObject->SetClientSite(spClientSite);\r
- }\r
-\r
- //Initialize control\r
- CComQIPtr<IPersistStreamInit> spPSI(m_spOleObject);\r
- if (spPSI)\r
- hr = spPSI->InitNew();\r
-\r
- if (FAILED(hr)) // If the initialization of the control failed...\r
- {\r
- // Clean up and return\r
- if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
- m_spOleObject->SetClientSite(NULL);\r
-\r
- m_dwMiscStatus = 0;\r
- m_spOleObject.Release();\r
- m_spUnknown.Release();\r
-\r
- return hr;\r
- }\r
- //end Initialize object\r
-\r
- if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))\r
- {\r
- CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
- m_spOleObject->SetClientSite(spClientSite);\r
- }\r
-\r
- CComPtr<IShockwaveFlash> spFlash;\r
- HRESULT hResultQuality;\r
- HRESULT hr2 = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
- if(hr2 == S_OK && spFlash)\r
- {\r
- if(FAILED(spFlash->put_WMode(TEXT("Transparent"))))\r
- CASPAR_LOG(warning) << print_() << L" Failed to set flash container to transparent mode.";\r
- //spFlash->put_WMode(TEXT("ogl"));\r
- hResultQuality = spFlash->put_Quality2(TEXT("Best"));\r
- }\r
- if(SUCCEEDED(DispEventAdvise(spFlash, &DIID__IShockwaveFlashEvents)))\r
- {\r
- }\r
-\r
- HRESULT hrView = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);\r
-\r
- CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());\r
- m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);\r
- if (m_spViewObject)\r
- m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);\r
-\r
- if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)\r
- {\r
- //Initialize window to some dummy size\r
- m_rcPos.top = 0;\r
- m_rcPos.left = 0;\r
- m_rcPos.right = 720;\r
- m_rcPos.bottom = 576;\r
-\r
- m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
- m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
- AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
- m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
- m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
- AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
- m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
- m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
-\r
- CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
- hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);\r
- }\r
- }\r
- CComPtr<IObjectWithSite> spSite;\r
- m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
- if (spSite != NULL)\r
- spSite->SetSite(GetControllingUnknown());\r
- }\r
-//End ActivateAx\r
-\r
-// hr = E_FAIL;\r
- if (FAILED(hr) || m_spUnknown == NULL)\r
- {\r
- return E_FAIL;\r
- // We don't have a control or something failed so release\r
-// ReleaseAll();\r
- }\r
-\r
- return S_OK;\r
-}\r
-\r
-void FlashAxContainer::SetSize(size_t width, size_t height) {\r
- if(m_spInPlaceObjectWindowless != 0)\r
- {\r
- m_rcPos.top = 0;\r
- m_rcPos.left = 0;\r
- m_rcPos.right = width;\r
- m_rcPos.bottom = height;\r
-\r
- m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
- m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
- AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
- m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
- m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
- AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
- m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
- m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
-\r
- m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
- bInvalidRect_ = true;\r
- }\r
-}\r
-\r
-HRESULT FlashAxContainer::QueryControl(REFIID iid, void** ppUnk)\r
-{\r
- ATLASSERT(ppUnk != NULL);\r
- if (ppUnk == NULL)\r
- return E_POINTER;\r
- HRESULT hr;\r
- hr = m_spOleObject->QueryInterface(iid, ppUnk);\r
- return hr;\r
-}\r
-\r
-bool FlashAxContainer::DrawControl(HDC targetDC)\r
-{\r
-// ATLTRACE(_T("FlashAxContainer::DrawControl\n"));\r
- DVASPECTINFO aspectInfo = {sizeof(DVASPECTINFO), DVASPECTINFOFLAG_CANOPTIMIZE};\r
- HRESULT hr = S_OK;\r
-\r
- hr = m_spViewObject->Draw(DVASPECT_CONTENT, -1, &aspectInfo, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
- bInvalidRect_ = false;\r
-/* const video_format_desc& fmtDesc = video_format_desc::FormatDescriptions[format_];\r
-\r
- //Trying to redraw just the dirty rectangles. Doesn't seem to work when the movie uses "filters", such as glow, dropshadow etc.\r
- std::vector<flash::DirtyRect>::iterator it = bDirtyRects_.begin();\r
- std::vector<flash::DirtyRect>::iterator end = bDirtyRects_.end();\r
- for(; it != end; ++it) {\r
- flash::DirtyRect& dirtyRect = (*it);\r
- if(dirtyRect.bWhole || dirtyRect.rect.right >= fmtDesc.width || dirtyRect.rect.bottom >= fmtDesc.height) {\r
- m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
- hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
- break;\r
- }\r
- else {\r
- m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &(dirtyRect.rect));\r
- hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
- }\r
- }\r
- bDirtyRects_.clear();\r
-*/\r
-\r
- return (hr == S_OK);\r
-}\r
-\r
-void FlashAxContainer::Tick()\r
-{\r
- if(pTimerHelper)\r
- {\r
- DWORD time = pTimerHelper->Invoke(); // Tick flash\r
- if(time - timerCount_ >= 400)\r
- {\r
- timerCount_ = time;\r
- LRESULT hr;\r
- m_spInPlaceObjectWindowless->OnWindowMessage(WM_TIMER, 3, 0, &hr);\r
- }\r
- }\r
-}\r
-\r
-bool FlashAxContainer::FlashCall(const std::wstring& str, std::wstring& result2)\r
-{\r
- CComBSTR result;\r
- CComPtr<IShockwaveFlash> spFlash;\r
- QueryControl(&spFlash);\r
- CComBSTR request(str.c_str());\r
- \r
- bIsEmpty_ = false;\r
- bCallSuccessful_ = false;\r
- for(size_t retries = 0; !bCallSuccessful_ && retries < 4; ++retries)\r
- spFlash->CallFunction(request, &result);\r
-\r
- if(bCallSuccessful_)\r
- result2 = result;\r
-\r
- return bCallSuccessful_;\r
-}\r
-\r
-} //namespace flash\r
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Nicklas P Andersson
+*/
+
+#include "../stdafx.h"
+
+#include "FlashAxContainer.h"
+#include "../interop/TimerHelper.h"
+
+#include <common/log.h>
+
+#if defined(_MSC_VER)
+#pragma warning (push, 2) // TODO
+#endif
+
+using namespace ATL;
+
+namespace caspar { namespace flash {
+
+CComBSTR FlashAxContainer::flashGUID_(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}"));
+
+_ATL_FUNC_INFO fnInfoFlashCallEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
+_ATL_FUNC_INFO fnInfoReadyStateChangeEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };
+
+FlashAxContainer::FlashAxContainer() : bInPlaceActive_(FALSE), pTimerHelper(0), bInvalidRect_(false), bReadyToRender_(false), bHasNewTiming_(false), m_lpDD4(0), timerCount_(0), bIsEmpty_(true)
+{
+}
+FlashAxContainer::~FlashAxContainer()
+{
+ if(m_lpDD4)
+ {
+ m_lpDD4->Release();
+ m_lpDD4 = nullptr;
+ }
+
+ if(pTimerHelper != 0)
+ delete pTimerHelper;
+}
+
+
+/////////
+// IObjectWithSite
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)
+{
+ ATLTRACE(_T("IObjectWithSite::SetSite\n"));
+ HRESULT hr = IObjectWithSiteImpl<FlashAxContainer>::SetSite(pUnkSite);
+
+ if (SUCCEEDED(hr) && m_spUnkSite)
+ {
+ // Look for "outer" IServiceProvider
+ hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices);
+ ATLASSERT( !hr && _T("No ServiceProvider!") );
+ }
+
+ if (pUnkSite == NULL)
+ m_spServices.Release();
+
+ return hr;
+}
+
+/////////
+// IOleClientSite
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject()
+{
+ ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk)
+{
+/* if(*ppmk != NULL) {
+ if(m_spMyMoniker == NULL) {
+ ATL::CComObject<MyMoniker>* pMoniker = NULL;
+ HRESULT hr = ATL::CComObject<MyMoniker>::CreateInstance(&pMoniker);
+ if(SUCCEEDED(hr))
+ m_spMyMoniker = pMoniker;
+ }
+
+ if(m_spMyMoniker != NULL) {
+ *ppmk = m_spMyMoniker;
+ (*ppmk)->AddRef();
+ return S_OK;
+ }
+ }
+*/ if(ppmk != NULL)
+ *ppmk = NULL;
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetContainer(IOleContainer** ppContainer)
+{
+ ATLTRACE(_T("IOleClientSite::GetContainer\n"));
+ (*ppContainer) = NULL;
+ return E_NOINTERFACE;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowObject()
+{
+ ATLTRACE(_T("IOleClientSite::ShowObject\n"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnShowWindow(BOOL fShow)
+{
+ ATLTRACE(_T("IOleClientSite::OnShowWindow"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout()
+{
+ ATLTRACE(_T("IOleClientSite::RequestNewObjectLayout"));
+ return S_OK;
+}
+
+/////////
+// IOleInPlaceSite
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd)
+{
+ ATLTRACE(_T("IOleInPlaceSite::GetWindow\n"));
+ (*pHwnd) = NULL;//GetApplication()->GetMainWindow()->getHwnd();
+ return E_FAIL;
+}
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ContextSensitiveHelp(BOOL fEnterMode)
+{
+ ATLTRACE(_T("IOleInPlaceSite::ContextSensitiveHelp"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CanInPlaceActivate()
+{
+ ATLTRACE(_T("IOleInPlaceSite::CanInPlaceActivate\n"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivate()
+{
+ ATLTRACE(_T("IOleInPlaceSite::OnInPlaceActivate"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIActivate()
+{
+ ATLTRACE(_T("IOleInPlaceSite::OnUIActivate\n"));
+ bUIActive_ = TRUE;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)
+{
+ ATLTRACE(_T("IOleInPlaceSite::GetWindowContext\n"));
+ if (ppFrame != NULL)
+ *ppFrame = NULL;
+ if (ppDoc != NULL)
+ *ppDoc = NULL;
+
+ if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL)
+ return E_POINTER;
+
+ pFrameInfo->fMDIApp = FALSE;
+ pFrameInfo->haccel = NULL;
+ pFrameInfo->cAccelEntries = 0;
+ pFrameInfo->hwndFrame = NULL;
+
+ lprcPosRect->top = m_rcPos.top;
+ lprcPosRect->left = m_rcPos.left;
+ lprcPosRect->right = m_rcPos.right;
+ lprcPosRect->bottom = m_rcPos.bottom;
+
+ lprcClipRect->top = m_rcPos.top;
+ lprcClipRect->left = m_rcPos.left;
+ lprcClipRect->right = m_rcPos.right;
+ lprcClipRect->bottom = m_rcPos.bottom;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Scroll(SIZE scrollExtant)
+{
+ ATLTRACE(_T("IOleInPlaceSite::Scroll"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIDeactivate(BOOL fUndoable)
+{
+ ATLTRACE(_T("IOleInPlaceSite::OnUIDeactivate\n"));
+ bUIActive_ = FALSE;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivate()
+{
+ ATLTRACE(_T("IOleInPlaceSite::OnInPlaceDeactivate\n"));
+ bInPlaceActive_ = FALSE;
+ m_spInPlaceObjectWindowless.Release();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::DiscardUndoState()
+{
+ ATLTRACE(_T("IOleInPlaceSite::DiscardUndoState"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::DeactivateAndUndo()
+{
+ ATLTRACE(_T("IOleInPlaceSite::DeactivateAndUndo"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect)
+{
+ ATLTRACE(_T("IOleInPlaceSite::OnPosRectChange"));
+ return S_OK;
+}
+
+
+//////////
+// IOleInPlaceSiteEx
+//////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags)
+{
+ // should only be called once the first time control is inplace-activated
+ ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceActivateEx\n"));
+ ATLASSERT(bInPlaceActive_ == FALSE);
+ ATLASSERT(m_spInPlaceObjectWindowless == NULL);
+
+ bInPlaceActive_ = TRUE;
+ OleLockRunning(m_spOleObject, TRUE, FALSE);
+ HRESULT hr = E_FAIL;
+ if (dwFlags & ACTIVATE_WINDOWLESS)
+ {
+ hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless);
+
+ if (m_spInPlaceObjectWindowless != NULL)
+ m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);
+ }
+
+ return (m_spInPlaceObjectWindowless != NULL) ? S_OK : E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivateEx(BOOL fNoRedraw)
+{
+ ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceDeactivateEx\n"));
+ bInPlaceActive_ = FALSE;
+ m_spInPlaceObjectWindowless.Release();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate()
+{
+ ATLTRACE(_T("IOleInPlaceSiteEx::RequestUIActivate\n"));
+ return S_OK;
+}
+
+
+//////////////
+// IOleInPlaceSiteWindowless
+//////////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate()
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n"));
+ return S_OK;
+// return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetCapture()
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::GetCapture\n"));
+ return bCapture_ ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetCapture(BOOL fCapture)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::SetCapture\n"));
+ bCapture_ = fCapture;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetFocus()
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::GetFocus\n"));
+ return bHaveFocus_ ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetFocus(BOOL fGotFocus)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::SetFocus\n"));
+ bHaveFocus_ = fGotFocus;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::GetDC"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ReleaseDC(HDC hDC)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::ReleaseDC"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRect(LPCRECT pRect, BOOL fErase)
+{
+// ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRect\n"));
+
+ bInvalidRect_ = true;
+
+/* //Keep a list of dirty rectangles in order to be able to redraw only them
+ if(pRect != NULL) {
+ bDirtyRects_.push_back(DirtyRect(*pRect, fErase != 0));
+ }
+ else {
+ bDirtyRects_.push_back(DirtyRect(true));
+ }
+*/ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRgn(HRGN hRGN, BOOL fErase)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRng\n"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::ScrollRect"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::AdjustRect(LPRECT prc)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::AdjustRect"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
+{
+ ATLTRACE(_T("IOleInPlaceSiteWindowless::OnDefWindowMessage"));
+ return S_OK;
+}
+
+/////////
+// IOleControlSite
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged()
+{
+ ATLTRACE(_T("IOleControlSite::OnControlInfoChanged"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::LockInPlaceActive(BOOL fLock)
+{
+ ATLTRACE(_T("IOleControlSite::LockInPlaceActive"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetExtendedControl(IDispatch** ppDisp)
+{
+ ATLTRACE(_T("IOleControlSite::GetExtendedControl"));
+
+ if (ppDisp == NULL)
+ return E_POINTER;
+ return m_spOleObject.QueryInterface(ppDisp);
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)
+{
+ ATLTRACE(_T("IOleControlSite::TransformCoords"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::TranslateAccelerator(LPMSG lpMsg, DWORD grfModifiers)
+{
+ ATLTRACE(_T("IOleControlSite::TranslateAccelerator"));
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::OnFocus(BOOL fGotFocus)
+{
+ bHaveFocus_ = fGotFocus;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame()
+{
+ ATLTRACE(_T("IOleControlSite::ShowPropertyFrame"));
+ return S_OK;
+}
+
+
+/////////
+// IAdviseSink
+/////////
+void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed)
+{
+ ATLTRACE(_T("IAdviseSink::OnDataChange\n"));
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnViewChange(DWORD dwAspect, LONG lindex)
+{
+ ATLTRACE(_T("IAdviseSink::OnViewChange\n"));
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnRename(IMoniker* pmk)
+{
+ ATLTRACE(_T("IAdviseSink::OnRename\n"));
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnSave()
+{
+ ATLTRACE(_T("IAdviseSink::OnSave\n"));
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnClose()
+{
+ ATLTRACE(_T("IAdviseSink::OnClose\n"));
+}
+
+
+//DirectDraw GUIDS
+
+DEFINE_GUID2(CLSID_DirectDraw,0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35);
+DEFINE_GUID2(CLSID_DirectDraw7,0x3c305196,0x50db,0x11d3,0x9c,0xfe,0x00,0xc0,0x4f,0xd9,0x30,0xc5);
+
+DEFINE_GUID2(IID_IDirectDraw,0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);
+DEFINE_GUID2(IID_IDirectDraw3,0x618f8ad4,0x8b7a,0x11d0,0x8f,0xcc,0x0,0xc0,0x4f,0xd9,0x18,0x9d);
+DEFINE_GUID2(IID_IDirectDraw4,0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5);
+DEFINE_GUID2(IID_IDirectDraw7,0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);
+
+/////////
+// IServiceProvider
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj)
+{
+// ATLTRACE(_T("IServiceProvider::QueryService\n"));
+ //the flashcontrol asks for an interface {618F8AD4-8B7A-11D0-8FCC-00C04FD9189D}, this is IID for a DirectDraw3 object
+
+ ATLASSERT(ppvObj != NULL);
+ if (ppvObj == NULL)
+ return E_POINTER;
+ *ppvObj = NULL;
+
+ HRESULT hr;
+ // Author: Makarov Igor
+ // Transparent Flash Control in Plain C++
+ // http://www.codeproject.com/KB/COM/flashcontrol.aspx
+ if (IsEqualGUID(rsid, IID_IDirectDraw3))
+ {
+ if (!m_lpDD4)
+ {
+ m_lpDD4 = new IDirectDraw4Ptr;
+ hr = m_lpDD4->CreateInstance(CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER);
+ if (FAILED(hr))
+ {
+ delete m_lpDD4;
+ m_lpDD4 = NULL;
+ CASPAR_LOG(info) << print_() << " DirectDraw not installed. Running without DirectDraw.";
+ return E_NOINTERFACE;
+ }
+ }
+ if (m_lpDD4 && m_lpDD4->GetInterfacePtr())
+ {
+ *ppvObj = m_lpDD4->GetInterfacePtr();
+ m_lpDD4->AddRef();
+ return S_OK;
+ }
+ }
+
+ //TODO: The fullscreen-consumer requires that ths does NOT return an ITimerService
+ hr = QueryInterface(riid, ppvObj);//E_NOINTERFACE;
+
+ return hr;
+}
+
+
+/////////
+// ITimerService
+/////////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)
+{
+ ATLTRACE(_T("ITimerService::CreateTimer\n"));
+ if(pTimerHelper != 0)
+ {
+ delete pTimerHelper;
+ pTimerHelper = 0;
+ }
+ pTimerHelper = new TimerHelper();
+ return QueryInterface(__uuidof(ITimer), (void**) ppNewTimer);
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetNamedTimer(REFGUID rguidName, ITimer **ppTimer)
+{
+ ATLTRACE(_T("ITimerService::GetNamedTimer"));
+ if(ppTimer == NULL)
+ return E_POINTER;
+ else
+ *ppTimer = NULL;
+
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer)
+{
+ ATLTRACE(_T("ITimerService::SetNamedTimerReference"));
+ return S_OK;
+}
+
+//////
+// ITimer
+//////
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie)
+{
+ ATLTRACE(_T("Timer::Advise\n"));
+
+ if(pdwCookie == 0)
+ return E_POINTER;
+
+ if(pTimerHelper != 0)
+ {
+ pTimerHelper->Setup(vtimeMin.ulVal, vtimeInterval.ulVal, pTimerSink);
+ *pdwCookie = pTimerHelper->ID;
+ bHasNewTiming_ = true;
+
+ return S_OK;
+ }
+ else
+ return E_OUTOFMEMORY;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Unadvise(/* [in] */ DWORD dwCookie)
+{
+ ATLTRACE(_T("Timer::Unadvice\n"));
+ if(pTimerHelper != 0)
+ {
+ pTimerHelper->pTimerSink = 0;
+ return S_OK;
+ }
+ else
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::Freeze(/* [in] */ BOOL fFreeze)
+{
+ ATLTRACE(_T("Timer::Freeze\n"));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FlashAxContainer::GetTime(/* [out] */ VARIANT *pvtime)
+{
+ ATLTRACE(_T("Timer::GetTime\n"));
+ if(pvtime == 0)
+ return E_POINTER;
+
+// return E_NOTIMPL;
+ pvtime->lVal = 0;
+ return S_OK;
+}
+
+double FlashAxContainer::GetFPS() {
+ if(pTimerHelper != 0 && pTimerHelper->interval > 0)
+ return (1000.0 / static_cast<double>(pTimerHelper->interval));
+
+ return 0.0;
+}
+
+bool FlashAxContainer::IsReadyToRender() const {
+ return bReadyToRender_;
+}
+
+void FlashAxContainer::EnterFullscreen()
+{
+ if(m_spInPlaceObjectWindowless != 0)
+ {
+ LRESULT result;
+ m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1), &result);
+ m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(1, 1), &result);
+ }
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnFlashCall(BSTR request)
+{
+ std::wstring str(request);
+ if(str.find(TEXT("DisplayedTemplate")) != std::wstring::npos)
+ {
+ ATLTRACE(_T("ShockwaveFlash::DisplayedTemplate\n"));
+ bReadyToRender_ = true;
+ }
+ else if(str.find(TEXT("OnCommand")) != std::wstring::npos) {
+ //this is how templatehost 1.8 reports that a command has been received
+ CASPAR_LOG(debug) << print_() << L" [command] " << str;
+ bCallSuccessful_ = true;
+ }
+ else if(str.find(TEXT("Activity")) != std::wstring::npos)
+ {
+ CASPAR_LOG(debug) << print_() << L" [activity] " << str;
+
+ //this is how templatehost 1.7 reports that a command has been received
+ if(str.find(TEXT("Command recieved")) != std::wstring::npos)
+ bCallSuccessful_ = true;
+
+ /*if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {
+ std::wstring::size_type pos = str.find(TEXT('@'));
+ if(pos != std::wstring::npos)
+ pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));
+ }*/
+ }
+ else if(str.find(TEXT("OnNotify")) != std::wstring::npos)
+ {
+ CASPAR_LOG(info) << print_() << L" [notification] " << str;
+
+ //if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {
+ // std::wstring::size_type pos = str.find(TEXT('@'));
+ // if(pos != std::wstring::npos)
+ // pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));
+ //}
+ }
+ else if(str.find(TEXT("IsEmpty")) != std::wstring::npos)
+ {
+ CASPAR_LOG(trace) << print_() << L" Empty.";
+ ATLTRACE(_T("ShockwaveFlash::IsEmpty\n"));
+ bIsEmpty_ = true;
+ }
+ else if(str.find(TEXT("OnError")) != std::wstring::npos)
+ {
+ CASPAR_LOG(error) << print_() << L" [error] " << str;
+ }
+ else if(str.find(TEXT("OnDebug")) != std::wstring::npos)
+ {
+ CASPAR_LOG(debug) << print_() << L" [debug] " << str;
+ }
+ //else if(str.find(TEXT("OnTemplateDescription")) != std::wstring::npos)
+ //{
+ // CASPAR_LOG(error) << print_() << L" TemplateDescription: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";
+ //}
+ //else if(str.find(TEXT("OnGetInfo")) != std::wstring::npos)
+ //{
+ // CASPAR_LOG(error) << print_() << L" Info: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";
+ //}
+ //else
+ //{
+ // CASPAR_LOG(error) << print_() << L" Unknown: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";
+ //}
+
+ CComPtr<IShockwaveFlash> spFlash;
+ HRESULT hr = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);
+ if(hr == S_OK && spFlash)
+ {
+ hr = spFlash->SetReturnValue(TEXT("<null/>"));
+ }
+}
+
+void STDMETHODCALLTYPE FlashAxContainer::OnReadyStateChange(long newState)
+{
+ if(newState == 4)
+ {
+ bReadyToRender_ = true;
+ }
+ else
+ bReadyToRender_ = false;
+}
+
+void FlashAxContainer::DestroyAxControl()
+{
+ GetControllingUnknown()->AddRef();
+
+ if ((!m_spViewObject) == false)
+ m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);
+
+ if ((!m_spOleObject) == false)
+ {
+ DispEventUnadvise(m_spOleObject, &DIID__IShockwaveFlashEvents);
+ m_spOleObject->Unadvise(m_dwOleObject);
+ m_spOleObject->Close(OLECLOSE_NOSAVE);
+ m_spOleObject->SetClientSite(NULL);
+ }
+
+ if ((!m_spUnknown) == false)
+ {
+ CComPtr<IObjectWithSite> spSite;
+ m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);
+ if (spSite != NULL)
+ spSite->SetSite(NULL);
+ }
+
+ if ((!m_spViewObject) == false)
+ m_spViewObject.Release();
+
+ if ((!m_spInPlaceObjectWindowless) == false)
+ m_spInPlaceObjectWindowless.Release();
+
+ if ((!m_spOleObject) == false)
+ m_spOleObject.Release();
+
+ if ((!m_spUnknown) == false)
+ m_spUnknown.Release();
+}
+
+bool FlashAxContainer::CheckForFlashSupport()
+{
+ CLSID clsid;
+ return SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID_, &clsid));
+}
+
+HRESULT FlashAxContainer::CreateAxControl()
+{
+ CLSID clsid;
+ HRESULT hr = CLSIDFromString((LPOLESTR)flashGUID_, &clsid);
+ if(SUCCEEDED(hr))
+ hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)&m_spUnknown);
+
+//Start ActivateAx
+ if(SUCCEEDED(hr))
+ {
+ m_spUnknown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);
+ if(m_spOleObject)
+ {
+ m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
+ if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
+ {
+ CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
+ m_spOleObject->SetClientSite(spClientSite);
+ }
+
+ //Initialize control
+ CComQIPtr<IPersistStreamInit> spPSI(m_spOleObject);
+ if (spPSI)
+ hr = spPSI->InitNew();
+
+ if (FAILED(hr)) // If the initialization of the control failed...
+ {
+ // Clean up and return
+ if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
+ m_spOleObject->SetClientSite(NULL);
+
+ m_dwMiscStatus = 0;
+ m_spOleObject.Release();
+ m_spUnknown.Release();
+
+ return hr;
+ }
+ //end Initialize object
+
+ if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
+ {
+ CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
+ m_spOleObject->SetClientSite(spClientSite);
+ }
+
+ CComPtr<IShockwaveFlash> spFlash;
+ HRESULT hResultQuality;
+ HRESULT hr2 = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);
+ if(hr2 == S_OK && spFlash)
+ {
+ if(FAILED(spFlash->put_WMode(TEXT("Transparent"))))
+ CASPAR_LOG(warning) << print_() << L" Failed to set flash container to transparent mode.";
+ //spFlash->put_WMode(TEXT("ogl"));
+ hResultQuality = spFlash->put_Quality2(TEXT("Best"));
+ }
+ if(SUCCEEDED(DispEventAdvise(spFlash, &DIID__IShockwaveFlashEvents)))
+ {
+ }
+
+ HRESULT hrView = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);
+
+ CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());
+ m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);
+ if (m_spViewObject)
+ m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);
+
+ if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)
+ {
+ //Initialize window to some dummy size
+ m_rcPos.top = 0;
+ m_rcPos.left = 0;
+ m_rcPos.right = 720;
+ m_rcPos.bottom = 576;
+
+ m_pxSize.cx = m_rcPos.right - m_rcPos.left;
+ m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;
+ AtlPixelToHiMetric(&m_pxSize, &m_hmSize);
+ m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);
+ m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);
+ AtlHiMetricToPixel(&m_hmSize, &m_pxSize);
+ m_rcPos.right = m_rcPos.left + m_pxSize.cx;
+ m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;
+
+ CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
+ hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);
+ }
+ }
+ CComPtr<IObjectWithSite> spSite;
+ m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);
+ if (spSite != NULL)
+ spSite->SetSite(GetControllingUnknown());
+ }
+//End ActivateAx
+
+// hr = E_FAIL;
+ if (FAILED(hr) || m_spUnknown == NULL)
+ {
+ return E_FAIL;
+ // We don't have a control or something failed so release
+// ReleaseAll();
+ }
+
+ return S_OK;
+}
+
+void FlashAxContainer::SetSize(size_t width, size_t height) {
+ if(m_spInPlaceObjectWindowless != 0)
+ {
+ m_rcPos.top = 0;
+ m_rcPos.left = 0;
+ m_rcPos.right = width;
+ m_rcPos.bottom = height;
+
+ m_pxSize.cx = m_rcPos.right - m_rcPos.left;
+ m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;
+ AtlPixelToHiMetric(&m_pxSize, &m_hmSize);
+ m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);
+ m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);
+ AtlHiMetricToPixel(&m_hmSize, &m_pxSize);
+ m_rcPos.right = m_rcPos.left + m_pxSize.cx;
+ m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;
+
+ m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);
+ bInvalidRect_ = true;
+ }
+}
+
+HRESULT FlashAxContainer::QueryControl(REFIID iid, void** ppUnk)
+{
+ ATLASSERT(ppUnk != NULL);
+ if (ppUnk == NULL)
+ return E_POINTER;
+ HRESULT hr;
+ hr = m_spOleObject->QueryInterface(iid, ppUnk);
+ return hr;
+}
+
+bool FlashAxContainer::DrawControl(HDC targetDC)
+{
+// ATLTRACE(_T("FlashAxContainer::DrawControl\n"));
+ DVASPECTINFO aspectInfo = {sizeof(DVASPECTINFO), DVASPECTINFOFLAG_CANOPTIMIZE};
+ HRESULT hr = S_OK;
+
+ hr = m_spViewObject->Draw(DVASPECT_CONTENT, -1, &aspectInfo, NULL, NULL, targetDC, NULL, NULL, NULL, NULL);
+ bInvalidRect_ = false;
+/* const video_format_desc& fmtDesc = video_format_desc::FormatDescriptions[format_];
+
+ //Trying to redraw just the dirty rectangles. Doesn't seem to work when the movie uses "filters", such as glow, dropshadow etc.
+ std::vector<flash::DirtyRect>::iterator it = bDirtyRects_.begin();
+ std::vector<flash::DirtyRect>::iterator end = bDirtyRects_.end();
+ for(; it != end; ++it) {
+ flash::DirtyRect& dirtyRect = (*it);
+ if(dirtyRect.bWhole || dirtyRect.rect.right >= fmtDesc.width || dirtyRect.rect.bottom >= fmtDesc.height) {
+ m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);
+ hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL);
+ break;
+ }
+ else {
+ m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &(dirtyRect.rect));
+ hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL);
+ }
+ }
+ bDirtyRects_.clear();
+*/
+
+ return (hr == S_OK);
+}
+
+void FlashAxContainer::Tick()
+{
+ if(pTimerHelper)
+ {
+ DWORD time = pTimerHelper->Invoke(); // Tick flash
+ if(time - timerCount_ >= 400)
+ {
+ timerCount_ = time;
+ LRESULT hr;
+ m_spInPlaceObjectWindowless->OnWindowMessage(WM_TIMER, 3, 0, &hr);
+ }
+ }
+}
+
+bool FlashAxContainer::FlashCall(const std::wstring& str, std::wstring& result2)
+{
+ CComBSTR result;
+ CComPtr<IShockwaveFlash> spFlash;
+ QueryControl(&spFlash);
+ CComBSTR request(str.c_str());
+
+ bIsEmpty_ = false;
+ bCallSuccessful_ = false;
+ for(size_t retries = 0; !bCallSuccessful_ && retries < 4; ++retries)
+ spFlash->CallFunction(request, &result);
+
+ if(bCallSuccessful_)
+ result2 = result;
+
+ return bCallSuccessful_;
+}
+
+} //namespace flash
} //namespace caspar
\ No newline at end of file