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

📄 olepset.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		pIStream->Seek(li, STREAM_SEEK_CUR, NULL);

		// Now pIStream is at the type/value pair
		if (pido.propertyID != 0)
		{
			pProp = new CProperty(pido.propertyID, NULL, 0);
			pProp->ReadFromStream(pIStream);
			m_PropList.AddTail(pProp);
		}
		else
		{
			ReadNameDictFromStream(pIStream);
		}
	}

	pIStrPIDO->Release();

	return TRUE;
}

BOOL CPropertySection::GetID(LPCTSTR pszName, DWORD* pdwPropID)
{
	CString strName(pszName);
	strName.MakeLower();        // Dictionary stores all names in lowercase

	void* pvID;
	if (m_NameDict.Lookup(strName, pvID))
	{
		*pdwPropID = (DWORD)pvID;
		return TRUE;
	}

	// Failed to find entry in dictionary
	return FALSE;
}

BOOL CPropertySection::SetName(DWORD dwPropID, LPCTSTR pszName)
{
	BOOL bSuccess = TRUE;
	CString strName(pszName);
	strName.MakeLower();        // Dictionary stores all names in lowercase

	TRY
	{
		void* pDummy;
		BOOL bNameExists = m_NameDict.Lookup(strName, pDummy);

		ASSERT(!bNameExists);  // Property names must be unique.

		if (bNameExists)
			bSuccess = FALSE;
		else
			m_NameDict.SetAt(strName, (void*)dwPropID);
	}
	CATCH (CException, e)
	{
		TRACE0("Failed to add entry to dictionary.\n");
		bSuccess = FALSE;
	}
	END_CATCH

	return bSuccess;
}

struct DICTENTRYHEADER
{
	DWORD dwPropID;
	DWORD cb;
};

struct DICTENTRY
{
	DICTENTRYHEADER hdr;
	char sz[256];
};

BOOL CPropertySection::ReadNameDictFromStream(IStream* pIStream)
{
	ULONG cb;
	ULONG cbRead = 0;

	// Read dictionary header (count).
	ULONG cProperties = 0;
	pIStream->Read((LPVOID)&cProperties, sizeof(cProperties), &cb);
	if (sizeof(cProperties) != cb)
	{
		TRACE0("Read of dictionary header failed.\n");
		return FALSE;
	}

	ULONG iProp;
	DICTENTRY entry;

	for (iProp = 0; iProp < cProperties; iProp++)
	{
		// Read entry header (dwPropID, cch).
		if (FAILED(pIStream->Read((LPVOID)&entry, sizeof(DICTENTRYHEADER),
			&cbRead)) ||
			(sizeof(DICTENTRYHEADER) != cbRead))
		{
			TRACE0("Read of dictionary entry failed.\n");
			return FALSE;
		}

		// Read entry data (name).

		cb = entry.hdr.cb;

		if (FAILED(pIStream->Read((LPVOID)&entry.sz, cb, &cbRead)) ||
			(cbRead != cb))
		{
			TRACE0("Read of dictionary entry failed.\n");
			return FALSE;
		}

		LPTSTR pszName;

#ifdef _UNICODE
		// Persistent form is always ANSI/DBCS.  Convert to Unicode.
		WCHAR wszName[256];
		_mbstowcsz(wszName, entry.sz, 256);
		pszName = wszName;
#else // _UNICODE
		pszName = entry.sz;
#endif // _UNICODE

		// Section's "name" appears first in list and has dwPropID == 0.
		if ((iProp == 0) && (entry.hdr.dwPropID == 0))
			m_strSectionName = pszName;             // Section name
		else
			SetName(entry.hdr.dwPropID, pszName);   // Some other property
	}

	return TRUE;
}

AFX_STATIC BOOL AFXAPI _AfxWriteNameDictEntry(IStream* pIStream, DWORD dwPropID, CString& strName)
{
	ULONG cb;
	ULONG cbWritten = 0;
	DICTENTRY entry;

	entry.hdr.dwPropID = dwPropID;
	entry.hdr.cb = min(strName.GetLength() + 1, 255);
#ifdef _UNICODE
	// Persistent form is always ANSI/DBCS.  Convert from Unicode.
	_wcstombsz(entry.sz, (LPCWSTR)strName, 256);
#else // _UNICODE
	memcpy(entry.sz, (LPCSTR)strName, (size_t)entry.hdr.cb);
#endif // _UNICODE

	cb = sizeof(DICTENTRYHEADER) + entry.hdr.cb;

	if (FAILED(pIStream->Write((LPVOID)&entry, cb, &cbWritten)) ||
		(cbWritten != cb))
	{
		TRACE0("Write of dictionary entry failed.\n");
		return FALSE;
	}

	return TRUE;
}

