STDMETHODIMP CTCMarshalByValue::GetMarshalSizeMax(REFIID riid, void* pv,
  DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
  UNUSED(riid);
  UNUSED(pv);
  UNUSED(dwDestContext);
  UNUSED(pvDestContext);
  UNUSED(mshlflags);

  // Initialize the [out] parameter
  *pSize = 0;

  // Delegate to the IPersistStream::GetSizeMax of the controlling unknown
  IPersistStreamPtr pps;
  HRESULT hr = GetOuterPersistStream(&pps);
  if (SUCCEEDED(hr))
  {
    // Include the size of an endian indicator DWORD value
    ULARGE_INTEGER uli;
    if (SUCCEEDED(hr = pps->GetSizeMax(&uli)) || (E_NOTIMPL == hr
      && SUCCEEDED(hr = TCGetPersistStreamSize(pps, &uli))))
        *pSize = uli.LowPart + sizeof(m_dwEndian);
  }

  // Display a trace message
  #if defined(_DEBUG) && defined(CTCMarshalByValue_DEBUG)
    _TRACE1("CTCMarshalByValue::GetMarshalSizeMax(): returning 0x%08X\n", *pSize);
  #endif

  // Return the last HRESULT
  return hr;
}
STDMETHODIMP CTCMarshalByValue::GetUnmarshalClass(REFIID riid, void* pv,
  DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
  UNUSED(riid);
  UNUSED(pv);
  UNUSED(dwDestContext);
  UNUSED(pvDestContext);
  UNUSED(mshlflags);

  // Delegate to the IPersistStream::GetClassID of the controlling unknown
  IPersistStreamPtr spps;
  HRESULT hr = GetOuterPersistStream(&spps);
  if (SUCCEEDED(hr))
    hr = spps->GetClassID(pCid);

  // Return the last HRESULT
  return hr;
}
STDMETHODIMP CTCMarshalByValue::UnmarshalInterface(IStream* pStm,
  REFIID riid, void** ppv)
{
  // Read the endian indicator DWORD value from the stream
  CLock lock(this);
  HRESULT hr = pStm->Read(&m_dwEndian, sizeof(m_dwEndian), NULL);
  if (SUCCEEDED(hr))
  {
    // Unlock the object
    lock.Unlock();

    // Delegate to the IPersistStream::Load of the controlling unknown
    IPersistStreamPtr pps;
    if (SUCCEEDED(hr = GetOuterPersistStream(&pps)))
      if (SUCCEEDED(hr = pps->Load(pStm)))
        hr = pps->QueryInterface(riid, ppv);
  }

  // Return the last HRESULT
  return hr;
}
STDMETHODIMP CTCMarshalByValue::MarshalInterface(IStream* pStm, REFIID riid,
  void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags)
{
  UNUSED(riid);
  UNUSED(pv);
  UNUSED(dwDestContext);
  UNUSED(pvDestContext);
  UNUSED(mshlflags);

  // Write an endian indicator DWORD value to the stream
  DWORD dwEndian = m_dwEndianOriginal;
  HRESULT hr = pStm->Write(&dwEndian, sizeof(dwEndian), NULL);
  if (SUCCEEDED(hr))
  {
    // Delegate to the IPersistStream::Save of the controlling unknown
    IPersistStreamPtr pps;
    if (SUCCEEDED(hr = GetOuterPersistStream(&pps)))
      hr = pps->Save(pStm, FALSE);
  }

  // Return the last HRESULT
  return hr;
}
Пример #5
0
/////////////////////////////////////////////////////////////////////////////
//功 能:创建或者导入控件项目
/////////////////////////////////////////////////////////////////////////////
BOOL CCtrlItem::CreateOrLoad(REFCLSID clsid, 
	REFIID iidPersistanceMedium, IUnknown* pPersistanceMedium)
{
	HRESULT hResult;
	BOOL bSuccess;
	IPersistStreamInitPtr pPersistStreamInit;
	IPersistStreamPtr pPersistStream;
	IPersistStoragePtr pPersistStorage;
	IStreamPtr pStream;
	IStoragePtr pStorage;

	ASSERT(m_lpObject == NULL);
	ASSERT(m_pDocument != NULL);

	m_dwItemNumber = GetNewItemNumber();
	GetItemStorage();
	ASSERT(m_lpStorage != NULL);

   	m_bExtendedControl = TRUE;
	hResult = CExtendedControl::CreateInstance(clsid, this, NULL,
		IID_IOleObject, (void**)&m_lpObject);
	if (FAILED(hResult))
	{
		m_bExtendedControl = FALSE;
		hResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|
			CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER, IID_IOleObject,
			(void**)&m_lpObject);

		if (SUCCEEDED(hResult))
		{
			TRACE("Could not aggregate on the control, so it won't support extended properties.\n");
		}
	}

	if (m_bExtendedControl)
	{
		m_pExtendedControl = m_lpObject;
		ASSERT(m_pExtendedControl != NULL);
	}

	//设置客户站点
	if (SUCCEEDED(hResult))
	{
		m_lpObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
		if (m_dwMiscStatus&OLEMISC_SETCLIENTSITEFIRST)
		{
			//GetClientSite 得到接口
			hResult = m_lpObject->SetClientSite(GetClientSite());
			if (FAILED(hResult))
			{
			   TRACE("SetClientSite failed.\n");
			}
		 }
	}

	//初始化或装载对象的状态
	if (SUCCEEDED(hResult))
	{
		if( iidPersistanceMedium == IID_NULL )
		{
			pPersistStreamInit = m_lpObject;
			if (pPersistStreamInit != NULL)
			{
				hResult = pPersistStreamInit->InitNew();
				if (hResult == E_NOTIMPL)
				{
					//没有实现 InitNew 为 Ok。
					hResult = S_OK;
				}
			}
			else
			{
				pPersistStorage = m_lpObject;
				if (pPersistStorage != NULL)
				{
					hResult = pPersistStorage->InitNew(m_lpStorage);
				}
				else
				{
					// 假设控件不支持持久性。
					hResult = S_OK;
				}
			}
		}
		else if (iidPersistanceMedium == IID_IStream)
		{
			pStream = pPersistanceMedium;
			ASSERT(pStream != NULL);

			pPersistStreamInit = m_lpObject;
			if (pPersistStreamInit != NULL)
			{
				hResult = pPersistStreamInit->Load(pStream);
			}
			else
			{
				pPersistStream = m_lpObject;
				if (pPersistStream != NULL)
				{
					hResult = pPersistStream->Load(pStream);
				}
				else
				{
					hResult = E_NOINTERFACE;
				}
			}
		}
		else if (iidPersistanceMedium == IID_IStorage)
		{
			pStorage = pPersistanceMedium;
			ASSERT(pStorage != NULL);

			pPersistStorage = m_lpObject;
			if (pPersistStorage != NULL)
			{
				hResult = pStorage->CopyTo(0, NULL, NULL, m_lpStorage);
				if (SUCCEEDED(hResult))
				{
					hResult = pPersistStorage->Load(m_lpStorage);
				}
			}
			else
			{
				hResult = E_NOINTERFACE;
			}
		}
	}

	if (SUCCEEDED(hResult))
	{
		if (!(m_dwMiscStatus&OLEMISC_SETCLIENTSITEFIRST))
		{
			hResult = m_lpObject->SetClientSite(GetClientSite());
			if (FAILED(hResult))
			{
				TRACE("SetClientSite failed.\n");
			}
		}
	}
	//SetClientSite 必须被使用

	bSuccess = FinishCreate(hResult);

	return bSuccess;
}