2005-03-02 17:47:31 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* oleobject.cpp: ActiveX control for VLC
|
|
|
|
*****************************************************************************
|
2005-07-09 08:17:09 +02:00
|
|
|
* Copyright (C) 2005 the VideoLAN team
|
2005-03-02 17:47:31 +01:00
|
|
|
*
|
|
|
|
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "plugin.h"
|
|
|
|
#include "oleobject.h"
|
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#include <docobj.h>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
VLCOleObject::VLCOleObject(VLCPlugin *p_instance) :
|
|
|
|
_p_clientsite(NULL), _p_instance(p_instance)
|
|
|
|
{
|
|
|
|
CreateOleAdviseHolder(&_p_advise_holder);
|
|
|
|
};
|
|
|
|
|
|
|
|
VLCOleObject::~VLCOleObject()
|
|
|
|
{
|
2005-08-21 19:40:32 +02:00
|
|
|
SetClientSite(NULL);
|
|
|
|
Close(OLECLOSE_NOSAVE);
|
2005-03-02 17:47:31 +01:00
|
|
|
_p_advise_holder->Release();
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
|
|
|
|
{
|
|
|
|
return _p_advise_holder->Advise(pAdvSink, dwConnection);
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
|
|
|
|
{
|
2005-08-21 19:40:32 +02:00
|
|
|
if( _p_instance->isRunning() )
|
|
|
|
{
|
|
|
|
_p_advise_holder->SendOnClose();
|
|
|
|
return _p_instance->onClose(dwSaveOption);
|
|
|
|
}
|
|
|
|
return S_OK;
|
2005-03-02 17:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActiveSite,
|
|
|
|
LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
|
|
|
|
{
|
|
|
|
switch( iVerb )
|
|
|
|
{
|
|
|
|
case OLEIVERB_PRIMARY:
|
|
|
|
case OLEIVERB_SHOW:
|
|
|
|
case OLEIVERB_OPEN:
|
2005-07-19 19:41:16 +02:00
|
|
|
// force control to be visible when activating in place
|
|
|
|
_p_instance->setVisible(TRUE);
|
2005-03-02 17:47:31 +01:00
|
|
|
case OLEIVERB_INPLACEACTIVATE:
|
2005-03-07 11:40:23 +01:00
|
|
|
return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
|
2005-03-02 17:47:31 +01:00
|
|
|
|
|
|
|
case OLEIVERB_HIDE:
|
|
|
|
_p_instance->setVisible(FALSE);
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
case OLEIVERB_UIACTIVATE:
|
|
|
|
return doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
|
|
|
|
|
|
|
|
case OLEIVERB_DISCARDUNDOSTATE:
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
default:
|
2005-07-19 19:41:16 +02:00
|
|
|
if( iVerb > 0 ) {
|
|
|
|
_p_instance->setVisible(TRUE);
|
|
|
|
doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
|
|
|
|
return OLEOBJ_S_INVALIDVERB;
|
|
|
|
}
|
|
|
|
return E_NOTIMPL;
|
2005-03-02 17:47:31 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite, HWND hwndParent, LPCRECT lprcPosRect)
|
|
|
|
{
|
|
|
|
RECT posRect;
|
|
|
|
RECT clipRect;
|
|
|
|
LPCRECT lprcClipRect = lprcPosRect;
|
|
|
|
|
|
|
|
if( NULL != pActiveSite )
|
|
|
|
{
|
|
|
|
// check if already activated
|
|
|
|
if( _p_instance->isInPlaceActive() )
|
|
|
|
{
|
|
|
|
// just attempt to show object then
|
2005-07-19 19:41:16 +02:00
|
|
|
if( _p_instance->getVisible() )
|
|
|
|
pActiveSite->ShowObject();
|
2005-03-02 17:47:31 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPOLEINPLACESITE p_inPlaceSite;
|
|
|
|
|
|
|
|
if( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
|
|
|
|
{
|
|
|
|
if( S_OK != p_inPlaceSite->CanInPlaceActivate() )
|
2005-06-27 13:41:16 +02:00
|
|
|
{
|
2005-03-07 11:40:23 +01:00
|
|
|
return OLEOBJ_S_CANNOT_DOVERB_NOW;
|
2005-06-27 13:41:16 +02:00
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
|
|
|
|
LPOLEINPLACEFRAME p_inPlaceFrame;
|
|
|
|
LPOLEINPLACEUIWINDOW p_inPlaceUIWindow;
|
|
|
|
OLEINPLACEFRAMEINFO oleFrameInfo;
|
|
|
|
|
2005-08-21 19:40:32 +02:00
|
|
|
oleFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
|
2005-03-02 17:47:31 +01:00
|
|
|
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();
|
|
|
|
}
|
2005-03-07 11:40:23 +01:00
|
|
|
|
|
|
|
if( (NULL == hwndParent) && FAILED(p_inPlaceSite->GetWindow(&hwndParent)) )
|
|
|
|
{
|
|
|
|
p_inPlaceSite->Release();
|
|
|
|
return OLEOBJ_S_INVALIDHWND;
|
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
}
|
2005-03-07 11:40:23 +01:00
|
|
|
else if( NULL == hwndParent )
|
2005-06-27 13:41:16 +02:00
|
|
|
{
|
2005-03-07 11:40:23 +01:00
|
|
|
return OLEOBJ_S_INVALIDHWND;
|
2005-06-27 13:41:16 +02:00
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
|
|
|
|
if( FAILED(_p_instance->onActivateInPlace(lpMsg, hwndParent, lprcPosRect, lprcClipRect)) )
|
2005-03-07 11:40:23 +01:00
|
|
|
{
|
|
|
|
if( NULL != p_inPlaceSite )
|
|
|
|
p_inPlaceSite->Release();
|
|
|
|
return OLEOBJ_S_CANNOT_DOVERB_NOW;
|
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
|
|
|
|
if( NULL != p_inPlaceSite )
|
|
|
|
p_inPlaceSite->OnPosRectChange(lprcPosRect);
|
|
|
|
|
|
|
|
pActiveSite->ShowObject();
|
|
|
|
_p_instance->setVisible(TRUE);
|
|
|
|
|
|
|
|
if( NULL != p_inPlaceSite )
|
|
|
|
{
|
|
|
|
p_inPlaceSite->OnInPlaceActivate();
|
|
|
|
p_inPlaceSite->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( NULL != lpMsg )
|
|
|
|
{
|
|
|
|
switch( lpMsg->message )
|
|
|
|
{
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
|
|
doUIActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
2005-03-07 11:40:23 +01:00
|
|
|
return OLEOBJ_S_CANNOT_DOVERB_NOW;
|
2005-03-02 17:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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( SUCCEEDED(pActiveSite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
|
|
|
|
{
|
|
|
|
p_inPlaceSite->OnUIActivate();
|
|
|
|
|
|
|
|
if( NULL != lprcPosRect )
|
|
|
|
{
|
|
|
|
p_inPlaceSite->OnPosRectChange(lprcPosRect);
|
|
|
|
}
|
|
|
|
p_inPlaceSite->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
pActiveSite->ShowObject();
|
|
|
|
_p_instance->setVisible(TRUE);
|
|
|
|
_p_instance->setFocus(TRUE);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
return E_FAIL;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
|
|
|
|
{
|
|
|
|
return _p_advise_holder->EnumAdvise(ppEnumAdvise);
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
|
|
|
|
{
|
2005-07-19 19:41:16 +02:00
|
|
|
return OleRegEnumVerbs(_p_instance->getClassID(),
|
|
|
|
ppEnumOleVerb);
|
2005-03-02 17:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
|
|
|
|
{
|
|
|
|
if( NULL == ppClientSite )
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
if( NULL != _p_clientsite )
|
|
|
|
_p_clientsite->AddRef();
|
|
|
|
|
2005-03-07 11:40:23 +01:00
|
|
|
*ppClientSite = _p_clientsite;
|
2005-03-02 17:47:31 +01:00
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
|
|
|
|
{
|
2005-07-19 19:41:16 +02:00
|
|
|
return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
|
2005-03-02 17:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
|
|
|
|
{
|
2005-04-18 13:35:18 +02:00
|
|
|
if( NULL == pSizel )
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
if( dwDrawAspect & DVASPECT_CONTENT )
|
|
|
|
{
|
|
|
|
*pSizel = _p_instance->getExtent();
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
pSizel->cx= 0L;
|
|
|
|
pSizel->cy= 0L;
|
2005-03-02 17:47:31 +01:00
|
|
|
return E_NOTIMPL;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
|
|
|
|
{
|
2005-07-19 19:41:16 +02:00
|
|
|
if( NULL == pdwStatus )
|
2005-03-02 17:47:31 +01:00
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
switch( dwAspect )
|
|
|
|
{
|
|
|
|
case DVASPECT_CONTENT:
|
|
|
|
*pdwStatus = OLEMISC_RECOMPOSEONRESIZE
|
|
|
|
| OLEMISC_CANTLINKINSIDE
|
|
|
|
| OLEMISC_INSIDEOUT
|
|
|
|
| OLEMISC_ACTIVATEWHENVISIBLE
|
|
|
|
| OLEMISC_SETCLIENTSITEFIRST;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*pdwStatus = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER *ppMoniker)
|
|
|
|
{
|
|
|
|
if( NULL != _p_clientsite )
|
|
|
|
return _p_clientsite->GetMoniker(dwAssign,dwWhichMoniker, ppMoniker);
|
|
|
|
|
|
|
|
return E_UNEXPECTED;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
|
|
|
|
{
|
|
|
|
if( NULL == pClsid )
|
|
|
|
return E_POINTER;
|
|
|
|
|
2005-07-19 19:41:16 +02:00
|
|
|
*pClsid = _p_instance->getClassID();
|
2005-03-02 17:47:31 +01:00
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
|
|
|
|
{
|
2005-07-19 19:41:16 +02:00
|
|
|
return OleRegGetUserType(_p_instance->getClassID(),
|
|
|
|
dwFormOfType, pszUserType);
|
2005-03-02 17:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::IsUpToDate(void)
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
|
|
|
|
{
|
2005-06-27 13:41:16 +02:00
|
|
|
if( NULL != _p_clientsite )
|
|
|
|
_p_clientsite->Release();
|
|
|
|
|
2005-03-02 17:47:31 +01:00
|
|
|
_p_clientsite = pClientSite;
|
2005-06-27 13:41:16 +02:00
|
|
|
|
2005-08-21 19:40:32 +02:00
|
|
|
if( NULL != pClientSite )
|
|
|
|
{
|
|
|
|
pClientSite->AddRef();
|
|
|
|
_p_instance->onAmbientChanged(pClientSite, DISPID_UNKNOWN);
|
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::SetColorScheme(LOGPALETTE *pLogpal)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
|
|
|
|
{
|
2005-04-18 13:35:18 +02:00
|
|
|
if( NULL == pSizel )
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
if( dwDrawAspect & DVASPECT_CONTENT )
|
|
|
|
{
|
|
|
|
_p_instance->setExtent(*pSizel);
|
|
|
|
|
|
|
|
if( _p_instance->isInPlaceActive() )
|
|
|
|
{
|
|
|
|
LPOLEINPLACESITE p_inPlaceSite;
|
|
|
|
|
|
|
|
if( SUCCEEDED(_p_clientsite->QueryInterface(IID_IOleInPlaceSite, (void**)&p_inPlaceSite)) )
|
|
|
|
{
|
2005-06-27 13:41:16 +02:00
|
|
|
HWND hwnd;
|
2005-04-18 13:35:18 +02:00
|
|
|
|
2005-06-27 13:41:16 +02:00
|
|
|
if( SUCCEEDED(p_inPlaceSite->GetWindow(&hwnd)) )
|
2005-04-18 13:35:18 +02:00
|
|
|
{
|
2005-06-27 13:41:16 +02:00
|
|
|
// use HIMETRIC to pixel transform
|
|
|
|
RECT posRect = _p_instance->getPosRect();
|
|
|
|
HDC hDC = GetDC(hwnd);
|
2005-04-18 13:35:18 +02:00
|
|
|
posRect.right = (pSizel->cx*GetDeviceCaps(hDC, LOGPIXELSX)/2540L)+posRect.left;
|
|
|
|
posRect.bottom = (pSizel->cy*GetDeviceCaps(hDC, LOGPIXELSY)/2540L)+posRect.top;
|
|
|
|
DeleteDC(hDC);
|
2005-06-27 13:41:16 +02:00
|
|
|
p_inPlaceSite->OnPosRectChange(&posRect);
|
2005-04-18 13:35:18 +02:00
|
|
|
}
|
|
|
|
p_inPlaceSite->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
2005-03-02 17:47:31 +01:00
|
|
|
return E_NOTIMPL;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pMoniker)
|
|
|
|
{
|
|
|
|
return _p_advise_holder->SendOnRename(pMoniker);
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::Unadvise(DWORD dwConnection)
|
|
|
|
{
|
|
|
|
return _p_advise_holder->Unadvise(dwConnection);
|
|
|
|
};
|
|
|
|
|
|
|
|
STDMETHODIMP VLCOleObject::Update(void)
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
};
|
|
|
|
|