void CColorButtonCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // Call PX_ functions for each persistent custom property. PX_Short(pPX, _T("BevelWidth"), m_BevelWidth, 2); PX_Color(pPX, _T("BackColor"), m_BackColor, ::GetSysColor(COLOR_BTNFACE)); PX_Color(pPX, _T("ForeColor"), m_ForeColor, ::GetSysColor(COLOR_BTNTEXT)); PX_String(pPX, _T("Caption"), m_sCaption, AmbientDisplayName()); }
BOOL COleControl::GetPropsetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium, REFCLSID fmtid) { ASSERT_VALID(this); ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE)); ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM))); BOOL bGetDataHere = (lpStgMedium->tymed != TYMED_NULL); // Allow IStream or IStorage as the storage medium. if (!(lpFormatEtc->tymed & (TYMED_ISTREAM|TYMED_ISTORAGE))) { TRACE0("Propset only supported for stream or storage.\n"); return FALSE; } LPSTORAGE lpStorage = NULL; LPSTREAM lpStream = NULL; if (lpFormatEtc->tymed & TYMED_ISTORAGE) { // Caller wants propset data in a storage object. if (bGetDataHere) { // Use the caller-supplied storage object. lpStorage = lpStgMedium->pstg; } else { // Create a storage object on a memory ILockBytes implementation. LPLOCKBYTES lpLockBytes = NULL; if (FAILED(CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes))) { TRACE0("CreateILockBytesOnHGlobal failed.\n"); return FALSE; } ASSERT_POINTER(lpLockBytes, ILockBytes); if (FAILED(StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage))) { TRACE0("StgCreateDocfileOnILockBytes failed.\n"); lpLockBytes->Release(); return FALSE; } // Docfile now has reference to ILockBytes, so release ours. lpLockBytes->Release(); } ASSERT_POINTER(lpStorage, IStorage); // Create a stream within the storage. if (FAILED(lpStorage->CreateStream(OLESTR("Contents"), STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, 0, &lpStream))) { TRACE0("IStorage::CreateStream failed.\n"); if (!bGetDataHere) lpStorage->Release(); return FALSE; } } else { // Caller wants propset data in a stream object. if (bGetDataHere) { // Use the caller-supplied stream object lpStream = lpStgMedium->pstm; } else { lpStream = _AfxCreateMemoryStream(); if (lpStream == NULL) return FALSE; } } ASSERT_POINTER(lpStream, IStream); // Create the property set. CLSID clsid; GetClassID(&clsid); CPropertySet pset(clsid); pset.SetOSVersion(MAKELONG(LOWORD(GetVersion()), OSTYPE)); CPropertySection* ppsec = pset.AddSection(fmtid); if (ppsec == NULL) { TRACE0("CPropertySet::AddSection failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Set the name, based on the ambient display name (from the container). ppsec->SetSectionName(AmbientDisplayName()); CPropsetPropExchange propx(*ppsec, lpStorage, FALSE); BOOL bPropExchange = FALSE; TRY { DoPropExchange(&propx); bPropExchange = TRUE; } END_TRY if (!bPropExchange) { TRACE0("DoPropExchange failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Store the property set in the stream. if (FAILED(pset.WriteToStream(lpStream))) { TRACE0("CPropertySet::WriteToStream failed.\n"); lpStream->Release(); lpStorage->Release(); return FALSE; } // Return the property set in the requested medium. if (lpFormatEtc->tymed & TYMED_ISTORAGE) { // Return as a storage object. ASSERT_POINTER(lpStorage, IStorage); lpStream->Release(); lpStgMedium->pstg = lpStorage; lpStgMedium->tymed = TYMED_ISTORAGE; lpStgMedium->pUnkForRelease = NULL; } else { // Return as a stream. ASSERT_POINTER(lpStream, IStream); lpStgMedium->pstm = lpStream; lpStgMedium->tymed = TYMED_ISTREAM; lpStgMedium->pUnkForRelease = NULL; } return TRUE; }