]> git.sesse.net Git - vlc/blob - activex/oleobject.cpp
- miscelleanous fixes and improvements
[vlc] / activex / oleobject.cpp
1 /*****************************************************************************\r
2  * oleobject.cpp: ActiveX control for VLC\r
3  *****************************************************************************\r
4  * Copyright (C) 2005 VideoLAN\r
5  *\r
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>\r
7  *\r
8  * This program is free software; you can redistribute it and/or modify\r
9  * it under the terms of the GNU General Public License as published by\r
10  * the Free Software Foundation; either version 2 of the License, or\r
11  * (at your option) any later version.\r
12  *\r
13  * This program is distributed in the hope that it will be useful,\r
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
16  * GNU General Public License for more details.\r
17  *\r
18  * You should have received a copy of the GNU General Public License\r
19  * along with this program; if not, write to the Free Software\r
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.\r
21  *****************************************************************************/\r
22 \r
23 #include "plugin.h"\r
24 #include "oleobject.h"\r
25 \r
26 #include "utils.h"\r
27 \r
28 #include <docobj.h>\r
29 \r
30 using namespace std;\r
31 \r
32 VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :\r
33 _p_clientsite(NULL), _p_instance(p_instance) \r
34 {\r
35     CreateOleAdviseHolder(&_p_advise_holder);\r
36 };\r
37 \r
38 VLCOleObject::~VLCOleObject()\r
39 {\r
40     _p_advise_holder->Release();\r
41     SetClientSite(NULL); \r
42 };\r
43 \r
44 STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)\r
45 {\r
46     return _p_advise_holder->Advise(pAdvSink, dwConnection);\r
47 };\r
48 \r
49 STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)\r
50 {\r
51     _p_advise_holder->SendOnClose();\r
52     OleFlushClipboard();\r
53     return _p_instance->onClose(dwSaveOption);\r
54 };\r
55 \r
56 STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,\r
57                                     LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)\r
58 {\r
59     if( 0 != lIndex )\r
60         return DV_E_LINDEX;\r
61 \r
62     switch( iVerb )\r
63     {\r
64         case OLEIVERB_PRIMARY:\r
65         case OLEIVERB_SHOW:\r
66         case OLEIVERB_OPEN:\r
67         case OLEIVERB_INPLACEACTIVATE:\r
68             if( NULL == hwndParent )\r
69                 return OLEOBJ_S_INVALIDHWND;\r
70 \r
71             if( SUCCEEDED(doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect)) )\r
72                 return S_OK;\r
73 \r
74             return OLEOBJ_S_CANNOT_DOVERB_NOW;\r
75 \r
76         case OLEIVERB_HIDE:\r
77             _p_instance->setVisible(FALSE);\r
78             return S_OK;\r
79 \r
80         case OLEIVERB_UIACTIVATE:\r
81             return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);\r
82 \r
83         case OLEIVERB_DISCARDUNDOSTATE:\r
84             return S_OK;\r
85 \r
86         default:\r
87             if( NULL == hwndParent )\r
88                 return OLEOBJ_S_INVALIDHWND;\r
89 \r
90             if( SUCCEEDED(doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect)) )\r
91                 return OLEOBJ_S_INVALIDVERB;\r
92 \r
93             return OLEOBJ_S_CANNOT_DOVERB_NOW;\r
94     }\r
95 };\r
96 \r
97 HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)\r
98 {\r
99     RECT posRect;\r
100     RECT clipRect;\r
101     LPCRECT lprcClipRect = lprcPosRect;\r
102 \r
103     if( NULL != pActiveSite )\r
104     {\r
105         // check if already activated\r
106         if( _p_instance->isInPlaceActive() )\r
107         {\r
108             // just attempt to show object then\r
109             pActiveSite->ShowObject();\r
110             _p_instance->setVisible(TRUE);\r
111             return S_OK;\r
112         }\r
113 \r
114         LPOLEINPLACESITE p_inPlaceSite;\r
115 \r
116         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )\r
117         {\r
118             if( S_OK != p_inPlaceSite->CanInPlaceActivate() )\r
119                 return E_FAIL;\r
120 \r
121             LPOLEINPLACEFRAME p_inPlaceFrame;\r
122             LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;\r
123             OLEINPLACEFRAMEINFO oleFrameInfo;\r
124 \r
125             if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )\r
126             {\r
127                 lprcPosRect = &posRect;\r
128                 lprcClipRect = &clipRect;\r
129 \r
130                 if( NULL != p_inPlaceFrame )\r
131                     p_inPlaceFrame->Release();\r
132                 if( NULL != p_inPlaceUIWindow )\r
133                     p_inPlaceUIWindow->Release();\r
134             }\r
135         }\r
136 \r
137         if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )\r
138             return E_FAIL;\r
139 \r
140         if( NULL != p_inPlaceSite )\r
141             p_inPlaceSite->OnPosRectChange(lprcPosRect);\r
142 \r
143         pActiveSite->ShowObject();\r
144         _p_instance->setVisible(TRUE);\r
145 \r
146         if( NULL != p_inPlaceSite )\r
147         {\r
148             p_inPlaceSite->OnInPlaceActivate();\r
149             p_inPlaceSite->Release();\r
150         }\r
151 \r
152         if( NULL != lpMsg )\r
153         {\r
154             switch( lpMsg->message )\r
155             {\r
156                 case WM_LBUTTONDOWN:\r
157                 case WM_LBUTTONDBLCLK:\r
158                     doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);\r
159                     break;\r
160                 default:\r
161                     break;\r
162             }\r
163         }\r
164         return S_OK;\r
165     }\r
166     return E_FAIL;\r
167 };\r
168 \r
169 HRESULT VLCOleObject::doUIActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)\r
170 {\r
171     if( NULL != pActiveSite )\r
172     {\r
173         // check if already activated\r
174         if( ! _p_instance->isInPlaceActive() )\r
175             return OLE_E_NOT_INPLACEACTIVE;\r
176 \r
177         LPOLEINPLACESITE p_inPlaceSite;\r
178 \r
179         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )\r
180         {\r
181             p_inPlaceSite->OnUIActivate();\r
182 \r
183             if( NULL != lprcPosRect )\r
184             {\r
185                 p_inPlaceSite->OnPosRectChange(lprcPosRect);\r
186             }\r
187             p_inPlaceSite->Release();\r
188         }\r
189 \r
190         pActiveSite->ShowObject();\r
191         _p_instance->setVisible(TRUE);\r
192         _p_instance->setFocus(TRUE);\r
193 \r
194         return S_OK;\r
195     }\r
196     return E_FAIL;\r
197 };\r
198 \r
199 STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)\r
200 {\r
201     return _p_advise_holder->EnumAdvise(ppEnumAdvise);\r
202 };\r
203 \r
204 STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)\r
205 {\r
206     return OLE_S_USEREG;\r
207 };\r
208 \r
209 STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)\r
210 {\r
211     if( NULL == ppClientSite )\r
212         return E_POINTER;\r
213  \r
214     if( NULL != _p_clientsite )\r
215         _p_clientsite->AddRef(); \r
216 \r
217     *ppClientSite= _p_clientsite;\r
218     return S_OK;\r
219 };\r
220 \r
221 STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)\r
222 {\r
223     return E_NOTIMPL;\r
224 };\r
225 \r
226 STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)\r
227 {\r
228     return E_NOTIMPL;\r
229 };\r
230 \r
231 STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)\r
232 {\r
233     if( NULL != pdwStatus )\r
234         return E_POINTER;\r
235 \r
236     switch( dwAspect )\r
237     {\r
238         case DVASPECT_CONTENT:\r
239             *pdwStatus = OLEMISC_RECOMPOSEONRESIZE\r
240                 | OLEMISC_CANTLINKINSIDE\r
241                 | OLEMISC_INSIDEOUT\r
242                 | OLEMISC_ACTIVATEWHENVISIBLE\r
243                 | OLEMISC_SETCLIENTSITEFIRST;\r
244             break;\r
245         default:\r
246             *pdwStatus = 0;\r
247     }\r
248 \r
249     return S_OK;\r
250 };\r
251 \r
252 STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)\r
253 {\r
254     if( NULL != _p_clientsite )\r
255         return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);\r
256  \r
257     return E_UNEXPECTED;\r
258 };\r
259 \r
260 STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)\r
261 {\r
262     if( NULL == pClsid )\r
263         return E_POINTER;\r
264  \r
265     pClsid = const_cast<LPCLSID>(&_p_instance->getClassID()); \r
266     return S_OK;\r
267 };\r
268 \r
269 STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)\r
270 {\r
271     return OLE_S_USEREG;\r
272 };\r
273 \r
274 STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)\r
275 {\r
276     return E_NOTIMPL;\r
277 };\r
278 \r
279 STDMETHODIMP VLCOleObject::IsUpToDate(void)\r
280 {\r
281     return S_OK;\r
282 };\r
283 \r
284 STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)\r
285 {\r
286     if( NULL != _p_clientsite )\r
287         _p_clientsite->Release(); \r
288  \r
289     if( NULL != pClientSite )\r
290     {\r
291         pClientSite->AddRef();\r
292 \r
293         /*\r
294         ** retrieve container ambient properties\r
295         */\r
296         VARIANT v;\r
297         VariantInit(&v);\r
298         V_VT(&v) = VT_I4;\r
299         if( SUCCEEDED(GetObjectProperty(pClientSite, DISPID_AMBIENT_CODEPAGE, v)) )\r
300         {\r
301             _p_instance->setCodePage(V_I4(&v));\r
302             VariantClear(&v);\r
303         }\r
304     }\r
305 \r
306     _p_clientsite = pClientSite;\r
307     return S_OK;\r
308 };\r
309 \r
310 STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)\r
311 {\r
312     return E_NOTIMPL;\r
313 };\r
314 \r
315 STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)\r
316 {\r
317     return E_NOTIMPL;\r
318 };\r
319 \r
320 STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)\r
321 {\r
322     return S_OK;\r
323 };\r
324 \r
325 STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)\r
326 {\r
327     return _p_advise_holder->SendOnRename(pMoniker);\r
328 };\r
329 \r
330 STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)\r
331 {\r
332     return _p_advise_holder->Unadvise(dwConnection);\r
333 };\r
334 \r
335 STDMETHODIMP VLCOleObject::Update(void)\r
336 {\r
337     return S_OK;\r
338 };\r
339 \r