📄 ctlpset.cpp
字号:
ASSERT(AfxIsValidString(pszPropName));
ASSERT_POINTER(phBlob, HGLOBAL);
BOOL bSuccess = FALSE;
ULONG cb = 0;
void* pvBlob = NULL;
if (m_bLoading)
{
if (*phBlob != NULL)
{
GlobalFree(*phBlob);
*phBlob = NULL;
}
DWORD dwPropID;
LPVOID pvData;
if (m_psec.GetID(pszPropName, &dwPropID) &&
((pvData = m_psec.Get(dwPropID)) != NULL))
{
// Copy count and blob data
cb = *(ULONG*)pvData;
if (cb > 0)
{
bSuccess = _AfxInitBlob(phBlob, pvData);
}
else
{
bSuccess = (cb == 0);
}
}
if (!bSuccess)
{
// Failed. Use default values.
if (hBlobDefault != NULL)
_AfxCopyBlob(phBlob, hBlobDefault);
bSuccess = TRUE;
}
}
else
{
++m_dwPropID;
pvBlob = NULL;
if (*phBlob != NULL)
pvBlob = GlobalLock(*phBlob);
ULONG lZero = 0;
void* pvBlobSave = (pvBlob != NULL) ? pvBlob : &lZero;
bSuccess = m_psec.SetName(m_dwPropID, pszPropName) &&
m_psec.Set(m_dwPropID, pvBlobSave, VT_BLOB);
if ((*phBlob != NULL) && (pvBlob != NULL))
GlobalUnlock(*phBlob);
}
return bSuccess;
}
BOOL AFXAPI _AfxSaveStreamDataAsBlobProp(LPSTREAM pstm, CPropertySection& psec,
DWORD dwPropID, DWORD dwType)
{
BOOL bSuccess = FALSE;
ULARGE_INTEGER uliStart;
ULARGE_INTEGER uliEnd;
// Note: Stream length must fit in a DWORD.
if (SUCCEEDED(pstm->Seek(_afxLargeZero, STREAM_SEEK_CUR, &uliStart)) &&
SUCCEEDED(pstm->Seek(_afxLargeZero, STREAM_SEEK_END, &uliEnd)) &&
SUCCEEDED(pstm->Seek(*(LARGE_INTEGER*)&uliStart, STREAM_SEEK_SET,
NULL)))
{
DWORD cb = uliEnd.LowPart - uliStart.LowPart;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,
cb + (DWORD)sizeof(cb));
if (hGlobal != NULL)
{
LPBYTE pbData = (LPBYTE)GlobalLock(hGlobal);
if (pbData != NULL)
{
*(DWORD*)pbData = cb;
if (SUCCEEDED(pstm->Read(pbData + (DWORD)sizeof(DWORD), cb,
NULL)))
{
bSuccess = psec.Set(dwPropID, pbData, dwType);
}
GlobalUnlock(hGlobal);
}
GlobalFree(hGlobal);
}
}
return bSuccess;
}
BOOL AFXAPI _AfxInitStreamDataFromBlobProp(LPSTREAM pstm, CProperty* pprop)
{
BOOL bSuccess = FALSE;
ULONG cb;
BYTE* pbData = (BYTE*)(pprop->Get(&cb));
if (pbData != NULL)
{
// Put the data into the stream, then seek back to start of data.
LARGE_INTEGER liOffset;
liOffset.LowPart = -(LONG)cb;
liOffset.HighPart = -1;
if (SUCCEEDED(pstm->Write(pbData + sizeof(ULONG), cb, NULL)) &&
SUCCEEDED(pstm->Seek(liOffset, STREAM_SEEK_CUR, NULL)))
{
bSuccess = TRUE;
}
}
return bSuccess;
}
AFX_STATIC_DATA const FONTDESC _afxFontDescHelv =
{ sizeof(FONTDESC), OLESTR("Helv"), FONTSIZE(12), FW_NORMAL,
DEFAULT_CHARSET, FALSE, FALSE, FALSE };
LPFONT AFXAPI _AfxCreateFontFromStream(LPSTREAM pstm)
{
BOOL bSuccess = FALSE;
LPFONT pFont = NULL;
LPPERSISTSTREAM pPersStm = NULL;
CLSID clsid;
if (SUCCEEDED(pstm->Read(&clsid, sizeof(CLSID), NULL)))
{
HRESULT hr;
if (IsEqualCLSID(clsid, CLSID_StdFont) ||
IsEqualCLSID(clsid, _afx_CLSID_StdFont_V1))
{
// We know this kind of font; create it using the API.
hr = ::OleCreateFontIndirect((LPFONTDESC)&_afxFontDescHelv, IID_IFont,
(LPVOID*)&pFont);
}
else
{
// Some other implementation of IFont.
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IFont,
(LPVOID*)&pFont);
}
if (SUCCEEDED(hr))
{
// Successfully created font, now get its IPersistStream interface.
ASSERT_POINTER(pFont, IFont);
if (SUCCEEDED(pFont->QueryInterface(IID_IPersistStream,
(LPVOID*)&pPersStm)))
{
ASSERT_POINTER(pPersStm, IPersistStream);
}
}
if (pPersStm != NULL)
{
// Load the font.
ASSERT_POINTER(pFont, IFont);
bSuccess = SUCCEEDED(pPersStm->Load(pstm));
pPersStm->Release();
}
}
// If we failed for any reason, clean up the font.
if (!bSuccess && pFont != NULL)
{
pFont->Release();
pFont = NULL;
}
return pFont;
}
BOOL AFXAPI _AfxLoadObjectFromStreamedPropset(LPUNKNOWN lpUnknown, LPSTREAM lpStream)
{
ASSERT_POINTER(lpUnknown, IUnknown);
ASSERT_POINTER(lpStream, IStream);
BOOL bSuccess = FALSE;
LPDATAOBJECT pDataObj = NULL;
if (SUCCEEDED(lpUnknown->QueryInterface(IID_IDataObject,
(LPVOID*)&pDataObj)))
{
ASSERT_POINTER(pDataObj, IDataObject);
// Set the persistent propset format on the object.
FORMATETC formatEtc;
STGMEDIUM stgMedium;
formatEtc.cfFormat = _AfxGetClipboardFormatPersistPropset();
formatEtc.ptd = NULL;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = -1;
formatEtc.tymed = TYMED_ISTREAM;
stgMedium.tymed = TYMED_ISTREAM;
stgMedium.pstm = lpStream;
stgMedium.pUnkForRelease = NULL;
bSuccess = SUCCEEDED(pDataObj->SetData(&formatEtc, &stgMedium, FALSE));
pDataObj->Release();
}
return bSuccess;
}
BOOL AFXAPI _AfxGetClassIDFromStreamedPropset(LPCLSID lpClsid, LPSTREAM lpStream)
{
BOOL bSuccess = FALSE;
ULARGE_INTEGER uliSave;
LARGE_INTEGER liClsidOffset;
LISet32(liClsidOffset, 8);
if (SUCCEEDED(lpStream->Seek(_afxLargeZero, STREAM_SEEK_CUR, &uliSave)))
{
if (SUCCEEDED(lpStream->Seek(liClsidOffset, STREAM_SEEK_CUR, NULL)) &&
SUCCEEDED(lpStream->Read(lpClsid, sizeof(CLSID), NULL)))
{
bSuccess = TRUE;
}
lpStream->Seek(*(LARGE_INTEGER*)&uliSave, STREAM_SEEK_SET, NULL);
}
return bSuccess;
}
LPUNKNOWN AFXAPI _AfxCreateObjectFromStreamedPropset(LPSTREAM lpStream, REFGUID iid)
{
LPUNKNOWN pUnk = NULL;
CLSID clsid;
if (_AfxGetClassIDFromStreamedPropset(&clsid, lpStream))
{
// Special case: we know how to create font objects
if (IsEqualCLSID(clsid, CLSID_StdFont) ||
IsEqualCLSID(clsid, _afx_CLSID_StdFont_V1))
{
if (FAILED(::OleCreateFontIndirect((LPFONTDESC)&_afxFontDescHelv, iid,
(LPVOID*)&pUnk)))
{
pUnk = NULL;
}
}
// Special case: we know how to create picture objects
else if (IsEqualCLSID(clsid, CLSID_StdPicture) ||
IsEqualCLSID(clsid, _afx_CLSID_StdPicture_V1))
{
if (FAILED(::OleCreatePictureIndirect(NULL, iid, FALSE,
(LPVOID*)&pUnk)))
{
pUnk = NULL;
}
}
// General case: create the object
else if (FAILED(CoCreateInstance(clsid, NULL,
CLSCTX_INPROC_SERVER, iid, (LPVOID*)&pUnk)))
{
pUnk = NULL;
}
if (pUnk != NULL)
{
if (!_AfxLoadObjectFromStreamedPropset(pUnk, lpStream))
{
RELEASE(pUnk);
pUnk = NULL;
}
}
}
return pUnk;
}
LPSTREAM AFXAPI _AfxLoadStreamFromPropset(CPropertySection& psec, LPCTSTR pszPropName,
DWORD& vtType)
{
ASSERT(AfxIsValidString(pszPropName));
vtType = VT_EMPTY;
DWORD dwPropID;
CProperty* pprop = NULL;
LPSTREAM pstm = NULL;
if (psec.GetID(pszPropName, &dwPropID) &&
((pprop = psec.GetProperty(dwPropID)) != NULL))
{
vtType = pprop->GetType();
if ((vtType == VT_BLOB) || (vtType == VT_BLOB_PROPSET))
{
pstm = _AfxCreateMemoryStream();
if (pstm != NULL)
{
if (!_AfxInitStreamDataFromBlobProp(pstm, pprop))
{
pstm->Release();
pstm = NULL;
}
}
}
}
return pstm;
}
BOOL AFXAPI _AfxSaveObjectInPropset(LPUNKNOWN pUnk, CPropertySection& psec,
DWORD dwPropID)
{
if (pUnk == NULL)
return FALSE;
ASSERT_POINTER(pUnk, IUnknown);
BOOL bSuccess = FALSE;
LPDATAOBJECT pDataObj;
if (SUCCEEDED(pUnk->QueryInterface(IID_IDataObject,
(LPVOID*)&pDataObj)))
{
// Get the persistent propset format from object.
FORMATETC formatEtc;
STGMEDIUM stgMedium;
formatEtc.cfFormat = _AfxGetClipboardFormatPersistPropset();
formatEtc.ptd = NULL;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = -1;
formatEtc.tymed = TYMED_ISTREAM;
stgMedium.tymed = TYMED_NULL;
stgMedium.pUnkForRelease = NULL;
if (SUCCEEDED(pDataObj->GetData(&formatEtc, &stgMedium)))
{
if (stgMedium.tymed == TYMED_ISTREAM)
{
LPSTREAM pstm = stgMedium.pstm;
// Seek to start of stream.
if (SUCCEEDED(pstm->Seek(_afxLargeZero, STREAM_SEEK_SET, NULL)))
{
// Create a "blobbed" propset from the stream
bSuccess = _AfxSaveStreamDataAsBlobProp(stgMedium.pstm,
psec, dwPropID, VT_BLOB_PROPSET);
}
}
// Cleanup
ReleaseStgMedium(&stgMedium);
}
pDataObj->Release();
}
LPPERSISTSTREAM pPersStm = NULL;
if ((!bSuccess) &&
SUCCEEDED(pUnk->QueryInterface(IID_IPersistStream,
(LPVOID*)&pPersStm)))
{
// Get the object to save itself into a stream, then store that
// streamed data as a blob.
ASSERT_POINTER(pPersStm, IPersistStream);
LPSTREAM pstm = _AfxCreateMemoryStream();
if (pstm != NULL)
{
if (SUCCEEDED(::OleSaveToStream(pPersStm, pstm)) &&
SUCCEEDED(pstm->Seek(_afxLargeZero, STREAM_SEEK_SET, NULL)))
{
bSuccess = _AfxSaveStreamDataAsBlobProp(pstm, psec,
dwPropID, VT_BLOB);
}
pstm->Release();
}
pPersStm->Release();
}
return bSuccess;
}
BOOL CPropsetPropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
{
ASSERT(AfxIsValidString(pszPropName));
ASSERT_POINTER(ppUnk, LPUNKNOWN);
ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
BOOL bSuccess = FALSE;
if (m_bLoading)
{
RELEASE(*ppUnk);
*ppUnk = NULL;
DWORD vtType;
LPSTREAM pstm = _AfxLoadStreamFromPropset(m_psec, pszPropName, vtType);
if (pstm != NULL)
{
CLSID clsid;
switch(vtType)
{
case VT_BLOB:
if (_AfxPeekAtClassIDInStream(pstm, &clsid))
{
if (IsEqualCLSID(clsid, CLSID_StdPicture) ||
IsEqualCLSID(clsid, _afx_CLSID_StdPicture_V1))
{
// Special case: load the picture directly.
bSuccess = SUCCEEDED(::ReadClassStm(pstm, &clsid)) &&
SUCCEEDED(::OleLoadPicture(pstm, 0, FALSE, iid,
(LPVOID*)ppUnk));
}
else
{
// Load the object.
bSuccess = SUCCEEDED(::OleLoadFromStream(pstm, iid,
(LPVOID*)ppUnk));
}
}
break;
case VT_BLOB_PROPSET:
*ppUnk = _AfxCreateObjectFromStreamedPropset(pstm, iid);
break;
default:
break;
}
pstm->Release();
}
if (!bSuccess && (pUnkDefault != NULL))
{
bSuccess = SUCCEEDED(pUnkDefault->QueryInterface(iid,
(LPVOID*)ppUnk));
}
}
else
{
if ((*ppUnk == NULL) ||
_AfxIsSameUnknownObject(iid, *ppUnk, pUnkDefault))
{
bSuccess = TRUE;
}
else
{
++m_dwPropID;
bSuccess = m_psec.SetName(m_dwPropID, pszPropName) &&
_AfxSaveObjectInPropset(*ppUnk, m_psec, m_dwPropID);
}
}
return bSuccess;
}
BOOL CPropsetPropExchange::ExchangeFontProp(LPCTSTR pszPropName,
CFontHolder& font, const FONTDESC* pFontDesc,
LPFONTDISP pFontDispAmbient)
{
ASSERT(AfxIsValidString(pszPropName));
ASSERT_POINTER(&font, CFontHolder);
ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
BOOL bSuccess = FALSE;
if (m_bLoading)
{
DWORD vtType;
LPSTREAM pstm = _AfxLoadStreamFromPropset(m_psec, pszPropName, vtType);
if (pstm != NULL)
{
LPFONT pFont;
switch(vtType)
{
case VT_BLOB:
pFont = _AfxCreateFontFromStream(pstm);
break;
case VT_BLOB_PROPSET:
pFont = (LPFONT)_AfxCreateObjectFromStreamedPropset(pstm,
IID_IFont);
break;
default:
pFont = NULL;
}
if (pFont != NULL)
{
font.SetFont(pFont);
bSuccess = TRUE;
}
pstm->Release();
}
if (!bSuccess)
{
// Initialize font to its default state
font.InitializeFont(pFontDesc, pFontDispAmbient);
}
}
else
{
if ((font.m_pFont == NULL) ||
_AfxIsSameFont(font, pFontDesc, pFontDispAmbient))
{
bSuccess = TRUE;
}
else
{
++m_dwPropID;
bSuccess = m_psec.SetName(m_dwPropID, pszPropName) &&
_AfxSaveObjectInPropset(font.m_pFont, m_psec, m_dwPropID);
}
}
return bSuccess;
}
/////////////////////////////////////////////////////////////////////////////
// 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 + -