⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctlpset.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"

#ifdef AFXCTL_PROP_SEG
#pragma code_seg(AFXCTL_PROP_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW

#define OSTYPE 2    // Win32

AFX_STATIC_DATA LARGE_INTEGER _afxLargeZero = { 0,0 };

// Old class IDs for font and picture types
AFX_STATIC_DATA const CLSID _afx_CLSID_StdFont_V1 =
	{ 0xfb8f0823,0x0164,0x101b, { 0x84,0xed,0x08,0x00,0x2b,0x2e,0xc7,0x13 } };
AFX_STATIC_DATA const CLSID _afx_CLSID_StdPicture_V1 =
	{ 0xfb8f0824,0x0164,0x101b, { 0x84,0xed,0x08,0x00,0x2b,0x2e,0xc7,0x13 } };

LPSTREAM AFXAPI _AfxCreateMemoryStream()
{
	LPSTREAM lpStream = NULL;

	// Create a stream object on a memory block.
	HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, 0);
	if (hGlobal != NULL)
	{
		if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &lpStream)))
		{
			TRACE0("CreateStreamOnHGlobal failed.\n");
			GlobalFree(hGlobal);
			return NULL;
		}

		ASSERT_POINTER(lpStream, IStream);
	}
	else
	{
		TRACE0("Failed to allocate memory for stream.\n");
		return NULL;
	}

	return lpStream;
}

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;
}

BOOL COleControl::SetPropsetData(LPFORMATETC lpFormatEtc,
		LPSTGMEDIUM lpStgMedium, REFCLSID fmtid)
{
	UNUSED(lpFormatEtc); // unused in release builds

	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));

	// Get the stream that contains the property set.

	LPSTORAGE lpStorage = NULL;
	LPSTREAM lpStream = NULL;

	switch (lpStgMedium->tymed)
	{
	case TYMED_ISTORAGE:
		{
			lpStorage = lpStgMedium->pstg;
			ASSERT_POINTER(lpStorage, IStorage);
			if (FAILED(lpStorage->OpenStream(OLESTR("Contents"), 0,
					STGM_SHARE_EXCLUSIVE|STGM_READ, 0, &lpStream)))
			{
				TRACE0("Failed to open content stream.\n");
				return FALSE;
			}
		}
		break;

	case TYMED_ISTREAM:
		lpStorage = NULL;
		lpStream = lpStgMedium->pstm;
		break;

	default:
		TRACE0("Propset only supported for stream or storage.\n");
		return FALSE;
	}

	ASSERT_POINTER(lpStream, IStream);

	// Read the property set from the stream.

	CPropertySet pset;
	if (!pset.ReadFromStream(lpStream))
	{
		TRACE0("CPropertySet::ReadFromStream failed.\n");
		return FALSE;
	}

	CPropertySection* ppsec = pset.GetSection(fmtid);
	if (ppsec == NULL)
	{
		TRACE0("CLSID_PersistPropset section not found in property set.\n");
		return FALSE;
	}

	// Detect whether we're converting a VBX
	m_bConvertVBX = (BYTE)IsEqualGUID(fmtid, CLSID_ConvertVBX);

	// Parse the property set.

	CPropsetPropExchange propx(*ppsec, lpStorage, TRUE);

	BOOL bPropExchange = FALSE;
	TRY
	{
		DoPropExchange(&propx);
		bPropExchange = TRUE;
	}
	END_TRY

	// Properties have probably changed
	BoundPropertyChanged(DISPID_UNKNOWN);
	InvalidateControl();

	m_bConvertVBX = FALSE;

	// Clear the modified flag.
	m_bModified = FALSE;

	// Unless IOleObject::SetClientSite is called after this, we can
	// count on ambient properties being available while loading.
	m_bCountOnAmbients = TRUE;

	// Properties have been initialized
	m_bInitialized = TRUE;

	// Cleanup.
	if (lpStorage != NULL)      // If we called OpenStream(), release now.
		lpStream->Release();

	BoundPropertyChanged(DISPID_UNKNOWN);
	return bPropExchange;
}

CPropsetPropExchange::CPropsetPropExchange(CPropertySection& psec,
		LPSTORAGE lpStorage, BOOL bLoading) :
	m_psec(psec),
	m_lpStorage(lpStorage),
	m_dwPropID(255)
{
	ASSERT_POINTER(&psec, CPropertySection);
	ASSERT_NULL_OR_POINTER(lpStorage, IStorage);

	m_bLoading = bLoading;
}

AFX_STATIC size_t AFXAPI _AfxGetSizeOfVarType(VARTYPE vt)
{
	switch (vt)
	{
	case VT_I2:
	case VT_BOOL:
		return 2;

	case VT_I4:
	case VT_R4:
		return 4;

	case VT_R8:
		return 8;

	case VT_CY:
		return sizeof(CURRENCY);

	case VT_BSTR:
		return sizeof(BSTR);
	}

	return 0;
}

