Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

oleobject.cpp

00001 /*****************************************************************************
00002  * oleobject.cpp: ActiveX control for VLC
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  *
00006  * Authors: Damien Fouilleul <[email protected]>
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00021  *****************************************************************************/
00022 
00023 #include "plugin.h"
00024 #include "oleobject.h"
00025 
00026 #include "utils.h"
00027 
00028 #include <docobj.h>
00029 
00030 using namespace std;
00031 
00032 VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :
00033 _p_clientsite(NULL), _p_instance(p_instance) 
00034 {
00035     CreateOleAdviseHolder(&_p_advise_holder);
00036 };
00037 
00038 VLCOleObject::~VLCOleObject()
00039 {
00040     SetClientSite(NULL);
00041     Close(OLECLOSE_NOSAVE);
00042     _p_advise_holder->Release();
00043 };
00044 
00045 STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
00046 {
00047     return _p_advise_holder->Advise(pAdvSink, dwConnection);
00048 };
00049 
00050 STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
00051 {
00052     if( _p_instance->isRunning() )
00053     {
00054         _p_advise_holder->SendOnClose();
00055         return _p_instance->onClose(dwSaveOption);
00056     }
00057     return S_OK;
00058 };
00059 
00060 STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
00061                                     LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
00062 {
00063     switch( iVerb )
00064     {
00065         case OLEIVERB_PRIMARY:
00066         case OLEIVERB_SHOW:
00067         case OLEIVERB_OPEN:
00068             // force control to be visible when activating in place
00069             _p_instance->setVisible(TRUE);
00070         case OLEIVERB_INPLACEACTIVATE:
00071             return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
00072 
00073         case OLEIVERB_HIDE:
00074             _p_instance->setVisible(FALSE);
00075             return S_OK;
00076 
00077         case OLEIVERB_UIACTIVATE:
00078             return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
00079 
00080         case OLEIVERB_DISCARDUNDOSTATE:
00081             return S_OK;
00082 
00083         default:
00084             if( iVerb > 0 ) {
00085                 _p_instance->setVisible(TRUE);
00086                 doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
00087                 return OLEOBJ_S_INVALIDVERB;
00088             }
00089             return E_NOTIMPL;
00090     }
00091 };
00092 
00093 HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
00094 {
00095     RECT posRect;
00096     RECT clipRect;
00097     LPCRECT lprcClipRect = lprcPosRect;
00098 
00099     if( NULL != pActiveSite )
00100     {
00101         // check if already activated
00102         if( _p_instance->isInPlaceActive() )
00103         {
00104             // just attempt to show object then
00105             if( _p_instance->getVisible() )
00106                 pActiveSite->ShowObject();
00107             return S_OK;
00108         }
00109 
00110         LPOLEINPLACESITE p_inPlaceSite;
00111 
00112         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
00113         {
00114             if( S_OK != p_inPlaceSite->CanInPlaceActivate() )
00115             {
00116                 return OLEOBJ_S_CANNOT_DOVERB_NOW;
00117             }
00118 
00119             LPOLEINPLACEFRAME p_inPlaceFrame;
00120             LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
00121             OLEINPLACEFRAMEINFO oleFrameInfo;
00122 
00123             oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
00124             if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) )
00125             {
00126                 lprcPosRect = &posRect;
00127                 lprcClipRect = &clipRect;
00128 
00129                 if( NULL != p_inPlaceFrame )
00130                     p_inPlaceFrame->Release();
00131                 if( NULL != p_inPlaceUIWindow )
00132                     p_inPlaceUIWindow->Release();
00133             }
00134 
00135             if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
00136             {
00137                 p_inPlaceSite->Release();
00138                 return OLEOBJ_S_INVALIDHWND;
00139             }
00140         }
00141         else if( NULL == hwndParent )
00142         {
00143             return OLEOBJ_S_INVALIDHWND;
00144         }
00145         else if( NULL == lprcPosRect )
00146         {
00147             SetRect(&posRect, 0, 0, 0, 0);
00148             lprcPosRect = &posRect;
00149             lprcClipRect = &posRect;
00150         }
00151 
00152         if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
00153         {
00154             if( NULL != p_inPlaceSite )
00155                 p_inPlaceSite->Release();
00156             return OLEOBJ_S_CANNOT_DOVERB_NOW;
00157         }
00158 
00159         if( NULL != p_inPlaceSite )
00160         {
00161             p_inPlaceSite->OnInPlaceActivate();
00162             p_inPlaceSite->OnPosRectChange(lprcPosRect);
00163             p_inPlaceSite->Release();
00164         }
00165 
00166         pActiveSite->ShowObject();
00167         _p_instance->setVisible(TRUE);
00168 
00169         if( NULL != lpMsg )
00170         {
00171             switch( lpMsg->message )
00172             {
00173                 case WM_LBUTTONDOWN:
00174                 case WM_LBUTTONDBLCLK:
00175                     doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
00176                     break;
00177                 default:
00178                     break;
00179             }
00180         }
00181         return S_OK;
00182     }
00183     return OLEOBJ_S_CANNOT_DOVERB_NOW;
00184 };
00185 
00186 HRESULT VLCOleObject::doUIActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
00187 {
00188     if( NULL != pActiveSite )
00189     {
00190         // check if already activated
00191         if( ! _p_instance->isInPlaceActive() )
00192             return OLE_E_NOT_INPLACEACTIVE;
00193 
00194         LPOLEINPLACESITE p_inPlaceSite;
00195 
00196         if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
00197         {
00198             p_inPlaceSite->OnUIActivate();
00199 
00200             if( NULL != lprcPosRect )
00201             {
00202                 p_inPlaceSite->OnPosRectChange(lprcPosRect);
00203             }
00204             p_inPlaceSite->Release();
00205         }
00206 
00207         pActiveSite->ShowObject();
00208         _p_instance->setVisible(TRUE);
00209         _p_instance->setFocus(TRUE);
00210 
00211         return S_OK;
00212     }
00213     return E_FAIL;
00214 };
00215 
00216 STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
00217 {
00218     return _p_advise_holder->EnumAdvise(ppEnumAdvise);
00219 };
00220 
00221 STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
00222 {
00223     return OleRegEnumVerbs(_p_instance->getClassID(),
00224         ppEnumOleVerb);
00225 };
00226 
00227 STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
00228 {
00229     if( NULL == ppClientSite )
00230         return E_POINTER;
00231  
00232     if( NULL != _p_clientsite )
00233         _p_clientsite->AddRef(); 
00234 
00235     *ppClientSite = _p_clientsite;
00236     return S_OK;
00237 };
00238 
00239 STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
00240 {
00241     return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
00242 };
00243 
00244 STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
00245 {
00246     if( NULL == pSizel )
00247         return E_POINTER;
00248 
00249     if( dwDrawAspect & DVASPECT_CONTENT )
00250     {
00251         *pSizel = _p_instance->getExtent();
00252         return S_OK;
00253     }
00254     pSizel->cx= 0L;
00255     pSizel->cy= 0L;
00256     return E_NOTIMPL;
00257 };
00258 
00259 STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
00260 {
00261     if( NULL == pdwStatus )
00262         return E_POINTER;
00263 
00264     switch( dwAspect )
00265     {
00266         case DVASPECT_CONTENT:
00267             *pdwStatus = OLEMISC_RECOMPOSEONRESIZE
00268                 | OLEMISC_CANTLINKINSIDE
00269                 | OLEMISC_INSIDEOUT
00270                 | OLEMISC_ACTIVATEWHENVISIBLE
00271                 | OLEMISC_SETCLIENTSITEFIRST;
00272             break;
00273         default:
00274             *pdwStatus = 0;
00275     }
00276 
00277     return S_OK;
00278 };
00279 
00280 STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
00281 {
00282     if( NULL != _p_clientsite )
00283         return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
00284  
00285     return E_UNEXPECTED;
00286 };
00287 
00288 STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
00289 {
00290     if( NULL == pClsid )
00291         return E_POINTER;
00292  
00293     *pClsid = _p_instance->getClassID(); 
00294     return S_OK;
00295 };
00296 
00297 STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
00298 {
00299     return OleRegGetUserType(_p_instance->getClassID(),
00300         dwFormOfType, pszUserType);
00301 };
00302 
00303 STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
00304 {
00305     return E_NOTIMPL;
00306 };
00307 
00308 STDMETHODIMP VLCOleObject::IsUpToDate(void)
00309 {
00310     return S_OK;
00311 };
00312 
00313 STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
00314 {
00315     if( NULL != _p_clientsite )
00316         _p_clientsite->Release();
00317 
00318     _p_clientsite = pClientSite;
00319 
00320     if( NULL != pClientSite )
00321     {
00322         pClientSite->AddRef();
00323         _p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN);
00324     }
00325     return S_OK;
00326 };
00327 
00328 STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
00329 {
00330     return E_NOTIMPL;
00331 };
00332 
00333 STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
00334 {
00335     if( NULL == pSizel )
00336         return E_POINTER;
00337 
00338 
00339     if( dwDrawAspect & DVASPECT_CONTENT )
00340     {
00341         _p_instance->setExtent(*pSizel);
00342 
00343         if( _p_instance->isInPlaceActive() )
00344         {
00345             LPOLEINPLACESITE p_inPlaceSite;
00346 
00347             if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
00348             {
00349                 HWND hwnd;
00350 
00351                 if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) )
00352                 {
00353                     // use HIMETRIC to pixel transform 
00354                     RECT posRect = _p_instance->getPosRect();
00355                     HDC hDC = GetDC(hwnd);
00356                     posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
00357                     posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
00358                     DeleteDC(hDC);
00359                     p_inPlaceSite->OnPosRectChange(&posRect);
00360                 }
00361                 p_inPlaceSite->Release();
00362             }
00363         }
00364         return S_OK;
00365     }
00366     return E_NOTIMPL;
00367 };
00368 
00369 STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
00370 {
00371     return S_OK;
00372 };
00373 
00374 STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
00375 {
00376     return _p_advise_holder->SendOnRename(pMoniker);
00377 };
00378 
00379 STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
00380 {
00381     return _p_advise_holder->Unadvise(dwConnection);
00382 };
00383 
00384 STDMETHODIMP VLCOleObject::Update(void)
00385 {
00386     return S_OK;
00387 };
00388 

Generated on Tue Dec 20 10:14:18 2005 for vlc-0.8.4a by  doxygen 1.4.2