]> git.sesse.net Git - casparcg/blob - modules/flash/producer/FlashAxContainer.cpp
2.0.2: Intergrated channel-exp branch:
[casparcg] / modules / flash / producer / FlashAxContainer.cpp
1 /*\r
2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 *  This file is part of CasparCG.\r
5 *\r
6 *    CasparCG is free software: you can redistribute it and/or modify\r
7 *    it under the terms of the GNU General Public License as published by\r
8 *    the Free Software Foundation, either version 3 of the License, or\r
9 *    (at your option) any later version.\r
10 *\r
11 *    CasparCG is distributed in the hope that it will be useful,\r
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 *    GNU General Public License for more details.\r
15 \r
16 *    You should have received a copy of the GNU General Public License\r
17 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 */\r
20  \r
21 #include "../stdafx.h"\r
22 \r
23 #include "FlashAxContainer.h"\r
24 #include "../interop/TimerHelper.h"\r
25 \r
26 #include <common/log/log.h>\r
27 \r
28 #if defined(_MSC_VER)\r
29 #pragma warning (push, 2) // TODO\r
30 #endif\r
31 \r
32 using namespace ATL;\r
33 \r
34 namespace caspar { namespace flash {\r
35 \r
36 CComBSTR FlashAxContainer::flashGUID_(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}"));\r
37 \r
38 _ATL_FUNC_INFO fnInfoFlashCallEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };\r
39 _ATL_FUNC_INFO fnInfoReadyStateChangeEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };\r
40 \r
41 FlashAxContainer::FlashAxContainer() : bInPlaceActive_(FALSE), pTimerHelper(0), bInvalidRect_(false), bReadyToRender_(false), bHasNewTiming_(false), m_lpDD4(0), timerCount_(0)\r
42 {\r
43 }\r
44 FlashAxContainer::~FlashAxContainer()\r
45 {       \r
46         if(m_lpDD4)\r
47         {\r
48                 m_lpDD4->Release();\r
49                 m_lpDD4 = nullptr;\r
50         }\r
51 \r
52         if(pTimerHelper != 0)\r
53                 delete pTimerHelper;\r
54 }\r
55 \r
56 \r
57 ///////////////////\r
58 // IObjectWithSite\r
59 ///////////////////\r
60 HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite)\r
61 {\r
62         ATLTRACE(_T("IObjectWithSite::SetSite\n"));\r
63         HRESULT hr = IObjectWithSiteImpl<FlashAxContainer>::SetSite(pUnkSite);\r
64 \r
65         if (SUCCEEDED(hr) && m_spUnkSite)\r
66         {\r
67                 // Look for "outer" IServiceProvider\r
68                 hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices);\r
69                 ATLASSERT( !hr && _T("No ServiceProvider!") );\r
70         }\r
71 \r
72         if (pUnkSite == NULL)\r
73                 m_spServices.Release();\r
74 \r
75         return hr;\r
76 }\r
77 \r
78 ///////////////////\r
79 // IOleClientSite\r
80 ///////////////////\r
81 HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject()\r
82 {\r
83         ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));\r
84 }\r
85 \r
86 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk)\r
87 {\r
88 /*      if(*ppmk != NULL) {\r
89                 if(m_spMyMoniker == NULL) {\r
90                         ATL::CComObject<MyMoniker>* pMoniker = NULL;\r
91                         HRESULT hr = ATL::CComObject<MyMoniker>::CreateInstance(&pMoniker);\r
92                         if(SUCCEEDED(hr))\r
93                                 m_spMyMoniker = pMoniker;\r
94                 }\r
95 \r
96                 if(m_spMyMoniker != NULL) {\r
97                         *ppmk = m_spMyMoniker;\r
98                         (*ppmk)->AddRef();\r
99                         return S_OK;\r
100                 }\r
101         }\r
102 */      if(ppmk != NULL)\r
103                 *ppmk = NULL;\r
104         return E_FAIL;\r
105 }\r
106 \r
107 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetContainer(IOleContainer** ppContainer)\r
108 {\r
109         ATLTRACE(_T("IOleClientSite::GetContainer\n"));\r
110         (*ppContainer) = NULL;\r
111         return E_NOINTERFACE;\r
112 }\r
113 \r
114 HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowObject()\r
115 {\r
116         ATLTRACE(_T("IOleClientSite::ShowObject\n"));\r
117         return S_OK;\r
118 }\r
119 \r
120 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnShowWindow(BOOL fShow)\r
121 {\r
122         ATLTRACE(_T("IOleClientSite::OnShowWindow"));\r
123         return S_OK;\r
124 }\r
125 \r
126 HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout()\r
127 {\r
128         ATLTRACE(_T("IOleClientSite::RequestNewObjectLayout"));\r
129         return S_OK;\r
130 }\r
131 \r
132 ///////////////////\r
133 // IOleInPlaceSite\r
134 ///////////////////\r
135 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd)\r
136 {\r
137         ATLTRACE(_T("IOleInPlaceSite::GetWindow\n"));\r
138         (*pHwnd) = NULL;//GetApplication()->GetMainWindow()->getHwnd();\r
139         return E_FAIL;\r
140 }\r
141 HRESULT STDMETHODCALLTYPE FlashAxContainer::ContextSensitiveHelp(BOOL fEnterMode)\r
142 {\r
143         ATLTRACE(_T("IOleInPlaceSite::ContextSensitiveHelp"));\r
144         return S_OK;\r
145 }\r
146 \r
147 HRESULT STDMETHODCALLTYPE FlashAxContainer::CanInPlaceActivate()\r
148 {\r
149         ATLTRACE(_T("IOleInPlaceSite::CanInPlaceActivate\n"));\r
150         return S_OK;\r
151 }\r
152 \r
153 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivate()\r
154 {\r
155         ATLTRACE(_T("IOleInPlaceSite::OnInPlaceActivate"));\r
156         return S_OK;\r
157 }\r
158 \r
159 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIActivate()\r
160 {\r
161         ATLTRACE(_T("IOleInPlaceSite::OnUIActivate\n"));\r
162         bUIActive_ = TRUE;\r
163         return S_OK;\r
164 }\r
165 \r
166 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)\r
167 {\r
168         ATLTRACE(_T("IOleInPlaceSite::GetWindowContext\n"));\r
169         if (ppFrame != NULL)\r
170                 *ppFrame = NULL;\r
171         if (ppDoc != NULL)\r
172                 *ppDoc = NULL;\r
173 \r
174         if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL)\r
175                 return E_POINTER;\r
176 \r
177         pFrameInfo->fMDIApp = FALSE;\r
178         pFrameInfo->haccel = NULL;\r
179         pFrameInfo->cAccelEntries = 0;\r
180         pFrameInfo->hwndFrame = NULL;\r
181 \r
182         lprcPosRect->top = m_rcPos.top;\r
183         lprcPosRect->left = m_rcPos.left;\r
184         lprcPosRect->right = m_rcPos.right;\r
185         lprcPosRect->bottom = m_rcPos.bottom;\r
186 \r
187         lprcClipRect->top = m_rcPos.top;\r
188         lprcClipRect->left = m_rcPos.left;\r
189         lprcClipRect->right = m_rcPos.right;\r
190         lprcClipRect->bottom = m_rcPos.bottom;\r
191 \r
192         return S_OK;\r
193 }\r
194 \r
195 HRESULT STDMETHODCALLTYPE FlashAxContainer::Scroll(SIZE scrollExtant)\r
196 {\r
197         ATLTRACE(_T("IOleInPlaceSite::Scroll"));\r
198         return S_OK;\r
199 }\r
200 \r
201 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIDeactivate(BOOL fUndoable)\r
202 {\r
203         ATLTRACE(_T("IOleInPlaceSite::OnUIDeactivate\n"));\r
204         bUIActive_ = FALSE;\r
205         return S_OK;\r
206 }\r
207 \r
208 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivate()\r
209 {\r
210         ATLTRACE(_T("IOleInPlaceSite::OnInPlaceDeactivate\n"));\r
211         bInPlaceActive_ = FALSE;\r
212         m_spInPlaceObjectWindowless.Release();\r
213         return S_OK;\r
214 }\r
215 \r
216 HRESULT STDMETHODCALLTYPE FlashAxContainer::DiscardUndoState()\r
217 {\r
218         ATLTRACE(_T("IOleInPlaceSite::DiscardUndoState"));\r
219         return S_OK;\r
220 }\r
221 \r
222 HRESULT STDMETHODCALLTYPE FlashAxContainer::DeactivateAndUndo()\r
223 {\r
224         ATLTRACE(_T("IOleInPlaceSite::DeactivateAndUndo"));\r
225         return S_OK;\r
226 }\r
227 \r
228 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect)\r
229 {\r
230         ATLTRACE(_T("IOleInPlaceSite::OnPosRectChange"));\r
231         return S_OK;\r
232 }\r
233 \r
234 \r
235 /////////////////////\r
236 // IOleInPlaceSiteEx\r
237 /////////////////////\r
238 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags)\r
239 {\r
240         // should only be called once the first time control is inplace-activated\r
241         ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceActivateEx\n"));\r
242         ATLASSERT(bInPlaceActive_ == FALSE);\r
243         ATLASSERT(m_spInPlaceObjectWindowless == NULL);\r
244 \r
245         bInPlaceActive_ = TRUE;\r
246         OleLockRunning(m_spOleObject, TRUE, FALSE);\r
247         HRESULT hr = E_FAIL;\r
248         if (dwFlags & ACTIVATE_WINDOWLESS)\r
249         {\r
250                 hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless);\r
251 \r
252                 if (m_spInPlaceObjectWindowless != NULL)\r
253                         m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
254         }\r
255 \r
256         return (m_spInPlaceObjectWindowless != NULL) ? S_OK : E_FAIL;\r
257 }\r
258 \r
259 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivateEx(BOOL fNoRedraw)\r
260 {\r
261         ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceDeactivateEx\n"));\r
262         bInPlaceActive_ = FALSE;\r
263         m_spInPlaceObjectWindowless.Release();\r
264         return S_OK;\r
265 }\r
266 \r
267 HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate()\r
268 {\r
269         ATLTRACE(_T("IOleInPlaceSiteEx::RequestUIActivate\n"));\r
270         return S_OK;\r
271 }\r
272 \r
273 \r
274 /////////////////////////////\r
275 // IOleInPlaceSiteWindowless\r
276 /////////////////////////////\r
277 HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate()\r
278 {\r
279         ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n"));\r
280         return S_OK;\r
281 //      return S_FALSE;\r
282 }\r
283 \r
284 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetCapture()\r
285 {\r
286         ATLTRACE(_T("IOleInPlaceSiteWindowless::GetCapture\n"));\r
287         return bCapture_ ? S_OK : S_FALSE;\r
288 }\r
289 \r
290 HRESULT STDMETHODCALLTYPE FlashAxContainer::SetCapture(BOOL fCapture)\r
291 {\r
292         ATLTRACE(_T("IOleInPlaceSiteWindowless::SetCapture\n"));\r
293         bCapture_ = fCapture;\r
294         return S_OK;\r
295 }\r
296 \r
297 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetFocus()\r
298 {\r
299         ATLTRACE(_T("IOleInPlaceSiteWindowless::GetFocus\n"));\r
300         return bHaveFocus_ ? S_OK : S_FALSE;\r
301 }\r
302 \r
303 HRESULT STDMETHODCALLTYPE FlashAxContainer::SetFocus(BOOL fGotFocus)\r
304 {\r
305         ATLTRACE(_T("IOleInPlaceSiteWindowless::SetFocus\n"));\r
306         bHaveFocus_ = fGotFocus;\r
307         return S_OK;\r
308 }\r
309 \r
310 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC)\r
311 {\r
312         ATLTRACE(_T("IOleInPlaceSiteWindowless::GetDC"));\r
313         return S_OK;\r
314 }\r
315 \r
316 HRESULT STDMETHODCALLTYPE FlashAxContainer::ReleaseDC(HDC hDC)\r
317 {\r
318         ATLTRACE(_T("IOleInPlaceSiteWindowless::ReleaseDC"));\r
319         return S_OK;\r
320 }\r
321 \r
322 HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRect(LPCRECT pRect, BOOL fErase)\r
323 {\r
324 //      ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRect\n"));\r
325         \r
326         bInvalidRect_ = true;\r
327 \r
328 /*      //Keep a list of dirty rectangles in order to be able to redraw only them\r
329         if(pRect != NULL) {\r
330                 bDirtyRects_.push_back(DirtyRect(*pRect, fErase != 0));\r
331         }\r
332         else {\r
333                 bDirtyRects_.push_back(DirtyRect(true));\r
334         }\r
335 */      return S_OK;\r
336 }\r
337 \r
338 HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRgn(HRGN hRGN, BOOL fErase)\r
339 {\r
340         ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRng\n"));\r
341         return S_OK;\r
342 }\r
343 \r
344 HRESULT STDMETHODCALLTYPE FlashAxContainer::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)\r
345 {\r
346         ATLTRACE(_T("IOleInPlaceSiteWindowless::ScrollRect"));\r
347         return S_OK;\r
348 }\r
349 \r
350 HRESULT STDMETHODCALLTYPE FlashAxContainer::AdjustRect(LPRECT prc)\r
351 {\r
352         ATLTRACE(_T("IOleInPlaceSiteWindowless::AdjustRect"));\r
353         return S_OK;\r
354 }\r
355 \r
356 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)\r
357 {\r
358         ATLTRACE(_T("IOleInPlaceSiteWindowless::OnDefWindowMessage"));\r
359         return S_OK;\r
360 }\r
361 \r
362 ///////////////////\r
363 // IOleControlSite\r
364 ///////////////////\r
365 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged()\r
366 {\r
367         ATLTRACE(_T("IOleControlSite::OnControlInfoChanged"));\r
368         return S_OK;\r
369 }\r
370 \r
371 HRESULT STDMETHODCALLTYPE FlashAxContainer::LockInPlaceActive(BOOL fLock)\r
372 {\r
373         ATLTRACE(_T("IOleControlSite::LockInPlaceActive"));\r
374         return S_OK;\r
375 }\r
376 \r
377 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetExtendedControl(IDispatch** ppDisp)\r
378 {\r
379         ATLTRACE(_T("IOleControlSite::GetExtendedControl"));\r
380 \r
381         if (ppDisp == NULL)\r
382                 return E_POINTER;\r
383         return m_spOleObject.QueryInterface(ppDisp);\r
384 }\r
385 \r
386 HRESULT STDMETHODCALLTYPE FlashAxContainer::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)\r
387 {\r
388         ATLTRACE(_T("IOleControlSite::TransformCoords"));\r
389         return S_OK;\r
390 }\r
391 \r
392 HRESULT STDMETHODCALLTYPE FlashAxContainer::TranslateAccelerator(LPMSG lpMsg, DWORD grfModifiers)\r
393 {\r
394         ATLTRACE(_T("IOleControlSite::TranslateAccelerator"));\r
395         return S_FALSE;\r
396 }\r
397 \r
398 HRESULT STDMETHODCALLTYPE FlashAxContainer::OnFocus(BOOL fGotFocus)\r
399 {\r
400         bHaveFocus_ = fGotFocus;\r
401         return S_OK;\r
402 }\r
403 \r
404 HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame()\r
405 {\r
406         ATLTRACE(_T("IOleControlSite::ShowPropertyFrame"));\r
407         return S_OK;\r
408 }\r
409 \r
410 \r
411 ///////////////////\r
412 // IAdviseSink\r
413 ///////////////////\r
414 void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed)\r
415 {\r
416         ATLTRACE(_T("IAdviseSink::OnDataChange\n"));\r
417 }\r
418 \r
419 void STDMETHODCALLTYPE FlashAxContainer::OnViewChange(DWORD dwAspect, LONG lindex)\r
420 {\r
421         ATLTRACE(_T("IAdviseSink::OnViewChange\n"));\r
422 }\r
423 \r
424 void STDMETHODCALLTYPE FlashAxContainer::OnRename(IMoniker* pmk)\r
425 {\r
426         ATLTRACE(_T("IAdviseSink::OnRename\n"));\r
427 }\r
428 \r
429 void STDMETHODCALLTYPE FlashAxContainer::OnSave()\r
430 {\r
431         ATLTRACE(_T("IAdviseSink::OnSave\n"));\r
432 }\r
433 \r
434 void STDMETHODCALLTYPE FlashAxContainer::OnClose()\r
435 {\r
436         ATLTRACE(_T("IAdviseSink::OnClose\n"));\r
437 }\r
438 \r
439 \r
440 //DirectDraw GUIDS\r
441 \r
442 DEFINE_GUID2(CLSID_DirectDraw,0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35);\r
443 DEFINE_GUID2(CLSID_DirectDraw7,0x3c305196,0x50db,0x11d3,0x9c,0xfe,0x00,0xc0,0x4f,0xd9,0x30,0xc5);\r
444 \r
445 DEFINE_GUID2(IID_IDirectDraw,0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);\r
446 DEFINE_GUID2(IID_IDirectDraw3,0x618f8ad4,0x8b7a,0x11d0,0x8f,0xcc,0x0,0xc0,0x4f,0xd9,0x18,0x9d);\r
447 DEFINE_GUID2(IID_IDirectDraw4,0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5);\r
448 DEFINE_GUID2(IID_IDirectDraw7,0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);\r
449 \r
450 ///////////////////\r
451 // IServiceProvider\r
452 ///////////////////\r
453 HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj) \r
454 {\r
455 //      ATLTRACE(_T("IServiceProvider::QueryService\n"));\r
456         //the flashcontrol asks for an interface {618F8AD4-8B7A-11D0-8FCC-00C04FD9189D}, this is IID for a DirectDraw3 object\r
457 \r
458         ATLASSERT(ppvObj != NULL);\r
459         if (ppvObj == NULL)\r
460                 return E_POINTER;\r
461         *ppvObj = NULL;\r
462         \r
463         HRESULT hr;\r
464         // Author: Makarov Igor\r
465         // Transparent Flash Control in Plain C++ \r
466         // http://www.codeproject.com/KB/COM/flashcontrol.aspx \r
467         if (IsEqualGUID(rsid, IID_IDirectDraw3))\r
468         {\r
469                 if (!m_lpDD4)\r
470                 {\r
471                         m_lpDD4 = new IDirectDraw4Ptr;\r
472                         hr = m_lpDD4->CreateInstance(CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER); \r
473                         if (FAILED(hr))\r
474                         {\r
475                                 delete m_lpDD4;\r
476                                 m_lpDD4 = NULL;\r
477                                 CASPAR_LOG(info) << print_() << " DirectDraw not installed. Running without DirectDraw.";\r
478                                 return E_NOINTERFACE;\r
479                         }\r
480                 }\r
481                 if (m_lpDD4 && m_lpDD4->GetInterfacePtr())\r
482                 {\r
483                         *ppvObj = m_lpDD4->GetInterfacePtr();\r
484                         m_lpDD4->AddRef();\r
485                         return S_OK;\r
486                 }\r
487         }\r
488 \r
489         //TODO: The fullscreen-consumer requires that ths does NOT return an ITimerService\r
490         hr = QueryInterface(riid, ppvObj);//E_NOINTERFACE;\r
491 \r
492         return hr;\r
493 }\r
494 \r
495 \r
496 ///////////////////\r
497 // ITimerService\r
498 ///////////////////\r
499 HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)\r
500 {\r
501         ATLTRACE(_T("ITimerService::CreateTimer\n"));\r
502         if(pTimerHelper != 0)\r
503         {\r
504                 delete pTimerHelper;\r
505                 pTimerHelper = 0;\r
506         }\r
507         pTimerHelper = new TimerHelper();\r
508         return QueryInterface(__uuidof(ITimer), (void**) ppNewTimer);\r
509 }\r
510 \r
511 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetNamedTimer(REFGUID rguidName, ITimer **ppTimer)\r
512 {\r
513         ATLTRACE(_T("ITimerService::GetNamedTimer"));\r
514         if(ppTimer == NULL)\r
515                 return E_POINTER;\r
516         else\r
517                 *ppTimer = NULL;\r
518 \r
519         return E_FAIL;\r
520 }\r
521 \r
522 HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer)\r
523 {\r
524         ATLTRACE(_T("ITimerService::SetNamedTimerReference"));\r
525         return S_OK;\r
526 }\r
527 \r
528 ///////////\r
529 // ITimer\r
530 ///////////\r
531 HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie)\r
532 {\r
533         ATLTRACE(_T("Timer::Advise\n"));\r
534 \r
535         if(pdwCookie == 0)\r
536                 return E_POINTER;\r
537 \r
538         if(pTimerHelper != 0)\r
539         {\r
540                 pTimerHelper->Setup(vtimeMin.ulVal, vtimeInterval.ulVal, pTimerSink);\r
541                 *pdwCookie = pTimerHelper->ID;\r
542                 bHasNewTiming_ = true;\r
543 \r
544                 return S_OK;\r
545         }\r
546         else\r
547                 return E_OUTOFMEMORY;\r
548 }\r
549 \r
550 HRESULT STDMETHODCALLTYPE FlashAxContainer::Unadvise(/* [in] */ DWORD dwCookie)\r
551 {\r
552         ATLTRACE(_T("Timer::Unadvice\n"));\r
553         if(pTimerHelper != 0)\r
554         {\r
555                 pTimerHelper->pTimerSink = 0;\r
556                 return S_OK;\r
557         }\r
558         else\r
559                 return E_FAIL;\r
560 }\r
561 \r
562 HRESULT STDMETHODCALLTYPE FlashAxContainer::Freeze(/* [in] */ BOOL fFreeze)\r
563 {\r
564         ATLTRACE(_T("Timer::Freeze\n"));\r
565         return S_OK;\r
566 }\r
567 \r
568 HRESULT STDMETHODCALLTYPE FlashAxContainer::GetTime(/* [out] */ VARIANT *pvtime)\r
569 {\r
570         ATLTRACE(_T("Timer::GetTime\n"));\r
571         if(pvtime == 0)\r
572                 return E_POINTER;\r
573 \r
574 //      return E_NOTIMPL;\r
575         pvtime->lVal = 0;\r
576         return S_OK;\r
577 }\r
578 \r
579 double FlashAxContainer::GetFPS() {\r
580         if(pTimerHelper != 0 && pTimerHelper->interval > 0)\r
581                 return (1000.0 / static_cast<double>(pTimerHelper->interval));\r
582         \r
583         return 0.0;\r
584 }\r
585 \r
586 bool FlashAxContainer::IsReadyToRender() const {\r
587         return bReadyToRender_;\r
588 }\r
589 \r
590 void FlashAxContainer::EnterFullscreen()\r
591 {\r
592         if(m_spInPlaceObjectWindowless != 0)\r
593         {\r
594                 HRESULT result;\r
595                 m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1), &result);\r
596                 m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(1, 1), &result);\r
597         }\r
598 }\r
599 \r
600 void STDMETHODCALLTYPE FlashAxContainer::OnFlashCall(BSTR request)\r
601 {\r
602         std::wstring str(request);\r
603         if(str.find(TEXT("DisplayedTemplate")) != std::wstring::npos)\r
604         {\r
605                 ATLTRACE(_T("ShockwaveFlash::DisplayedTemplate\n"));\r
606                 bReadyToRender_ = true;\r
607         }\r
608         else if(str.find(TEXT("OnCommand")) != std::wstring::npos) {\r
609                 //this is how templatehost 1.8 reports that a command has been received\r
610                 CASPAR_LOG(info)  << print_()  << L" Command: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
611                 bCallSuccessful_ = true;\r
612         }\r
613         else if(str.find(TEXT("Activity")) != std::wstring::npos)\r
614         {\r
615                 CASPAR_LOG(info) << print_() << L" Activity: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
616 \r
617                 //this is how templatehost 1.7 reports that a command has been received\r
618                 if(str.find(TEXT("Command recieved")) != std::wstring::npos)\r
619                         bCallSuccessful_ = true;\r
620 \r
621                 /*if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
622                         std::wstring::size_type pos = str.find(TEXT('@'));\r
623                         if(pos != std::wstring::npos)\r
624                                 pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
625                 }*/\r
626         }\r
627         else if(str.find(TEXT("OnNotify")) != std::wstring::npos)\r
628         {\r
629                 CASPAR_LOG(info) << print_() << L" Notification: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
630 \r
631                 //if(pFlashProducer_ != 0 && pFlashProducer_->pMonitor_) {\r
632                 //      std::wstring::size_type pos = str.find(TEXT('@'));\r
633                 //      if(pos != std::wstring::npos)\r
634                 //              pFlashProducer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos));\r
635                 //}\r
636         }\r
637         else if(str.find(TEXT("IsEmpty")) != std::wstring::npos)\r
638         {\r
639                 CASPAR_LOG(info) << print_() << L" Empty.";\r
640                 ATLTRACE(_T("ShockwaveFlash::IsEmpty\n"));\r
641                 bIsEmpty_ = true;\r
642         }\r
643         else if(str.find(TEXT("OnError")) != std::wstring::npos)\r
644         {\r
645                 CASPAR_LOG(error) << print_() << L" Error: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
646         }\r
647         else if(str.find(TEXT("OnDebug")) != std::wstring::npos)\r
648         {\r
649                 CASPAR_LOG(error) << print_() << L" Debug: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
650         }\r
651         //else if(str.find(TEXT("OnTemplateDescription")) != std::wstring::npos)\r
652         //{\r
653         //      CASPAR_LOG(error) << print_() << L" TemplateDescription: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
654         //}\r
655         //else if(str.find(TEXT("OnGetInfo")) != std::wstring::npos)\r
656         //{\r
657         //      CASPAR_LOG(error) << print_() << L" Info: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
658         //}\r
659         //else\r
660         //{\r
661         //      CASPAR_LOG(error) << print_() << L" Unknown: \n-------------------------------------------\n" << str << L"\n-------------------------------------------";\r
662         //}\r
663 \r
664         CComPtr<IShockwaveFlash> spFlash;\r
665         HRESULT hr = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
666         if(hr == S_OK && spFlash)\r
667         {\r
668                 hr = spFlash->SetReturnValue(TEXT("<null/>"));\r
669         }\r
670 }\r
671 \r
672 void STDMETHODCALLTYPE FlashAxContainer::OnReadyStateChange(long newState)\r
673 {\r
674         if(newState == 4)\r
675         {\r
676                 bReadyToRender_ = true;\r
677         }\r
678         else\r
679                 bReadyToRender_ = false;\r
680 }\r
681 \r
682 void FlashAxContainer::DestroyAxControl()\r
683 {\r
684         GetControllingUnknown()->AddRef();\r
685 \r
686         if ((!m_spViewObject) == false)\r
687                 m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);\r
688 \r
689         if ((!m_spOleObject) == false)\r
690         {\r
691                 DispEventUnadvise(m_spOleObject, &DIID__IShockwaveFlashEvents);\r
692                 m_spOleObject->Unadvise(m_dwOleObject);\r
693                 m_spOleObject->Close(OLECLOSE_NOSAVE);\r
694                 m_spOleObject->SetClientSite(NULL);\r
695         }\r
696 \r
697         if ((!m_spUnknown) == false)\r
698         {\r
699                 CComPtr<IObjectWithSite> spSite;\r
700                 m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
701                 if (spSite != NULL)\r
702                         spSite->SetSite(NULL);\r
703         }\r
704 \r
705         if ((!m_spViewObject) == false)\r
706                 m_spViewObject.Release();\r
707 \r
708         if ((!m_spInPlaceObjectWindowless) == false)\r
709                 m_spInPlaceObjectWindowless.Release();\r
710 \r
711         if ((!m_spOleObject) == false)\r
712                 m_spOleObject.Release();\r
713 \r
714         if ((!m_spUnknown) == false)\r
715                 m_spUnknown.Release();\r
716 }\r
717 \r
718 bool FlashAxContainer::CheckForFlashSupport()\r
719 {\r
720         CLSID clsid;\r
721         return SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID_, &clsid));\r
722 }\r
723 \r
724 HRESULT FlashAxContainer::CreateAxControl()\r
725 {\r
726         CLSID clsid;\r
727         HRESULT hr = CLSIDFromString((LPOLESTR)flashGUID_, &clsid); \r
728         if(SUCCEEDED(hr))\r
729                 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)&m_spUnknown);\r
730 \r
731 //Start ActivateAx\r
732         if(SUCCEEDED(hr))\r
733         {\r
734                 m_spUnknown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);\r
735                 if(m_spOleObject)\r
736                 {\r
737                         m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);\r
738                         if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
739                         {\r
740                                 CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
741                                 m_spOleObject->SetClientSite(spClientSite);\r
742                         }\r
743 \r
744                         //Initialize control\r
745                         CComQIPtr<IPersistStreamInit> spPSI(m_spOleObject);\r
746                         if (spPSI)\r
747                                 hr = spPSI->InitNew();\r
748 \r
749                         if (FAILED(hr)) // If the initialization of the control failed...\r
750                         {\r
751                                 // Clean up and return\r
752                                 if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)\r
753                                         m_spOleObject->SetClientSite(NULL);\r
754 \r
755                                 m_dwMiscStatus = 0;\r
756                                 m_spOleObject.Release();\r
757                                 m_spUnknown.Release();\r
758 \r
759                                 return hr;\r
760                         }\r
761                         //end Initialize object\r
762 \r
763                         if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))\r
764                         {\r
765                                 CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
766                                 m_spOleObject->SetClientSite(spClientSite);\r
767                         }\r
768 \r
769                         CComPtr<IShockwaveFlash> spFlash;\r
770                         HRESULT hResultQuality;\r
771                         HRESULT hr2 = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash);\r
772                         if(hr2 == S_OK && spFlash)\r
773                         {\r
774                                 if(FAILED(spFlash->put_WMode(TEXT("Transparent"))))\r
775                                         CASPAR_LOG(warning) << print_() << L" Failed to set flash container to transparent mode.";\r
776                                 //spFlash->put_WMode(TEXT("GPU"));\r
777                                 hResultQuality = spFlash->put_Quality2(TEXT("Best"));\r
778                         }\r
779                         if(SUCCEEDED(DispEventAdvise(spFlash, &DIID__IShockwaveFlashEvents)))\r
780                         {\r
781                         }\r
782 \r
783                         HRESULT hrView = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);\r
784 \r
785                         CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());\r
786                         m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);\r
787                         if (m_spViewObject)\r
788                                 m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);\r
789 \r
790                         if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)\r
791                         {\r
792                                 //Initialize window to some dummy size\r
793                                 m_rcPos.top = 0;\r
794                                 m_rcPos.left = 0;\r
795                                 m_rcPos.right = 720;\r
796                                 m_rcPos.bottom = 576;\r
797 \r
798                                 m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
799                                 m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
800                                 AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
801                                 m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
802                                 m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
803                                 AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
804                                 m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
805                                 m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
806 \r
807                                 CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());\r
808                                 hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);\r
809                         }\r
810                 }\r
811                 CComPtr<IObjectWithSite> spSite;\r
812                 m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);\r
813                 if (spSite != NULL)\r
814                         spSite->SetSite(GetControllingUnknown());\r
815         }\r
816 //End ActivateAx\r
817 \r
818 //      hr = E_FAIL;\r
819         if (FAILED(hr) || m_spUnknown == NULL)\r
820         {\r
821                 return E_FAIL;\r
822                 // We don't have a control or something failed so release\r
823 //              ReleaseAll();\r
824         }\r
825 \r
826         return S_OK;\r
827 }\r
828 \r
829 void FlashAxContainer::SetSize(size_t width, size_t height) {\r
830         if(m_spInPlaceObjectWindowless != 0)\r
831         {\r
832                 m_rcPos.top = 0;\r
833                 m_rcPos.left = 0;\r
834                 m_rcPos.right = width;\r
835                 m_rcPos.bottom = height;\r
836 \r
837                 m_pxSize.cx = m_rcPos.right - m_rcPos.left;\r
838                 m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;\r
839                 AtlPixelToHiMetric(&m_pxSize, &m_hmSize);\r
840                 m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);\r
841                 m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);\r
842                 AtlHiMetricToPixel(&m_hmSize, &m_pxSize);\r
843                 m_rcPos.right = m_rcPos.left + m_pxSize.cx;\r
844                 m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;\r
845 \r
846                 m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
847                 bInvalidRect_ = true;\r
848         }\r
849 }\r
850 \r
851 HRESULT FlashAxContainer::QueryControl(REFIID iid, void** ppUnk)\r
852 {\r
853         ATLASSERT(ppUnk != NULL);\r
854         if (ppUnk == NULL)\r
855                 return E_POINTER;\r
856         HRESULT hr;\r
857         hr = m_spOleObject->QueryInterface(iid, ppUnk);\r
858         return hr;\r
859 }\r
860 \r
861 bool FlashAxContainer::DrawControl(HDC targetDC)\r
862 {\r
863 //      ATLTRACE(_T("FlashAxContainer::DrawControl\n"));\r
864         DVASPECTINFO aspectInfo = {sizeof(DVASPECTINFO), DVASPECTINFOFLAG_CANOPTIMIZE};\r
865         HRESULT hr = S_OK;\r
866 \r
867         hr = m_spViewObject->Draw(DVASPECT_CONTENT, -1, &aspectInfo, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
868         bInvalidRect_ = false;\r
869 /*      const video_format_desc& fmtDesc = video_format_desc::FormatDescriptions[format_];\r
870 \r
871         //Trying to redraw just the dirty rectangles. Doesn't seem to work when the movie uses "filters", such as glow, dropshadow etc.\r
872         std::vector<flash::DirtyRect>::iterator it = bDirtyRects_.begin();\r
873         std::vector<flash::DirtyRect>::iterator end = bDirtyRects_.end();\r
874         for(; it != end; ++it) {\r
875                 flash::DirtyRect& dirtyRect = (*it);\r
876                 if(dirtyRect.bWhole || dirtyRect.rect.right >= fmtDesc.width || dirtyRect.rect.bottom >= fmtDesc.height) {\r
877                         m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);\r
878                         hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
879                         break;\r
880                 }\r
881                 else {\r
882                         m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &(dirtyRect.rect));\r
883                         hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); \r
884                 }\r
885         }\r
886         bDirtyRects_.clear();\r
887 */\r
888 \r
889         return (hr == S_OK);\r
890 }\r
891 \r
892 void FlashAxContainer::Tick()\r
893 {\r
894         if(pTimerHelper)\r
895         {\r
896                 DWORD time = pTimerHelper->Invoke(); // Tick flash\r
897                 if(time - timerCount_ >= 400)\r
898                 {\r
899                         timerCount_ = time;\r
900                         HRESULT hr;\r
901                         m_spInPlaceObjectWindowless->OnWindowMessage(WM_TIMER, 3, 0, &hr);\r
902                 }\r
903         }\r
904 }\r
905 \r
906 bool FlashAxContainer::FlashCall(const std::wstring& str, std::wstring& result2)\r
907 {\r
908         CComBSTR result;\r
909         CComPtr<IShockwaveFlash> spFlash;\r
910         QueryControl(&spFlash);\r
911         CComBSTR request(str.c_str());\r
912         \r
913         bIsEmpty_ = false;\r
914         bCallSuccessful_ = false;\r
915         for(size_t retries = 0; !bCallSuccessful_ && retries < 4; ++retries)\r
916                 spFlash->CallFunction(request, &result);\r
917 \r
918         result2 = result;\r
919 \r
920         return bCallSuccessful_;\r
921 }\r
922 \r
923 }       //namespace flash\r
924 }       //namespace caspar