]> git.sesse.net Git - vlc/blob - activex/oleobject.cpp
compilation fixes for MSVC
[vlc] / activex / oleobject.cpp
1 /*****************************************************************************
2  * oleobject.cpp: ActiveX control for VLC
3  *****************************************************************************
4  * Copyright (C) 2005 VideoLAN
5  *
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23 #include "plugin.h"
24 #include "oleobject.h"
25
26 #include "utils.h"
27
28 #include <docobj.h>
29
30 using namespace std;
31
32 VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :
33 _p_clientsite(NULL), _p_instance(p_instance) 
34 {
35     CreateOleAdviseHolder(&_p_advise_holder);
36 };
37
38 VLCOleObject::~VLCOleObject()
39 {
40     _p_advise_holder->Release();
41     SetClientSite(NULL); 
42 };
43
44 STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
45 {
46     return _p_advise_holder->Advise(pAdvSink, dwConnection);
47 };
48
49 STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
50 {
51     _p_advise_holder->SendOnClose();
52     OleFlushClipboard();
53     return _p_instance->onClose(dwSaveOption);
54 };
55
56 STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
57                                     LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
58 {
59     if( 0 != lIndex )
60         return DV_E_LINDEX;
61
62     switch( iVerb )
63     {
64         case OLEIVERB_PRIMARY:
65         case OLEIVERB_SHOW:
66         case OLEIVERB_OPEN:
67         case OLEIVERB_INPLACEACTIVATE:
68             return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
69
70         case OLEIVERB_HIDE:
71             _p_instance->setVisible(FALSE);
72             return S_OK;
73
74         case OLEIVERB_UIACTIVATE:
75             return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
76
77         case OLEIVERB_DISCARDUNDOSTATE:
78             return S_OK;
79
80         default:
81             return OLEOBJ_S_INVALIDVERB;
82     }
83 };
84
85 HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
86 {
87     RECT posRect;
88     RECT clipRect;
89     LPCRECT lprcClipRect = lprcPosRect;
90
91     if( NULL != pActiveSite )
92     {
93         // check if already activated
94         if( _p_instance->isInPlaceActive() )
95         {
96             // just attempt to show object then
97             pActiveSite->ShowObject();
98             _p_instance->setVisible(TRUE);
99             return S_OK;
100         }
101
102         LPOLEINPLACESITE p_inPlaceSite;
103
104         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
105         {
106             if( S_OK != p_inPlaceSite->CanInPlaceActivate() )
107                 return OLEOBJ_S_CANNOT_DOVERB_NOW;
108
109             LPOLEINPLACEFRAME p_inPlaceFrame;
110             LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
111             OLEINPLACEFRAMEINFO oleFrameInfo;
112
113             if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
114             {
115                 lprcPosRect = &posRect;
116                 lprcClipRect = &clipRect;
117
118                 if( NULL != p_inPlaceFrame )
119                     p_inPlaceFrame->Release();
120                 if( NULL != p_inPlaceUIWindow )
121                     p_inPlaceUIWindow->Release();
122             }
123
124             if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
125             {
126                 p_inPlaceSite->Release();
127                 return OLEOBJ_S_INVALIDHWND;
128             }
129         }
130         else if( NULL == hwndParent )
131             return OLEOBJ_S_INVALIDHWND;
132
133         if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
134         {
135             if( NULL != p_inPlaceSite )
136                 p_inPlaceSite->Release();
137             return OLEOBJ_S_CANNOT_DOVERB_NOW;
138         }
139
140         if( NULL != p_inPlaceSite )
141             p_inPlaceSite->OnPosRectChange(lprcPosRect);
142
143         pActiveSite->ShowObject();
144         _p_instance->setVisible(TRUE);
145
146         if( NULL != p_inPlaceSite )
147         {
148             p_inPlaceSite->OnInPlaceActivate();
149             p_inPlaceSite->Release();
150         }
151
152         if( NULL != lpMsg )
153         {
154             switch( lpMsg->message )
155             {
156                 case WM_LBUTTONDOWN:
157                 case WM_LBUTTONDBLCLK:
158                     doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
159                     break;
160                 default:
161                     break;
162             }
163         }
164         return S_OK;
165     }
166     return OLEOBJ_S_CANNOT_DOVERB_NOW;
167 };
168
169 HRESULT VLCOleObject::doUIActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
170 {
171     if( NULL != pActiveSite )
172     {
173         // check if already activated
174         if( ! _p_instance->isInPlaceActive() )
175             return OLE_E_NOT_INPLACEACTIVE;
176
177         LPOLEINPLACESITE p_inPlaceSite;
178
179         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
180         {
181             p_inPlaceSite->OnUIActivate();
182
183             if( NULL != lprcPosRect )
184             {
185                 p_inPlaceSite->OnPosRectChange(lprcPosRect);
186             }
187             p_inPlaceSite->Release();
188         }
189
190         pActiveSite->ShowObject();
191         _p_instance->setVisible(TRUE);
192         _p_instance->setFocus(TRUE);
193
194         return S_OK;
195     }
196     return E_FAIL;
197 };
198
199 STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
200 {
201     return _p_advise_holder->EnumAdvise(ppEnumAdvise);
202 };
203
204 STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
205 {
206     return OLE_S_USEREG;
207 };
208
209 STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
210 {
211     if( NULL == ppClientSite )
212         return E_POINTER;
213  
214     if( NULL != _p_clientsite )
215         _p_clientsite->AddRef(); 
216
217     *ppClientSite = _p_clientsite;
218     return S_OK;
219 };
220
221 STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
222 {
223     return E_NOTIMPL;
224 };
225
226 STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
227 {
228     if( NULL == pSizel )
229         return E_POINTER;
230
231     if( dwDrawAspect & DVASPECT_CONTENT )
232     {
233         *pSizel = _p_instance->getExtent();
234         return S_OK;
235     }
236     pSizel->cx= 0L;
237     pSizel->cy= 0L;
238     return E_NOTIMPL;
239 };
240
241 STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
242 {
243     if( NULL != pdwStatus )
244         return E_POINTER;
245
246     switch( dwAspect )
247     {
248         case DVASPECT_CONTENT:
249             *pdwStatus = OLEMISC_RECOMPOSEONRESIZE
250                 | OLEMISC_CANTLINKINSIDE
251                 | OLEMISC_INSIDEOUT
252                 | OLEMISC_ACTIVATEWHENVISIBLE
253                 | OLEMISC_SETCLIENTSITEFIRST;
254             break;
255         default:
256             *pdwStatus = 0;
257     }
258
259     return S_OK;
260 };
261
262 STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
263 {
264     if( NULL != _p_clientsite )
265         return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
266  
267     return E_UNEXPECTED;
268 };
269
270 STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
271 {
272     if( NULL == pClsid )
273         return E_POINTER;
274  
275     pClsid = const_cast<LPCLSID>(&_p_instance->getClassID()); 
276     return S_OK;
277 };
278
279 STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
280 {
281     return OLE_S_USEREG;
282 };
283
284 STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
285 {
286     return E_NOTIMPL;
287 };
288
289 STDMETHODIMP VLCOleObject::IsUpToDate(void)
290 {
291     return S_OK;
292 };
293
294 STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
295 {
296     if( NULL != _p_clientsite )
297         _p_clientsite->Release(); 
298  
299     if( NULL != pClientSite )
300     {
301         pClientSite->AddRef();
302
303         /*
304         ** retrieve container ambient properties
305         */
306         VARIANT v;
307         VariantInit(&v);
308         V_VT(&v) = VT_I4;
309         if( SUCCEEDED(GetObjectProperty(pClientSite, DISPID_AMBIENT_CODEPAGE, v)) )
310         {
311             _p_instance->setCodePage(V_I4(&v));
312             VariantClear(&v);
313         }
314     }
315     _p_clientsite = pClientSite;
316     _p_instance->onClientSiteChanged(pClientSite);
317     return S_OK;
318 };
319
320 STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
321 {
322     return E_NOTIMPL;
323 };
324
325 STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
326 {
327     if( NULL == pSizel )
328         return E_POINTER;
329
330     if( dwDrawAspect & DVASPECT_CONTENT )
331     {
332         _p_instance->setExtent(*pSizel);
333
334         if( _p_instance->isInPlaceActive() )
335         {
336             LPOLEINPLACESITE p_inPlaceSite;
337
338             if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
339             {
340                 LPOLECONTROLSITE p_controlSite;
341                 RECT posRect = _p_instance->getPosRect();
342
343                 if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleControlSite, (void**)&p_controlSite)) )
344                 {
345                     // use HIMETRIC to container transform
346                     POINTL extent = { pSizel->cx, pSizel->cy };
347                     POINTF container;
348                     if( SUCCEEDED(p_controlSite->TransformCoords(&extent,
349                                     &container, XFORMCOORDS_SIZE|XFORMCOORDS_HIMETRICTOCONTAINER)) )
350                     {
351                         posRect.right  = ((LONG)container.x)+posRect.left;
352                         posRect.bottom = ((LONG)container.y)+posRect.top;
353                     }
354                     p_controlSite->Release();
355                 }
356                 else {
357                     // use HIMETRIC to display transform 
358                     HDC hDC = CreateDevDC(NULL);
359                     posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
360                     posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
361                     DeleteDC(hDC);
362                 }
363                 p_inPlaceSite->OnPosRectChange(&posRect);
364                 p_inPlaceSite->Release();
365             }
366         }
367         return S_OK;
368     }
369     return E_NOTIMPL;
370 };
371
372 STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
373 {
374     return S_OK;
375 };
376
377 STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
378 {
379     return _p_advise_holder->SendOnRename(pMoniker);
380 };
381
382 STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
383 {
384     return _p_advise_holder->Unadvise(dwConnection);
385 };
386
387 STDMETHODIMP VLCOleObject::Update(void)
388 {
389     return S_OK;
390 };
391