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., 59 Temple Place - Suite 330, Boston, MA 02111, 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()
40 _p_advise_holder->Release();
44 STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
46 return _p_advise_holder->Advise(pAdvSink, dwConnection);
49 STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
51 _p_advise_holder->SendOnClose();
52 return _p_instance->onClose(dwSaveOption);
55 STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
56 LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
60 case OLEIVERB_PRIMARY:
63 // force control to be visible when activating in place
64 _p_instance->setVisible(TRUE);
65 case OLEIVERB_INPLACEACTIVATE:
66 return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
69 _p_instance->setVisible(FALSE);
72 case OLEIVERB_UIACTIVATE:
73 return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
75 case OLEIVERB_DISCARDUNDOSTATE:
80 _p_instance->setVisible(TRUE);
81 doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
82 return OLEOBJ_S_INVALIDVERB;
88 HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
92 LPCRECT lprcClipRect = lprcPosRect;
94 if( NULL != pActiveSite )
96 // check if already activated
97 if( _p_instance->isInPlaceActive() )
99 // just attempt to show object then
100 if( _p_instance->getVisible() )
101 pActiveSite->ShowObject();
105 LPOLEINPLACESITE p_inPlaceSite;
107 if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
109 if( S_OK != p_inPlaceSite->CanInPlaceActivate() )
111 return OLEOBJ_S_CANNOT_DOVERB_NOW;
114 LPOLEINPLACEFRAME p_inPlaceFrame;
115 LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
116 OLEINPLACEFRAMEINFO oleFrameInfo;
118 if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
120 lprcPosRect = &posRect;
121 lprcClipRect = &clipRect;
123 if( NULL != p_inPlaceFrame )
124 p_inPlaceFrame->Release();
125 if( NULL != p_inPlaceUIWindow )
126 p_inPlaceUIWindow->Release();
129 if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
131 p_inPlaceSite->Release();
132 return OLEOBJ_S_INVALIDHWND;
135 else if( NULL == hwndParent )
137 return OLEOBJ_S_INVALIDHWND;
140 if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
142 if( NULL != p_inPlaceSite )
143 p_inPlaceSite->Release();
144 return OLEOBJ_S_CANNOT_DOVERB_NOW;
147 if( NULL != p_inPlaceSite )
148 p_inPlaceSite->OnPosRectChange(lprcPosRect);
150 pActiveSite->ShowObject();
151 _p_instance->setVisible(TRUE);
153 if( NULL != p_inPlaceSite )
155 p_inPlaceSite->OnInPlaceActivate();
156 p_inPlaceSite->Release();
161 switch( lpMsg->message )
164 case WM_LBUTTONDBLCLK:
165 doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
173 return OLEOBJ_S_CANNOT_DOVERB_NOW;
176 HRESULT VLCOleObject::doUIActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
178 if( NULL != pActiveSite )
180 // check if already activated
181 if( ! _p_instance->isInPlaceActive() )
182 return OLE_E_NOT_INPLACEACTIVE;
184 LPOLEINPLACESITE p_inPlaceSite;
186 if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
188 p_inPlaceSite->OnUIActivate();
190 if( NULL != lprcPosRect )
192 p_inPlaceSite->OnPosRectChange(lprcPosRect);
194 p_inPlaceSite->Release();
197 pActiveSite->ShowObject();
198 _p_instance->setVisible(TRUE);
199 _p_instance->setFocus(TRUE);
206 STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
208 return _p_advise_holder->EnumAdvise(ppEnumAdvise);
211 STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
213 return OleRegEnumVerbs(_p_instance->getClassID(),
217 STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
219 if( NULL == ppClientSite )
222 if( NULL != _p_clientsite )
223 _p_clientsite->AddRef();
225 *ppClientSite = _p_clientsite;
229 STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
231 return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
234 STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
239 if( dwDrawAspect & DVASPECT_CONTENT )
241 *pSizel = _p_instance->getExtent();
249 STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
251 if( NULL == pdwStatus )
256 case DVASPECT_CONTENT:
257 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE
258 | OLEMISC_CANTLINKINSIDE
260 | OLEMISC_ACTIVATEWHENVISIBLE
261 | OLEMISC_SETCLIENTSITEFIRST;
270 STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
272 if( NULL != _p_clientsite )
273 return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
278 STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
283 *pClsid = _p_instance->getClassID();
287 STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
289 return OleRegGetUserType(_p_instance->getClassID(),
290 dwFormOfType, pszUserType);
293 STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
298 STDMETHODIMP VLCOleObject::IsUpToDate(void)
303 STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
305 if( NULL != pClientSite )
307 pClientSite->AddRef();
310 ** retrieve container ambient properties
315 if( SUCCEEDED(GetObjectProperty(pClientSite, DISPID_AMBIENT_CODEPAGE, v)) )
317 _p_instance->setCodePage(V_I4(&v));
322 if( NULL != _p_clientsite )
323 _p_clientsite->Release();
325 _p_clientsite = pClientSite;
326 _p_instance->onClientSiteChanged(pClientSite);
331 STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
336 STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
341 if( dwDrawAspect & DVASPECT_CONTENT )
343 _p_instance->setExtent(*pSizel);
345 if( _p_instance->isInPlaceActive() )
347 LPOLEINPLACESITE p_inPlaceSite;
349 if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
353 if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) )
355 // use HIMETRIC to pixel transform
356 RECT posRect = _p_instance->getPosRect();
357 HDC hDC = GetDC(hwnd);
358 posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
359 posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
361 p_inPlaceSite->OnPosRectChange(&posRect);
363 p_inPlaceSite->Release();
371 STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
376 STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
378 return _p_advise_holder->SendOnRename(pMoniker);
381 STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
383 return _p_advise_holder->Unadvise(dwConnection);
386 STDMETHODIMP VLCOleObject::Update(void)