1 /*****************************************************************************
2 * oleobject.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
24 #include "oleobject.h"
32 VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :
33 _p_clientsite(NULL), _p_instance(p_instance)
35 CreateOleAdviseHolder(&_p_advise_holder);
38 VLCOleObject::~VLCOleObject()
41 Close(OLECLOSE_NOSAVE);
42 _p_advise_holder->Release();
45 STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
47 return _p_advise_holder->Advise(pAdvSink, dwConnection);
50 STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
52 if( _p_instance->isRunning() )
54 _p_advise_holder->SendOnClose();
55 return _p_instance->onClose(dwSaveOption);
60 STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
61 LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
65 case OLEIVERB_PRIMARY:
68 // force control to be visible when activating in place
69 _p_instance->setVisible(TRUE);
70 return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
72 case OLEIVERB_INPLACEACTIVATE:
73 return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, FALSE);
76 _p_instance->setVisible(FALSE);
79 case OLEIVERB_UIACTIVATE:
80 // UI activate only if visible
81 if( _p_instance->isVisible() )
82 return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
83 return OLEOBJ_S_CANNOT_DOVERB_NOW;
85 case OLEIVERB_DISCARDUNDOSTATE:
90 _p_instance->setVisible(TRUE);
91 doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE);
92 return OLEOBJ_S_INVALIDVERB;
98 HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect, BOOL uiActivate)
102 LPCRECT lprcClipRect = lprcPosRect;
106 LPOLEINPLACESITE p_inPlaceSite;
107 IOleInPlaceSiteEx *p_inPlaceSiteEx;
108 LPOLEINPLACEFRAME p_inPlaceFrame;
109 LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
111 if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSiteEx, reinterpret_cast<void**>(&p_inPlaceSiteEx))) )
113 p_inPlaceSite = p_inPlaceSiteEx;
114 p_inPlaceSite->AddRef();
116 else if FAILED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, reinterpret_cast<void**>(&p_inPlaceSite)) )
118 p_inPlaceSite = p_inPlaceSiteEx = NULL;
123 OLEINPLACEFRAMEINFO oleFrameInfo;
125 oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
126 if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
128 lprcPosRect = &posRect;
129 lprcClipRect = &clipRect;
132 if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
134 p_inPlaceSite->Release();
135 if( p_inPlaceSiteEx )
136 p_inPlaceSiteEx->Release();
138 p_inPlaceFrame->Release();
139 if( p_inPlaceUIWindow )
140 p_inPlaceUIWindow->Release();
142 return OLEOBJ_S_INVALIDHWND;
145 else if( NULL == hwndParent )
147 return OLEOBJ_S_INVALIDHWND;
149 else if( NULL == lprcPosRect )
151 SetRect(&posRect, 0, 0, 0, 0);
152 lprcPosRect = &posRect;
153 lprcClipRect = &posRect;
156 // check if not already activated
157 if( ! _p_instance->isInPlaceActive() )
159 if( ((NULL == p_inPlaceSite) || (S_OK == p_inPlaceSite->CanInPlaceActivate()))
160 && SUCCEEDED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
162 if( p_inPlaceSiteEx )
165 p_inPlaceSiteEx->OnInPlaceActivateEx(&needsRedraw, 0);
167 else if( p_inPlaceSite )
168 p_inPlaceSite->OnInPlaceActivate();
174 p_inPlaceSite->Release();
175 if( p_inPlaceSiteEx )
176 p_inPlaceSiteEx->Release();
178 p_inPlaceFrame->Release();
179 if( p_inPlaceUIWindow )
180 p_inPlaceUIWindow->Release();
182 return OLEOBJ_S_CANNOT_DOVERB_NOW;
187 p_inPlaceSite->OnPosRectChange(lprcPosRect);
191 if( (NULL == p_inPlaceSiteEx) || (S_OK == p_inPlaceSiteEx->RequestUIActivate()) )
195 p_inPlaceSite->OnUIActivate();
197 LPOLEINPLACEACTIVEOBJECT p_inPlaceActiveObject;
198 if( SUCCEEDED(QueryInterface(IID_IOleInPlaceActiveObject, reinterpret_cast<void**>(&p_inPlaceActiveObject))) )
201 p_inPlaceFrame->SetActiveObject(p_inPlaceActiveObject, NULL);
202 if( p_inPlaceUIWindow )
203 p_inPlaceUIWindow->SetActiveObject(p_inPlaceActiveObject, NULL);
204 p_inPlaceActiveObject->Release();
207 p_inPlaceFrame->RequestBorderSpace(NULL);
209 pActiveSite->ShowObject();
211 _p_instance->setFocus(TRUE);
217 p_inPlaceSite->Release();
218 if( p_inPlaceSiteEx )
219 p_inPlaceSiteEx->Release();
221 p_inPlaceFrame->Release();
222 if( p_inPlaceUIWindow )
223 p_inPlaceUIWindow->Release();
227 return OLEOBJ_S_CANNOT_DOVERB_NOW;
230 STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
232 return _p_advise_holder->EnumAdvise(ppEnumAdvise);
235 STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
237 return OleRegEnumVerbs(_p_instance->getClassID(),
241 STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
243 if( NULL == ppClientSite )
246 if( NULL != _p_clientsite )
247 _p_clientsite->AddRef();
249 *ppClientSite = _p_clientsite;
253 STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
255 return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
258 STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
263 if( dwDrawAspect & DVASPECT_CONTENT )
265 *pSizel = _p_instance->getExtent();
273 STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
275 if( NULL == pdwStatus )
280 case DVASPECT_CONTENT:
281 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE
282 | OLEMISC_CANTLINKINSIDE
284 | OLEMISC_ACTIVATEWHENVISIBLE
285 | OLEMISC_SETCLIENTSITEFIRST;
294 STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
296 if( NULL != _p_clientsite )
297 return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
302 STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
307 *pClsid = _p_instance->getClassID();
311 STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
313 return OleRegGetUserType(_p_instance->getClassID(),
314 dwFormOfType, pszUserType);
317 STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
322 STDMETHODIMP VLCOleObject::IsUpToDate(void)
327 STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
329 if( NULL != _p_clientsite )
330 _p_clientsite->Release();
332 _p_clientsite = pClientSite;
334 if( NULL != pClientSite )
336 pClientSite->AddRef();
337 _p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN);
342 STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
347 STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
352 if( dwDrawAspect & DVASPECT_CONTENT )
354 _p_instance->setExtent(*pSizel);
356 if( _p_instance->isInPlaceActive() )
358 LPOLEINPLACESITE p_inPlaceSite;
360 if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
364 if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) )
366 // use HIMETRIC to pixel transform
367 RECT posRect = _p_instance->getPosRect();
368 HDC hDC = GetDC(hwnd);
369 posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
370 posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
372 p_inPlaceSite->OnPosRectChange(&posRect);
374 p_inPlaceSite->Release();
382 STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
387 STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
389 return _p_advise_holder->SendOnRename(pMoniker);
392 STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
394 return _p_advise_holder->Unadvise(dwConnection);
397 STDMETHODIMP VLCOleObject::Update(void)