BOOL CPropertySection::WriteNameDictToStream(IStream* pIStream)
{
	ULONG cb;

	// Write dictionary header (count).
	ULONG cProperties = m_NameDict.GetCount() + 1;
	pIStream->Write((LPVOID)&cProperties, sizeof(cProperties), &cb);
	if (sizeof(cProperties) != cb)
	{
		TRACE0("Write of dictionary header failed.\n");
		return FALSE;
	}

	POSITION pos;
	CString strName;
	void* pvID;

	// Write out section's "name" with dwPropID == 0 first
	if (!_AfxWriteNameDictEntry(pIStream, 0, m_strSectionName))
		return FALSE;

	// Enumerate contents of dictionary and write out (dwPropID, cb, name).
	pos = m_NameDict.GetStartPosition();
	while (pos != NULL)
	{
		m_NameDict.GetNextAssoc(pos, strName, pvID);
		if (!_AfxWriteNameDictEntry(pIStream, (DWORD)pvID, strName))
			return FALSE;
	}

	return TRUE;
}

BOOL CPropertySection::SetSectionName(LPCTSTR pszName)
{
	m_strSectionName = pszName;
	return TRUE;
}

LPCTSTR CPropertySection::GetSectionName()
{
	return (LPCTSTR)m_strSectionName;
}

/////////////////////////////////////////////////////////////////////////////
// Implementation of the CPropertySet class

CPropertySet::CPropertySet()
{
	m_PH.wByteOrder = 0xFFFE;
	m_PH.wFormat = 0;
	m_PH.dwOSVer = (DWORD)MAKELONG(LOWORD(GetVersion()), 2);
	m_PH.clsID =  GUID_NULL;
	m_PH.cSections = 0;

}

CPropertySet::CPropertySet(CLSID clsID)
{
	m_PH.wByteOrder = 0xFFFE;
	m_PH.wFormat = 0;
	m_PH.dwOSVer = (DWORD)MAKELONG(LOWORD(GetVersion()), 2);
	m_PH.clsID = clsID;
	m_PH.cSections = 0;
}

CPropertySet::~CPropertySet()
{   RemoveAll();  }

BOOL CPropertySet::Set(CLSID FormatID, DWORD dwPropID, LPVOID pValue, DWORD dwType)
{
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect == NULL)
	{
		if ((pSect = new CPropertySection(FormatID)) != NULL)
			AddSection(pSect);
	}
	pSect->Set(dwPropID, pValue, dwType);
	return TRUE;
}

BOOL CPropertySet::Set(CLSID FormatID, DWORD dwPropID, LPVOID pValue)
{
	// Since there is no dwType, we have to assume that the property
	// already exists.  If it doesn't, fail.
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect != NULL)
		return pSect->Set(dwPropID, pValue);
	else
		return FALSE;
}

LPVOID CPropertySet::Get(CLSID FormatID, DWORD dwPropID, DWORD* pcb)
{
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect)
		return pSect->Get(dwPropID, pcb);
	else
		return NULL;
}

LPVOID CPropertySet::Get(CLSID FormatID, DWORD dwPropID)
{   return Get(FormatID, dwPropID, (DWORD*)NULL); }

void CPropertySet::Remove(CLSID FormatID, DWORD dwPropID)
{
	CPropertySection*  pSect = GetSection(FormatID);
	if (pSect)
		pSect->Remove(dwPropID);
}

void CPropertySet::Remove(CLSID FormatID)
{
	CPropertySection* pSect;
	POSITION posRemove = m_SectionList.GetHeadPosition();
	POSITION pos = posRemove;
	while (posRemove != NULL)
	{
		pSect = (CPropertySection*)m_SectionList.GetNext(pos);
		if (IsEqualCLSID(pSect->m_FormatID, FormatID))
		{
			m_SectionList.RemoveAt(posRemove);
			delete pSect;
			m_PH.cSections--;
			return;
		}
		posRemove = pos;
	}
}

void CPropertySet::RemoveAll()
{
	POSITION pos = m_SectionList.GetHeadPosition();
	while (pos != NULL)
	{
		delete (CPropertySection*)m_SectionList.GetNext(pos);
	}
	m_SectionList.RemoveAll();
	m_PH.cSections = 0;
}

CPropertySection* CPropertySet::GetSection(CLSID FormatID)
{
	POSITION pos = m_SectionList.GetHeadPosition();
	CPropertySection* pSect;
	while (pos != NULL)
	{
		pSect = (CPropertySection*)m_SectionList.GetNext(pos);
		if (IsEqualCLSID(pSect->m_FormatID, FormatID))
			return pSect;
	}
	return NULL;
}

CPropertySection* CPropertySet::AddSection(CLSID FormatID)
{
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect)
		return pSect;

	pSect = new CPropertySection(FormatID);
	if (pSect)
		AddSection(pSect);
	return pSect;
}

void CPropertySet::AddSection(CPropertySection* pSect)
{
	m_SectionList.AddTail(pSect);
	m_PH.cSections++;
}

CProperty* CPropertySet::GetProperty(CLSID FormatID, DWORD dwPropID)
{
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect)
		return pSect->GetProperty(dwPropID);
	else
		return NULL;
}

void CPropertySet::AddProperty(CLSID FormatID, CProperty* pProp)
{
	CPropertySection* pSect = GetSection(FormatID);
	if (pSect)
		pSect->AddProperty(pProp);
}

WORD CPropertySet::GetByteOrder()
{   return m_PH.wByteOrder;  }