BOOL AFXAPI _AfxCoerceNumber(void* pvDst, VARTYPE vtDst, void* pvSrc, VARTYPE vtSrc)
{
	// Check size of source.
	size_t cbSrc = _AfxGetSizeOfVarType(vtSrc);
	if (cbSrc == 0)
		return FALSE;

	// If source and destination are same type, just copy.
	if (vtSrc == vtDst)
	{
		memcpy(pvDst, pvSrc, cbSrc);
		return TRUE;
	}

	// Check size of destination.
	size_t cbDst = _AfxGetSizeOfVarType(vtDst);

	if (cbDst == 0)
		return FALSE;

	// Initialize variant for coercion.
	VARIANTARG var;
	V_VT(&var) = vtSrc;
	memcpy((void*)&V_NONE(&var), pvSrc, cbSrc);

	// Do the coercion.
	if (FAILED(VariantChangeType(&var, &var, 0, vtDst)))
		return FALSE;

	// Copy result to destination.
	memcpy(pvDst, (void*)&V_NONE(&var), cbDst);
	return TRUE;
}

BOOL AFXAPI _AfxIsSamePropValue(VARTYPE vtProp, const void* pv1, const void* pv2)
{
	if (pv1 == pv2)
		return TRUE;

	if ((pv1 == NULL) || (pv2 == NULL))
		return FALSE;

	BOOL bSame = FALSE;

	switch (vtProp)
	{
	case VT_BSTR:
		bSame = ((CString*)pv1)->Compare(*(CString*)pv2) == 0;
		break;
	case VT_LPSTR:
		bSame = ((CString*)pv1)->Compare((LPCTSTR)pv2) == 0;
		break;

	case VT_BOOL:
	case VT_I2:
	case VT_I4:
	case VT_CY:
	case VT_R4:
	case VT_R8:
		bSame = memcmp(pv1, pv2, _AfxGetSizeOfVarType(vtProp)) == 0;
		break;
	}

	return bSame;
}

BOOL CPropsetPropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
	void* pvProp, const void* pvDefault)
{
	USES_CONVERSION;

	ASSERT(AfxIsValidString(pszPropName));
	ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
	ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));

	BOOL bSuccess = FALSE;

	if (m_bLoading)
	{
		DWORD dwPropID;
		LPVOID pvData;
		CProperty* pprop;

		if (m_psec.GetID(pszPropName, &dwPropID) &&
			((pprop = m_psec.GetProperty(dwPropID)) != NULL) &&
			((pvData = pprop->Get()) != NULL))
		{
			VARTYPE vtData = (VARTYPE)pprop->GetType();

			CString strTmp;

#ifdef _UNICODE
			// Unicode is "native" format
			if ((vtData == VT_BSTR) || (vtData == VT_LPWSTR))
#else
			// ANSI is "native" format
			if ((vtData == VT_BSTR) || (vtData == VT_LPSTR))
#endif
			{
				strTmp = (LPCTSTR)pvData;
			}

#ifdef _UNICODE
			else if (vtData == VT_LPSTR)
			{
				// Convert from ANSI to Unicode
				strTmp = (LPCSTR)pvData;
			}
#else
			else if (vtData == VT_LPWSTR)
			{
				// Convert from Unicode to ANSI
				strTmp = (LPCWSTR)pvData;
			}
#endif

			switch (vtProp)
			{
			case VT_LPSTR:
			case VT_BSTR:
				bSuccess = _AfxCopyPropValue(VT_BSTR, pvProp, &strTmp);
				break;

			case VT_BOOL:
				{
					short sProp;
					BSTR bstrTmp = NULL;

					if ((vtData == VT_BSTR) || (vtData == VT_LPSTR) ||
						(vtData == VT_LPWSTR))
					{
						bstrTmp = SysAllocString(T2COLE(strTmp));
						pvData = &bstrTmp;
						vtData = VT_BSTR;
					}

					bSuccess = _AfxCoerceNumber(&sProp, VT_BOOL, pvData,
						vtData);

					if (bstrTmp != NULL)
						SysFreeString(bstrTmp);

					if (bSuccess)
					{
						ASSERT((sProp == -1) || (sProp == 0));
						*(BOOL*)pvProp = !!sProp;
					}
				}
				break;

			case VT_I2:
			case VT_I4:
			case VT_CY:
			case VT_R4:
			case VT_R8:
				bSuccess = _AfxCoerceNumber(pvProp, vtProp, pvData, vtData);
				break;
			}
		}
		else
		{
			bSuccess = _AfxCopyPropValue(vtProp, pvProp, pvDefault);
		}
	}
	else
	{
		if (!_AfxIsSamePropValue(vtProp, pvProp, pvDefault))
		{
			++m_dwPropID;

			LPVOID pvData = NULL;
			BOOL bData;

			switch (vtProp)
			{
			case VT_LPSTR:
			case VT_BSTR:
				pvData = (LPVOID)(LPCTSTR)*(CString*)pvProp;
				break;

			case VT_BOOL:
				// Convert boolean value to -1 or 0.
				bData = (*(BOOL*)pvProp) ? -1 : 0;
				pvData = &bData;
				break;

			case VT_I2:
			case VT_I4:
			case VT_CY:
			case VT_R4:
			case VT_R8:
				pvData = pvProp;
				break;
			}

			bSuccess = m_psec.SetName(m_dwPropID, pszPropName) &&
				m_psec.Set(m_dwPropID, pvData, vtProp);
		}
		else
		{
			bSuccess = TRUE;
		}
	}

	return bSuccess;
}

BOOL CPropsetPropExchange::ExchangeBlobProp(LPCTSTR pszPropName,
	HGLOBAL* phBlob, HGLOBAL hBlobDefault)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -