Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

357 lines
7.9 KiB

/*----------------------------------------**
** Implementation file for CXObject class **
** **
** Author: Phil Cooper **
** Created: 9/25/95 **
**----------------------------------------*/
#include "project.hpp"
#pragma hdrstop
#include "helpers.hpp"
#include "csite.hpp"
#include "xobj.hpp"
// CXObject is an extended control maintained by the container. The extended control aggregates
// the embedded control, but does not itself support being aggregated.
CXObject::CXObject(CSite *site, const char* name)
{
DBGOUT("CXObject::CXObject\n");
_dwRef = 0;
_pSite = site;
::SetRectEmpty(&_rcPos);
::SetSize(&_size, 0, 0);
_pInnerObj = NULL;
_pIOleObject = NULL;
_pInnerDisp = NULL;
_propName = NULL;
Ansi2Unicode(name, &_propName);
}
CXObject::~CXObject()
{
DBGOUT("CXObject::~CXObject\n");
if (_propName)
GTR_FREE(_propName);
}
// IUnknown methods
STDMETHODIMP_(ULONG) CXObject::AddRef(void)
{
return ++_dwRef;
}
STDMETHODIMP_(ULONG) CXObject::Release(void)
{
if (--_dwRef == 0)
{
delete this;
return 0;
}
return _dwRef;
}
STDMETHODIMP CXObject::QueryInterface(REFIID riid, LPVOID *ppvObj)
{
ASSERT(ppvObj != NULL);
DBGOUT("CXObject::QueryInterface\n");
if (ppvObj == NULL)
return E_INVALIDARG;
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch))
*ppvObj = this;
else
return _pInnerObj->QueryInterface(riid, ppvObj);
if (ppvObj != NULL)
{
((LPUNKNOWN)*ppvObj)->AddRef();
return S_OK;
}
else
return E_NOINTERFACE;
}
// IDispatch methods. _Really_ lame implementation. Don't take this too seriously...
STDMETHODIMP CXObject::Invoke(LONG DispId, REFIID riid, LCID locale, USHORT wFlags,
DISPPARAMS * pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
DBGOUT("CXObject::Invoke\n");
ASSERT(pVarResult != NULL);
if ((pVarResult != NULL) && (wFlags == DISPATCH_PROPERTYGET) && (DispId == DISPID_NAME))
{
pVarResult->vt = VT_BSTR;
pVarResult->bstrVal = get_Name();
return S_OK;
}
// Forward to aggregated control
ASSERT(_pInnerDisp != NULL);
if (_pInnerDisp != NULL)
return _pInnerDisp->Invoke(DispId, riid, locale, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
else
return E_UNEXPECTED;
}
STDMETHODIMP CXObject::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, UINT cNames, LCID lcid,
DISPID * rgDispId)
{
DBGOUT("CXObject::GetIDsOfNames\n");
ASSERT(riid == IID_NULL);
ASSERT(rgszNames != NULL);
HRESULT hr = S_OK;
if (!(IsEqualIID(riid, IID_NULL)))
return DISP_E_UNKNOWNINTERFACE;
LPOLESTR pName = *rgszNames;
DISPID *pDisp = rgDispId;
for (int i = 0; i < cNames ; i++)
{
if ((GetIDOfSingleName(lcid, pName, pDisp)) == DISP_E_UNKNOWNNAME)
hr = DISP_E_UNKNOWNNAME;
pDisp++;
pName++;
}
return hr;
}
STDMETHODIMP CXObject::GetTypeInfo(UINT itInfo, LCID lcid, ITypeInfo ** ppTypeInfo)
{
DBGOUT("CXObject::GetTypeInfo\n");
ASSERT(ppTypeInfo != NULL);
ASSERT(_pInnerDisp != NULL);
if (_pInnerDisp != NULL)
return _pInnerDisp->GetTypeInfo(itInfo, lcid, ppTypeInfo); // delegate to inner object;
else
return E_NOTIMPL;
}
STDMETHODIMP CXObject::GetTypeInfoCount(UINT *pctInfo)
{
DBGOUT("CXObject::GetTypeInfoCount\n");
ASSERT(pctInfo != NULL);
ASSERT(_pInnerDisp != NULL);
if (_pInnerDisp != NULL)
return _pInnerDisp->GetTypeInfoCount(pctInfo);
else
return E_NOTIMPL;
}
// Extended Property access functions
void CXObject::put_Name(BSTR newName)
{
DBGOUT("CXObject::put_Name\n");
ASSERT(newName != NULL);
if (_propName)
{
GTR_FREE(_propName);
_propName = NULL;
}
_propName = (LPOLESTR) GTR_MALLOC((SysStringLen(newName) * sizeof(OLECHAR)) + 1);
wcscpy(newName, _propName);
}
BSTR CXObject::get_Name(void)
{
DBGOUT("CXObject::get_Name\n");
return SysAllocString(_propName);
}
STDMETHODIMP CXObject::GetIDOfSingleName(LCID lcid, LPOLESTR pName, DISPID *pDisp)
{
DBGOUT("CXObject::GetIDOfSingleName\n");
ASSERT((pName != NULL) && (pDisp != NULL));
HRESULT hr = DISP_E_UNKNOWNNAME;
// If the ID for the "name" property has been requested...
if (pName != NULL)
{
if(_wcsicmp(pName, L"Name") == 0)
{
*pDisp = DISPID_NAME;
hr = NOERROR;
}
else
*pDisp = DISPID_UNKNOWN;
}
return hr;
}
// Public helper functions...
HRESULT CXObject::Initialize(void)
{
DBGOUT("CXObject::SetInnerObject\n");
ASSERT(_pInnerObj != NULL);
if (_pInnerObj == NULL)
return E_UNEXPECTED;
// Inner control must support a primary IDispatch
_pInnerObj->QueryInterface(IID_IDispatch, (void **)&_pInnerDisp);
ASSERT(_pInnerDisp != NULL);
if (_pInnerDisp == NULL)
return E_UNEXPECTED;
// Cache an IOleObject interface pointer
_pInnerObj->QueryInterface(IID_IOleObject, (void **)&_pIOleObject);
ASSERT(_pIOleObject != NULL); // Need an IOleObject, or we're really hosed.
if (_pIOleObject == NULL)
return E_UNEXPECTED;
InitializeControl();
AddRef();
return S_OK;
}
HRESULT CXObject::Activate(void)
{
ASSERT((_pIOleObject != NULL) && (_pSite != NULL) && (IsWindow(_pSite->_docWnd)));
if ((_pIOleObject != NULL) && (_pSite != NULL))
return _pIOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, _pSite->_pIOleClientSite, 0, _pSite->_docWnd, &_rcPos);
else
return E_UNEXPECTED;
}
HRESULT CXObject::Deactivate(void)
{
LPOLEINPLACEOBJECT lpInPlaceObject = NULL;
ASSERT(_pIOleObject != NULL);
if (_pIOleObject != NULL)
_pIOleObject->QueryInterface(IID_IOleInPlaceObject, (void **)&lpInPlaceObject);
if (lpInPlaceObject)
{
HRESULT hr = lpInPlaceObject->InPlaceDeactivate();
SAFERELEASE(lpInPlaceObject);
return hr;
}
return E_UNEXPECTED; // Embedded object doesn't support IOleInPlaceObject.
}
HRESULT CXObject::Hide(void)
{
ASSERT(_pIOleObject != NULL);
if (_pIOleObject != NULL)
{
HRESULT hr = _pIOleObject->DoVerb(OLEIVERB_HIDE, NULL, _pSite->_pIOleClientSite, 0, _pSite->_docWnd, NULL);
if (SUCCEEDED(hr) && (g_Container != NULL))
g_Container->DeleteSite(&_pSite->_SiteCookie);
return hr;
}
else
return E_UNEXPECTED;
}
HRESULT CXObject::Show(void)
{
ASSERT(_pIOleObject != NULL);
if (_pIOleObject != NULL)
{
HRESULT hr = _pIOleObject->DoVerb(OLEIVERB_SHOW, NULL, _pSite->_pIOleClientSite, 0, _pSite->_docWnd, NULL);
if (SUCCEEDED(hr) && (g_Container != NULL))
g_Container->AddSite(_pSite, &_pSite->_SiteCookie);
return hr;
}
else
return E_UNEXPECTED;
}
HRESULT CXObject::GetExtents(DWORD dwAspect, LPSIZEL pSize)
{
ASSERT((pSize != NULL) && (_pIOleObject != NULL));
if (_pIOleObject != NULL)
return _pIOleObject->GetExtent(dwAspect, pSize);
else
return E_UNEXPECTED;
}
HRESULT CXObject::SetClientSite(LPOLECLIENTSITE pIOleClientSite)
{
ASSERT((pIOleClientSite != NULL) && (_pIOleObject != NULL));
if (pIOleClientSite != NULL)
return _pIOleObject->SetClientSite(pIOleClientSite);
else
return E_INVALIDARG;
}
void CXObject::Destroy(void)
{
SAFERELEASE(_pIOleObject);
SAFERELEASE(_pInnerDisp);
SAFERELEASE(_pInnerObj); // Must be released last. This destroys embedded object.
Release(); // Final release on XObject. Bye-Bye!
}
HRESULT CXObject::InitializeControl(LPSTREAM pStream)
{
HRESULT hr = E_FAIL;
LPPERSISTSTREAMINIT pInit = NULL;
if (SUCCEEDED(QueryInterface(IID_IPersistStreamInit, (void **)&pInit)))
{
if (pStream != NULL)
hr = pInit->Load(pStream);
else
hr = pInit->InitNew();
SAFERELEASE(pInit);
}
else
return hr; // This initialization function requires support for IPersistStreamInit
// Get the control's desired size.
SIZE himetric;
ASSERT(_pIOleObject != NULL);
if ((SUCCEEDED(hr)) && (_pIOleObject != NULL))
hr = _pIOleObject->GetExtent(DVASPECT_CONTENT, &himetric);
else
return E_UNEXPECTED;
ASSERT((_pSite != NULL) && (IsWindow(_pSite->_docWnd)));
if ((SUCCEEDED(hr)) && (_pSite != NULL))
{
HDC hdc = GetDC(_pSite->_docWnd);
if (hdc == NULL)
return E_UNEXPECTED;
XformSizeInHimetricToPixels(hdc, &himetric, &_size);
ReleaseDC(_pSite->_docWnd, hdc);
return hr;
}
else
return E_UNEXPECTED;
}