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; }
///////////////////////////////////////////////////////////////////////////// //功 能:创建或者导入控件项目 ///////////////////////////////////////////////////////////////////////////// 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; }