X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=activex%2Foleobject.cpp;h=3c71b03e0b7b19a9aa846d291268017afc5b9e56;hb=76edc14f9b492a3ddbbae7869a9fee384e6c3a33;hp=bf6a76246fc12c88c90688fe2b3d38b94828e656;hpb=da4dc63b33a3cbffa38513107882a05f2043d17c;p=vlc diff --git a/activex/oleobject.cpp b/activex/oleobject.cpp index bf6a76246f..3c71b03e0b 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,9 +49,12 @@ 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, @@ -61,68 +65,80 @@ STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActi 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; } } @@ -130,71 +146,85 @@ HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite { 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; - } - - 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) @@ -204,16 +234,17 @@ 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(); + _p_clientsite->AddRef(); *ppClientSite = _p_clientsite; return S_OK; @@ -221,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) @@ -241,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 ) @@ -264,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; }; @@ -273,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,30 +326,16 @@ STDMETHODIMP VLCOleObject::IsUpToDate(void) STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE 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); - } - } - if( NULL != _p_clientsite ) _p_clientsite->Release(); _p_clientsite = pClientSite; - _p_instance->onClientSiteChanged(pClientSite); + if( NULL != pClientSite ) + { + pClientSite->AddRef(); + _p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN); + } return S_OK; }; @@ -345,7 +363,7 @@ STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel) if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) ) { - // use HIMETRIC to pixel transform + // use HIMETRIC to pixel transform RECT posRect = _p_instance->getPosRect(); HDC hDC = GetDC(hwnd); posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;