X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=activex%2Foleobject.cpp;h=b7ef8867d0ecb1d957a8c20a5560fdfc99827460;hb=70bb5bccb040d4bf7870177f2c83bad8008bc9e1;hp=ec7d8aedbefbaa66ac04a8888642d9040c8c1d8e;hpb=1b75d79ed2680352f5ed1f67d57e9c205dd73162;p=vlc diff --git a/activex/oleobject.cpp b/activex/oleobject.cpp index ec7d8aedbe..b7ef8867d0 100644 --- a/activex/oleobject.cpp +++ b/activex/oleobject.cpp @@ -1,7 +1,7 @@ /***************************************************************************** * oleobject.cpp: ActiveX control for VLC ***************************************************************************** - * Copyright (C) 2005 VideoLAN + * Copyright (C) 2005 the VideoLAN team * * Authors: Damien Fouilleul * @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #include "plugin.h" @@ -30,15 +30,16 @@ using namespace std; VLCOleObject::VLCOleObject(VLCPlugin *p_instance) : -_p_clientsite(NULL), _p_instance(p_instance) +_p_clientsite(NULL), _p_instance(p_instance) { CreateOleAdviseHolder(&_p_advise_holder); }; VLCOleObject::~VLCOleObject() { + SetClientSite(NULL); + Close(OLECLOSE_NOSAVE); _p_advise_holder->Release(); - SetClientSite(NULL); }; STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection) @@ -48,152 +49,182 @@ STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection) STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption) { - _p_advise_holder->SendOnClose(); - OleFlushClipboard(); - return _p_instance->onClose(dwSaveOption); + if( _p_instance->isRunning() ) + { + _p_advise_holder->SendOnClose(); + return _p_instance->onClose(dwSaveOption); + } + return S_OK; }; STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect) { - if( 0 != lIndex ) - return DV_E_LINDEX; - switch( iVerb ) { case OLEIVERB_PRIMARY: case OLEIVERB_SHOW: case OLEIVERB_OPEN: + // force control to be visible when activating in place + _p_instance->setVisible(TRUE); + return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE); + case OLEIVERB_INPLACEACTIVATE: - return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect); + return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, FALSE); case OLEIVERB_HIDE: _p_instance->setVisible(FALSE); return S_OK; case OLEIVERB_UIACTIVATE: - return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect); + // UI activate only if visible + if( _p_instance->isVisible() ) + return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE); + return OLEOBJ_S_CANNOT_DOVERB_NOW; case OLEIVERB_DISCARDUNDOSTATE: return S_OK; default: - return OLEOBJ_S_INVALIDVERB; + if( iVerb > 0 ) { + _p_instance->setVisible(TRUE); + doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect, TRUE); + return OLEOBJ_S_INVALIDVERB; + } + return E_NOTIMPL; } }; -HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect) +HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect, BOOL uiActivate) { RECT posRect; RECT clipRect; LPCRECT lprcClipRect = lprcPosRect; - if( NULL != pActiveSite ) + if( pActiveSite ) { - // check if already activated - if( _p_instance->isInPlaceActive() ) - { - // just attempt to show object then - pActiveSite->ShowObject(); - _p_instance->setVisible(TRUE); - return S_OK; - } - LPOLEINPLACESITE p_inPlaceSite; + IOleInPlaceSiteEx *p_inPlaceSiteEx; + LPOLEINPLACEFRAME p_inPlaceFrame; + LPOLEINPLACEUIWINDOW p_inPlaceUIWindow; - if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) ) + if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSiteEx, reinterpret_cast(&p_inPlaceSiteEx))) ) { - if( S_OK != p_inPlaceSite->CanInPlaceActivate() ) - return OLEOBJ_S_CANNOT_DOVERB_NOW; + p_inPlaceSite = p_inPlaceSiteEx; + p_inPlaceSite->AddRef(); + } + else if FAILED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, reinterpret_cast(&p_inPlaceSite)) ) + { + p_inPlaceSite = p_inPlaceSiteEx = NULL; + } - LPOLEINPLACEFRAME p_inPlaceFrame; - LPOLEINPLACEUIWINDOW p_inPlaceUIWindow; + if( p_inPlaceSite ) + { OLEINPLACEFRAMEINFO oleFrameInfo; + oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO); if( SUCCEEDED(p_inPlaceSite->GetWindowContext(&p_inPlaceFrame, &p_inPlaceUIWindow, &posRect, &clipRect, &oleFrameInfo)) ) { lprcPosRect = &posRect; lprcClipRect = &clipRect; - - if( NULL != p_inPlaceFrame ) - p_inPlaceFrame->Release(); - if( NULL != p_inPlaceUIWindow ) - p_inPlaceUIWindow->Release(); } if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) ) { p_inPlaceSite->Release(); + if( p_inPlaceSiteEx ) + p_inPlaceSiteEx->Release(); + if( p_inPlaceFrame ) + p_inPlaceFrame->Release(); + if( p_inPlaceUIWindow ) + p_inPlaceUIWindow->Release(); + return OLEOBJ_S_INVALIDHWND; } } else if( NULL == hwndParent ) - return OLEOBJ_S_INVALIDHWND; - - if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) ) { - if( NULL != p_inPlaceSite ) - p_inPlaceSite->Release(); - return OLEOBJ_S_CANNOT_DOVERB_NOW; + return OLEOBJ_S_INVALIDHWND; } - - if( NULL != p_inPlaceSite ) - p_inPlaceSite->OnPosRectChange(lprcPosRect); - - pActiveSite->ShowObject(); - _p_instance->setVisible(TRUE); - - if( NULL != p_inPlaceSite ) + else if( NULL == lprcPosRect ) { - p_inPlaceSite->OnInPlaceActivate(); - p_inPlaceSite->Release(); + SetRect(&posRect, 0, 0, 0, 0); + lprcPosRect = &posRect; + lprcClipRect = &posRect; } - if( NULL != lpMsg ) + // check if not already activated + if( ! _p_instance->isInPlaceActive() ) { - switch( lpMsg->message ) + if( ((NULL == p_inPlaceSite) || (S_OK == p_inPlaceSite->CanInPlaceActivate())) + && SUCCEEDED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) ) { - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect); - break; - default: - break; + if( p_inPlaceSiteEx ) + { + BOOL needsRedraw; + p_inPlaceSiteEx->OnInPlaceActivateEx(&needsRedraw, 0); + } + else if( p_inPlaceSite ) + p_inPlaceSite->OnInPlaceActivate(); } + else + { + if( p_inPlaceSite ) + { + p_inPlaceSite->Release(); + if( p_inPlaceSiteEx ) + p_inPlaceSiteEx->Release(); + if( p_inPlaceFrame ) + p_inPlaceFrame->Release(); + if( p_inPlaceUIWindow ) + p_inPlaceUIWindow->Release(); + } + return OLEOBJ_S_CANNOT_DOVERB_NOW; + } } - return S_OK; - } - return OLEOBJ_S_CANNOT_DOVERB_NOW; -}; -HRESULT VLCOleObject::doUIActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect) -{ - if( NULL != pActiveSite ) - { - // check if already activated - if( ! _p_instance->isInPlaceActive() ) - return OLE_E_NOT_INPLACEACTIVE; - - LPOLEINPLACESITE p_inPlaceSite; + if( p_inPlaceSite ) + p_inPlaceSite->OnPosRectChange(lprcPosRect); - if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) ) + if( uiActivate ) { - p_inPlaceSite->OnUIActivate(); - - if( NULL != lprcPosRect ) + if( (NULL == p_inPlaceSiteEx) || (S_OK == p_inPlaceSiteEx->RequestUIActivate()) ) { - p_inPlaceSite->OnPosRectChange(lprcPosRect); + if( p_inPlaceSite) + { + p_inPlaceSite->OnUIActivate(); + + LPOLEINPLACEACTIVEOBJECT p_inPlaceActiveObject; + if( SUCCEEDED(QueryInterface(IID_IOleInPlaceActiveObject, reinterpret_cast(&p_inPlaceActiveObject))) ) + { + if( p_inPlaceFrame ) + p_inPlaceFrame->SetActiveObject(p_inPlaceActiveObject, NULL); + if( p_inPlaceUIWindow ) + p_inPlaceUIWindow->SetActiveObject(p_inPlaceActiveObject, NULL); + p_inPlaceActiveObject->Release(); + } + if( p_inPlaceFrame ) + p_inPlaceFrame->RequestBorderSpace(NULL); + + pActiveSite->ShowObject(); + } + _p_instance->setFocus(TRUE); } - p_inPlaceSite->Release(); } - pActiveSite->ShowObject(); - _p_instance->setVisible(TRUE); - _p_instance->setFocus(TRUE); - + if( p_inPlaceSite ) + { + p_inPlaceSite->Release(); + if( p_inPlaceSiteEx ) + p_inPlaceSiteEx->Release(); + if( p_inPlaceFrame ) + p_inPlaceFrame->Release(); + if( p_inPlaceUIWindow ) + p_inPlaceUIWindow->Release(); + } return S_OK; } - return E_FAIL; + return OLEOBJ_S_CANNOT_DOVERB_NOW; }; STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise) @@ -203,14 +234,15 @@ STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise) STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb) { - return OLE_S_USEREG; + return OleRegEnumVerbs(_p_instance->getClassID(), + ppEnumOleVerb); }; STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite) { if( NULL == ppClientSite ) return E_POINTER; - + if( NULL != _p_clientsite ) _p_clientsite->AddRef(); @@ -220,7 +252,7 @@ STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite) STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject) { - return E_NOTIMPL; + return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject); }; STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel) @@ -240,7 +272,7 @@ STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel) STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus) { - if( NULL != pdwStatus ) + if( NULL == pdwStatus ) return E_POINTER; switch( dwAspect ) @@ -263,7 +295,7 @@ STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMO { if( NULL != _p_clientsite ) return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker); - + return E_UNEXPECTED; }; @@ -272,13 +304,14 @@ STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid) if( NULL == pClsid ) return E_POINTER; - pClsid = const_cast(&_p_instance->getClassID()); + *pClsid = _p_instance->getClassID(); return S_OK; }; STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType) { - return OLE_S_USEREG; + return OleRegGetUserType(_p_instance->getClassID(), + dwFormOfType, pszUserType); }; STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved) @@ -294,26 +327,15 @@ STDMETHODIMP VLCOleObject::IsUpToDate(void) STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite) { if( NULL != _p_clientsite ) - _p_clientsite->Release(); - + _p_clientsite->Release(); + + _p_clientsite = pClientSite; + if( NULL != pClientSite ) { pClientSite->AddRef(); - - /* - ** retrieve container ambient properties - */ - VARIANT v; - VariantInit(&v); - V_VT(&v) = VT_I4; - if( SUCCEEDED(GetObjectProperty(pClientSite, DISPID_AMBIENT_CODEPAGE, v)) ) - { - _p_instance->setCodePage(V_I4(&v)); - VariantClear(&v); - } + _p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN); } - _p_clientsite = pClientSite; - _p_instance->onClientSiteChanged(pClientSite); return S_OK; }; @@ -337,30 +359,18 @@ STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel) if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) ) { - LPOLECONTROLSITE p_controlSite; - RECT posRect = _p_instance->getPosRect(); + HWND hwnd; - if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleControlSite, (void**)&p_controlSite)) ) + if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) ) { - // use HIMETRIC to container transform - POINTL extent = { pSizel->cx, pSizel->cy }; - POINTF container; - if( SUCCEEDED(p_controlSite->TransformCoords(&extent, - &container, XFORMCOORDS_SIZE|XFORMCOORDS_HIMETRICTOCONTAINER)) ) - { - posRect.right = ((LONG)container.x)+posRect.left; - posRect.bottom = ((LONG)container.y)+posRect.top; - } - p_controlSite->Release(); - } - else { - // use HIMETRIC to display transform - HDC hDC = CreateDevDC(NULL); + // use HIMETRIC to pixel transform + RECT posRect = _p_instance->getPosRect(); + HDC hDC = GetDC(hwnd); posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left; posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top; DeleteDC(hDC); + p_inPlaceSite->OnPosRectChange(&posRect); } - p_inPlaceSite->OnPosRectChange(&posRect); p_inPlaceSite->Release(); } }