WORD CPropertySet::GetFormatVersion()
{   return m_PH.wFormat;  }

void CPropertySet::SetFormatVersion(WORD wFmtVersion)
{   m_PH.wFormat = wFmtVersion;  }

DWORD CPropertySet::GetOSVersion()
{   return m_PH.dwOSVer;  }

void CPropertySet::SetOSVersion(DWORD dwOSVer)
{   m_PH.dwOSVer = dwOSVer;  }

CLSID CPropertySet::GetClassID()
{   return m_PH.clsID;  }

void CPropertySet::SetClassID(CLSID clsID)
{   m_PH.clsID = clsID;  }

DWORD CPropertySet::GetCount()
{   return m_SectionList.GetCount();  }

CPtrList* CPropertySet::GetList()
{   return &m_SectionList;  }


BOOL CPropertySet::WriteToStream(IStream* pIStream)
{
	LPSTREAM        pIStrFIDO;
	FORMATIDOFFSET  fido;
	ULONG           cb;
	ULARGE_INTEGER  ulSeek;
	LARGE_INTEGER   li;

	// Write the Property List Header
	m_PH.cSections = m_SectionList.GetCount();
	pIStream->Write((LPVOID)&m_PH, sizeof(m_PH), &cb);
	if (sizeof(m_PH) != cb)
	{
		TRACE0("Write of Property Set Header failed.\n");
		return FALSE;
	}

	if (m_SectionList.IsEmpty())
	{
		TRACE0("Warning: Wrote empty property set.\n");
		return TRUE;
	}

	// After the header is the list of Format ID/Offset pairs
	// Since there is an ID/Offset pair for each section and we
	// need to write the ID/Offset pair as we write each section
	// we clone the stream and use the clone to access the
	// table of ID/offset pairs (FIDO)...
	//
	pIStream->Clone(&pIStrFIDO);

	// Now seek pIStream past the FIDO list
	//
	LISet32(li, m_PH.cSections * sizeof(FORMATIDOFFSET));
	pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);

	// Write each section.
	CPropertySection*   pSect = NULL;
	POSITION            pos = m_SectionList.GetHeadPosition();
	while (pos != NULL)
	{
		// Get next element (note cast)
		pSect = (CPropertySection*)m_SectionList.GetNext(pos);

		// Write it
		if (!pSect->WriteToStream(pIStream))
		{
			pIStrFIDO->Release();
			return FALSE;
		}

		// Using our cloned stream write the Format ID / Offset pair
		fido.formatID = pSect->m_FormatID;
		fido.dwOffset = ulSeek.LowPart;
		pIStrFIDO->Write((LPVOID)&fido, sizeof(fido), &cb);
		if (sizeof(fido) != cb)
		{
			TRACE0("Write of 'fido' failed.\n");
			pIStrFIDO->Release();
			return FALSE;
		}

		// Get the seek offset (for pIStream) after the write
		LISet32(li, 0);
		pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);
	}

	pIStrFIDO->Release();

	return TRUE;
}

BOOL CPropertySet::ReadFromStream(IStream* pIStream)
{
	ULONG               cb;
	FORMATIDOFFSET      fido;
	ULONG               cSections;
	LPSTREAM            pIStrFIDO;
	CPropertySection*   pSect;
	LARGE_INTEGER       li;
	LARGE_INTEGER       liPropSet;

	// Save the stream position at which the property set starts.
	LARGE_INTEGER liZero = {0,0};
	pIStream->Seek(liZero, STREAM_SEEK_CUR, (ULARGE_INTEGER*)&liPropSet);

	if (m_PH.cSections || !m_SectionList.IsEmpty())
		 RemoveAll();

	// The stream starts like this:
	//  wByteOrder   wFmtVer   dwOSVer   clsID  cSections
	// Which is nice, because our PROPHEADER is the same!
	pIStream->Read((LPVOID)&m_PH, sizeof(m_PH), &cb);
	if (cb != sizeof(m_PH))
		return FALSE;

	// Now we're pointing at the first of the FormatID/Offset pairs
	// (FIDOs).   To get to each section we use a cloned stream
	// to stay back and point at the FIDOs (pIStrFIDO).  We seek
	// pIStream to each of the sections, creating CProperitySection
	// and so forth as we go...
	//
	pIStream->Clone(&pIStrFIDO);

	cSections = m_PH.cSections;
	while (cSections--)
	{
		pIStrFIDO->Read((LPVOID)&fido, sizeof(fido), &cb);
		if (cb != sizeof(fido))
		{
			pIStrFIDO->Release();
			return FALSE;
		}

		// Do a seek from the beginning of the property set.
		LISet32(li, fido.dwOffset);
		pIStream->Seek(liPropSet, STREAM_SEEK_SET, NULL);
		pIStream->Seek(li, STREAM_SEEK_CUR, NULL);

		// Now pIStream is at the type/value pair
		pSect = new CPropertySection;
		pSect->SetFormatID(fido.formatID);
		pSect->ReadFromStream(pIStream, liPropSet);
		m_SectionList.AddTail(pSect);
	}

	pIStrFIDO->Release();
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

⌨️ 快捷键说明

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