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)