mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1166 lines
28 KiB
1166 lines
28 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 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
|
|
|
|
#ifdef _DEBUG
|
|
#define ASSERT_BUFFER_VALID(p, cb, bWrite) \
|
|
ASSERT(AfxIsValidAddress(p, cb, bWrite))
|
|
#else
|
|
#define ASSERT_BUFFER_VALID(p, cb, bWrite)
|
|
#endif
|
|
|
|
// Old class ID for picture type
|
|
static const CLSID CLSID_StdPicture_V1 =
|
|
{ 0xfb8f0824,0x0164,0x101b, { 0x84,0xed,0x08,0x00,0x2b,0x2e,0xc7,0x13 } };
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _AfxGetArchiveStream
|
|
|
|
LPSTREAM AFXAPI _AfxGetArchiveStream(CArchive& ar, CArchiveStream& stm)
|
|
{
|
|
// Obtain direct access to the archive's LPSTREAM.
|
|
ar.Flush();
|
|
CFile* pFile = ar.GetFile();
|
|
ASSERT(pFile != NULL);
|
|
LPSTREAM pstm;
|
|
if (pFile->IsKindOf(RUNTIME_CLASS(COleStreamFile)))
|
|
{
|
|
pstm = ((COleStreamFile*)pFile)->m_lpStream;
|
|
ASSERT(pstm != NULL);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(stm.m_pArchive == NULL || stm.m_pArchive == &ar);
|
|
stm.m_pArchive = &ar;
|
|
pstm = &stm;
|
|
}
|
|
return pstm;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _AfxInitBlob
|
|
|
|
BOOL AFXAPI _AfxInitBlob(HGLOBAL* phDst, void* pvSrc)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
ULONG cb;
|
|
if ((cb = *(long*)pvSrc) > 0)
|
|
{
|
|
ASSERT_BUFFER_VALID(pvSrc, sizeof(cb) + cb, TRUE);
|
|
*phDst = GlobalAlloc(GMEM_MOVEABLE, sizeof(cb) + cb);
|
|
if (*phDst != NULL)
|
|
{
|
|
void* pvDst = GlobalLock(*phDst);
|
|
ASSERT(pvDst != NULL);
|
|
memcpy(pvDst, pvSrc, sizeof(cb) + cb);
|
|
bResult = TRUE;
|
|
GlobalUnlock(*phDst);
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _AfxCopyBlob
|
|
|
|
BOOL AFXAPI _AfxCopyBlob(HGLOBAL* phDst, HGLOBAL hSrc)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
void* pvSrc = GlobalLock(hSrc);
|
|
if (pvSrc != NULL)
|
|
{
|
|
bResult = _AfxInitBlob(phDst, pvSrc);
|
|
GlobalUnlock(hSrc);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// _AfxCopyPropValue
|
|
|
|
BOOL AFXAPI _AfxCopyPropValue(VARTYPE vtProp, void* pvDest, const void * pvSrc)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pvDest, 1));
|
|
|
|
if (pvSrc != NULL)
|
|
{
|
|
ASSERT(AfxIsValidAddress(pvSrc, 1, FALSE));
|
|
|
|
switch (vtProp)
|
|
{
|
|
case VT_I2:
|
|
*(short*)pvDest = *(short*)pvSrc;
|
|
break;
|
|
case VT_I4:
|
|
*(long*)pvDest = *(long*)pvSrc;
|
|
break;
|
|
case VT_BOOL:
|
|
*(BOOL*)pvDest = *(BOOL*)pvSrc;
|
|
break;
|
|
case VT_BSTR:
|
|
*(CString*)pvDest = *(CString*)pvSrc;
|
|
break;
|
|
case VT_LPSTR:
|
|
*(CString*)pvDest = (LPCTSTR)pvSrc;
|
|
break;
|
|
case VT_CY:
|
|
*(CY*)pvDest = *(CY*)pvSrc;
|
|
break;
|
|
case VT_R4:
|
|
*(_AFX_FLOAT*)pvDest = *(_AFX_FLOAT*)pvSrc;
|
|
break;
|
|
case VT_R8:
|
|
*(_AFX_DOUBLE*)pvDest = *(_AFX_DOUBLE*)pvSrc;
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
return pvSrc != NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleControl::ExchangeExtent
|
|
|
|
BOOL COleControl::ExchangeExtent(CPropExchange* pPX)
|
|
{
|
|
// Save extent
|
|
SIZEL szl;
|
|
szl.cx = m_cxExtent;
|
|
szl.cy = m_cyExtent;
|
|
|
|
if (PX_Long(pPX, _T("_ExtentX"), szl.cx) &&
|
|
PX_Long(pPX, _T("_ExtentY"), szl.cy))
|
|
{
|
|
if ((pPX->IsLoading()) &&
|
|
((m_cxExtent != szl.cx) || (m_cyExtent != szl.cy)))
|
|
{
|
|
m_xOleObject.SetExtent(DVASPECT_CONTENT, &szl);
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Serialization for version number
|
|
|
|
DWORD COleControl::SerializeVersion(CArchive& ar, DWORD dwVersionDefault,
|
|
BOOL bConvert)
|
|
{
|
|
DWORD dwVersion;
|
|
|
|
if (ar.IsLoading())
|
|
{
|
|
ar >> m_dwVersionLoaded;
|
|
dwVersion = m_dwVersionLoaded;
|
|
}
|
|
else
|
|
{
|
|
dwVersion = bConvert ? dwVersionDefault : m_dwVersionLoaded;
|
|
ar << dwVersion;
|
|
}
|
|
|
|
return dwVersion;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialization for version number
|
|
|
|
void COleControl::ResetVersion(DWORD dwVersionDefault)
|
|
{
|
|
m_dwVersionLoaded = dwVersionDefault;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Serialization for extent
|
|
|
|
void COleControl::SerializeExtent(CArchive& ar)
|
|
{
|
|
if (ar.IsLoading())
|
|
{
|
|
SIZEL szl;
|
|
ar >> szl.cx;
|
|
ar >> szl.cy;
|
|
if ((m_cxExtent != szl.cx) || (m_cyExtent != szl.cy))
|
|
m_xOleObject.SetExtent(DVASPECT_CONTENT, &szl);
|
|
}
|
|
else
|
|
{
|
|
ar << m_cxExtent;
|
|
ar << m_cyExtent;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPropExchange member functions
|
|
|
|
BOOL CPropExchange::ExchangeVersion(DWORD& dwVersionLoaded,
|
|
DWORD dwVersionDefault, BOOL bConvert)
|
|
{
|
|
BOOL bResult;
|
|
if (m_bLoading)
|
|
{
|
|
bResult = PX_ULong(this, _T("_Version"), m_dwVersion,
|
|
dwVersionDefault);
|
|
dwVersionLoaded = m_dwVersion;
|
|
}
|
|
else
|
|
{
|
|
m_dwVersion = bConvert ? dwVersionDefault : dwVersionLoaded;
|
|
bResult = PX_ULong(this, _T("_Version"), m_dwVersion);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CArchivePropExchange member functions
|
|
|
|
CArchivePropExchange::CArchivePropExchange(CArchive& ar) :
|
|
m_ar(ar)
|
|
{
|
|
ASSERT_POINTER(&ar, CArchive);
|
|
m_bLoading = m_ar.IsLoading();
|
|
}
|
|
|
|
BOOL CArchivePropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
|
void* pvProp, const void* pvDefault)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
UNUSED(pvDefault); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
|
|
ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));
|
|
|
|
if (m_bLoading)
|
|
{
|
|
switch (vtProp)
|
|
{
|
|
case VT_I2:
|
|
m_ar >> *(WORD*)pvProp;
|
|
break;
|
|
case VT_I4:
|
|
m_ar >> *(long*)pvProp;
|
|
break;
|
|
case VT_BOOL:
|
|
*(BOOL*)pvProp = 0;
|
|
m_ar >> *(BYTE*)pvProp;
|
|
break;
|
|
case VT_LPSTR:
|
|
case VT_BSTR:
|
|
m_ar >> *(CString*)pvProp;
|
|
break;
|
|
case VT_CY:
|
|
m_ar >> ((CY*)pvProp)->Lo;
|
|
m_ar >> ((CY*)pvProp)->Hi;
|
|
break;
|
|
case VT_R4:
|
|
m_ar >> *(float*)pvProp;
|
|
break;
|
|
case VT_R8:
|
|
m_ar >> *(double*)pvProp;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (vtProp)
|
|
{
|
|
case VT_I2:
|
|
m_ar << *(WORD*)pvProp;
|
|
break;
|
|
case VT_I4:
|
|
m_ar << *(long*)pvProp;
|
|
break;
|
|
case VT_BOOL:
|
|
m_ar << *(BYTE*)pvProp;
|
|
break;
|
|
case VT_LPSTR:
|
|
case VT_BSTR:
|
|
m_ar << *(CString*)pvProp;
|
|
break;
|
|
case VT_CY:
|
|
m_ar << ((CY*)pvProp)->Lo;
|
|
m_ar << ((CY*)pvProp)->Hi;
|
|
break;
|
|
case VT_R4:
|
|
m_ar << *(float*)pvProp;
|
|
break;
|
|
case VT_R8:
|
|
m_ar << *(double*)pvProp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CArchivePropExchange::ExchangeBlobProp(LPCTSTR pszPropName,
|
|
HGLOBAL* phBlob, HGLOBAL /*hBlobDefault*/)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(phBlob, HGLOBAL);
|
|
|
|
DWORD cb;
|
|
|
|
if (m_bLoading)
|
|
{
|
|
// free previous memory block
|
|
if (*phBlob != NULL)
|
|
{
|
|
GlobalFree(*phBlob);
|
|
*phBlob = NULL;
|
|
}
|
|
|
|
// read new size
|
|
m_ar >> cb;
|
|
|
|
// allocate and fill new memory block
|
|
*phBlob = GlobalAlloc(GMEM_MOVEABLE, sizeof(cb)+cb);
|
|
if (*phBlob != NULL)
|
|
{
|
|
void* pvBlob = GlobalLock(*phBlob);
|
|
ASSERT(pvBlob != NULL);
|
|
*(long*)pvBlob = cb;
|
|
if (m_ar.Read((BYTE*)pvBlob+sizeof(cb), cb) != cb)
|
|
AfxThrowArchiveException(CArchiveException::endOfFile);
|
|
GlobalUnlock(*phBlob);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (*phBlob != NULL)
|
|
{
|
|
void* pvBlob = GlobalLock(*phBlob);
|
|
ASSERT(pvBlob != NULL);
|
|
cb = *(long*)pvBlob;
|
|
ASSERT_BUFFER_VALID(pvBlob, sizeof(cb)+cb, FALSE);
|
|
m_ar.Write(pvBlob, sizeof(cb)+cb);
|
|
GlobalUnlock(*phBlob);
|
|
}
|
|
else
|
|
m_ar << (DWORD)0;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL AFXAPI _AfxPeekAtClassIDInStream(LPSTREAM pstm, LPCLSID lpClassID)
|
|
{
|
|
// Read the class ID, then restore the seek pointer.
|
|
LARGE_INTEGER li;
|
|
li.LowPart = (DWORD)(-(long)sizeof(CLSID));
|
|
li.HighPart = -1;
|
|
|
|
return (SUCCEEDED(ReadClassStm(pstm, lpClassID)) &&
|
|
SUCCEEDED(pstm->Seek(li, STREAM_SEEK_CUR, NULL)));
|
|
}
|
|
|
|
BOOL AFXAPI _AfxIsSameUnknownObject(REFIID iid, LPUNKNOWN pUnk1, LPUNKNOWN pUnk2)
|
|
{
|
|
if (pUnk1 == pUnk2)
|
|
return TRUE;
|
|
|
|
if (pUnk1 == NULL || pUnk2 == NULL)
|
|
return FALSE;
|
|
|
|
LPUNKNOWN pI1 = NULL;
|
|
LPUNKNOWN pI2 = NULL;
|
|
BOOL bResult = FALSE;
|
|
if (SUCCEEDED(pUnk1->QueryInterface(iid, (void**)&pI1)))
|
|
{
|
|
ASSERT_POINTER(pI1, IUnknown);
|
|
if (SUCCEEDED(pUnk2->QueryInterface(iid, (void**)&pI2)))
|
|
{
|
|
ASSERT_POINTER(pI2, IUnknown);
|
|
bResult = (pI1 == pI2);
|
|
pI2->Release();
|
|
}
|
|
pI1->Release();
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CArchivePropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
|
|
LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(ppUnk, LPUNKNOWN);
|
|
ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
|
|
|
|
BOOL bResult = FALSE;
|
|
CArchiveStream stm(&m_ar);
|
|
|
|
if (m_bLoading)
|
|
{
|
|
RELEASE(*ppUnk);
|
|
*ppUnk = NULL;
|
|
|
|
BYTE bFlag;
|
|
m_ar >> bFlag;
|
|
if (bFlag != 0xFF)
|
|
{
|
|
// read the CLSID
|
|
CLSID clsid;
|
|
m_ar >> clsid.Data1;
|
|
m_ar >> clsid.Data2;
|
|
m_ar >> clsid.Data3;
|
|
m_ar.Read(&clsid.Data4[0], sizeof clsid.Data4);
|
|
|
|
// check for GUID_NULL first and skip if found
|
|
if (IsEqualCLSID(clsid, GUID_NULL))
|
|
bResult = TRUE;
|
|
else
|
|
{
|
|
// otherwise will need a stream
|
|
LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
|
|
if (IsEqualCLSID(clsid, CLSID_StdPicture) ||
|
|
IsEqualCLSID(clsid, CLSID_StdPicture_V1))
|
|
{
|
|
// special case for pictures
|
|
bResult = SUCCEEDED(::OleLoadPicture(pstm, 0, FALSE, iid,
|
|
(void**)ppUnk));
|
|
}
|
|
else
|
|
{
|
|
// otherwise, seek back to the CLSID
|
|
LARGE_INTEGER li;
|
|
li.LowPart = (DWORD)(-(long)sizeof(CLSID));
|
|
li.HighPart = -1;
|
|
VERIFY(SUCCEEDED(pstm->Seek(li, STREAM_SEEK_CUR, NULL)));
|
|
|
|
// and load the object normally
|
|
|
|
CLSID clsid;
|
|
if (SUCCEEDED(::ReadClassStm(pstm, &clsid)) &&
|
|
(SUCCEEDED(::CoCreateInstance(clsid, NULL,
|
|
CLSCTX_SERVER | CLSCTX_REMOTE_SERVER,
|
|
iid, (void**)ppUnk)) ||
|
|
SUCCEEDED(::CoCreateInstance(clsid, NULL,
|
|
CLSCTX_SERVER & ~CLSCTX_REMOTE_SERVER,
|
|
iid, (void**)ppUnk))))
|
|
{
|
|
LPPERSISTSTREAM pps = NULL;
|
|
if (SUCCEEDED((*ppUnk)->QueryInterface(
|
|
IID_IPersistStream, (void**)&pps)) ||
|
|
SUCCEEDED((*ppUnk)->QueryInterface(
|
|
IID_IPersistStreamInit, (void**)&pps)))
|
|
{
|
|
ASSERT_POINTER(pps, IPersistStream);
|
|
bResult = SUCCEEDED(pps->Load(pstm));
|
|
pps->Release();
|
|
}
|
|
|
|
if (!bResult)
|
|
{
|
|
(*ppUnk)->Release();
|
|
*ppUnk = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Use default value.
|
|
bResult = pUnkDefault == NULL ||
|
|
SUCCEEDED(pUnkDefault->QueryInterface(iid, (LPVOID*)ppUnk));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ASSERT_NULL_OR_POINTER(*ppUnk, IUnknown);
|
|
|
|
// Check if *ppUnk and pUnkDefault are the same thing. If so, don't
|
|
// bother saving the object; just write a special flag instead.
|
|
|
|
if (_AfxIsSameUnknownObject(iid, *ppUnk, pUnkDefault))
|
|
{
|
|
m_ar << (BYTE)0xFF;
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_ar << (BYTE)0x00;
|
|
if (*ppUnk != NULL)
|
|
{
|
|
LPPERSISTSTREAM pps = NULL;
|
|
if (SUCCEEDED((*ppUnk)->QueryInterface(
|
|
IID_IPersistStream, (void**)&pps)) ||
|
|
SUCCEEDED((*ppUnk)->QueryInterface(
|
|
IID_IPersistStreamInit, (void**)&pps)))
|
|
{
|
|
ASSERT_POINTER(pps, IPersistStream);
|
|
LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
|
|
bResult = SUCCEEDED(::OleSaveToStream(pps, pstm));
|
|
pps->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If no object, write null class ID.
|
|
m_ar.Write(&GUID_NULL, sizeof(GUID));
|
|
}
|
|
}
|
|
}
|
|
|
|
// throw exception in case of unthrown errors
|
|
if (!bResult)
|
|
AfxThrowArchiveException(CArchiveException::generic);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CArchivePropExchange::ExchangeFontProp(LPCTSTR pszPropName,
|
|
CFontHolder& font, const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&font, CFontHolder);
|
|
ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
|
|
ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
|
|
|
|
BOOL bResult = FALSE;
|
|
CArchiveStream stm(&m_ar);
|
|
LPFONT pFont;
|
|
|
|
if (m_bLoading)
|
|
{
|
|
BYTE bFlag;
|
|
m_ar >> bFlag;
|
|
if (bFlag != 0xFF)
|
|
{
|
|
LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
|
|
pFont = _AfxCreateFontFromStream(pstm);
|
|
if (pFont != NULL)
|
|
{
|
|
font.SetFont(pFont);
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
if (!bResult)
|
|
{
|
|
font.InitializeFont(pFontDesc, pFontDispAmbient);
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFont = font.m_pFont;
|
|
if (pFont != NULL)
|
|
{
|
|
// If same as ambient font (or error), write 0xFF for the flag
|
|
if (!_AfxIsSameFont(font, pFontDesc, pFontDispAmbient))
|
|
{
|
|
LPPERSISTSTREAM pps = NULL;
|
|
if (SUCCEEDED(pFont->QueryInterface(IID_IPersistStream,
|
|
(LPVOID*)&pps)))
|
|
{
|
|
ASSERT_POINTER(pps, IPersistStream);
|
|
m_ar << (BYTE)0x00;
|
|
LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
|
|
bResult = SUCCEEDED(::OleSaveToStream(pps, pstm));
|
|
pps->Release();
|
|
if (!bResult)
|
|
AfxThrowArchiveException(CArchiveException::generic);
|
|
}
|
|
}
|
|
}
|
|
if (!bResult)
|
|
{
|
|
m_ar << (BYTE)0xFF;
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CResetPropExchange member functions
|
|
|
|
CResetPropExchange::CResetPropExchange()
|
|
{
|
|
m_bLoading = TRUE;
|
|
}
|
|
|
|
BOOL CResetPropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
|
void* pvProp, const void* pvDefault)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
|
|
ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));
|
|
|
|
return _AfxCopyPropValue(vtProp, pvProp, pvDefault);
|
|
}
|
|
|
|
BOOL CResetPropExchange::ExchangeBlobProp(LPCTSTR pszPropName,
|
|
HGLOBAL* phBlob, HGLOBAL hBlobDefault)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(phBlob, HGLOBAL);
|
|
|
|
// free the previous memory block
|
|
if (*phBlob != NULL)
|
|
{
|
|
GlobalFree(*phBlob);
|
|
*phBlob = NULL;
|
|
}
|
|
|
|
// copy the memory block
|
|
BOOL bResult = TRUE;
|
|
if (hBlobDefault != NULL)
|
|
bResult = _AfxCopyBlob(phBlob, hBlobDefault);
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CResetPropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
|
|
LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(ppUnk, LPUNKNOWN);
|
|
ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
|
|
|
|
RELEASE(*ppUnk);
|
|
|
|
BOOL bResult = TRUE;
|
|
if (pUnkDefault != NULL)
|
|
{
|
|
bResult = SUCCEEDED(pUnkDefault->QueryInterface(iid,
|
|
(LPVOID*)ppUnk));
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CResetPropExchange::ExchangeFontProp(
|
|
LPCTSTR pszPropName, CFontHolder& font, const FONTDESC* pFontDesc,
|
|
LPFONTDISP pFontDispAmbient)
|
|
{
|
|
UNUSED(pszPropName); // unused in release builds
|
|
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&font, CFontHolder);
|
|
ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
|
|
ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
|
|
|
|
font.InitializeFont(pFontDesc, pFontDispAmbient);
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAsyncPropExchange member functions
|
|
|
|
CAsyncPropExchange::CAsyncPropExchange(DWORD dwVersion)
|
|
{
|
|
m_bAsync = TRUE;
|
|
m_bLoading = TRUE;
|
|
m_dwVersion = dwVersion;
|
|
}
|
|
|
|
BOOL CAsyncPropExchange::ExchangeVersion(DWORD& dwVersionLoaded,
|
|
DWORD dwVersionDefault, BOOL bConvert)
|
|
{
|
|
if (m_bLoading)
|
|
{
|
|
dwVersionLoaded = m_dwVersion;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return m_dwVersion == (bConvert ? dwVersionDefault : dwVersionLoaded);
|
|
}
|
|
}
|
|
|
|
BOOL CAsyncPropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
|
void* pvProp, const void* pvDefault)
|
|
{
|
|
// Should never be called
|
|
UNUSED_ALWAYS(pszPropName);
|
|
UNUSED_ALWAYS(vtProp);
|
|
UNUSED_ALWAYS(pvProp);
|
|
UNUSED_ALWAYS(pvDefault);
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CAsyncPropExchange::ExchangeBlobProp(LPCTSTR pszPropName, HGLOBAL* phBlob,
|
|
HGLOBAL hBlobDefault)
|
|
{
|
|
// Should never be called
|
|
UNUSED_ALWAYS(pszPropName);
|
|
UNUSED_ALWAYS(phBlob);
|
|
UNUSED_ALWAYS(hBlobDefault);
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CAsyncPropExchange::ExchangeFontProp(LPCTSTR pszPropName,
|
|
CFontHolder& font, const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
|
|
{
|
|
// Should never be called
|
|
UNUSED_ALWAYS(pszPropName);
|
|
UNUSED_ALWAYS(font);
|
|
UNUSED_ALWAYS(pFontDesc);
|
|
UNUSED_ALWAYS(pFontDispAmbient);
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CAsyncPropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
|
|
LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
|
|
{
|
|
// Should never be called
|
|
UNUSED_ALWAYS(pszPropName);
|
|
UNUSED_ALWAYS(ppUnk);
|
|
UNUSED_ALWAYS(iid);
|
|
UNUSED_ALWAYS(pUnkDefault);
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// PX_ functions
|
|
|
|
BOOL AFX_CDECL PX_Short(CPropExchange* pPX, LPCTSTR pszPropName, short& sValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&sValue, short);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I2, &sValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Short(CPropExchange* pPX, LPCTSTR pszPropName, short& sValue,
|
|
short sDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&sValue, short);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I2, &sValue, &sDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_UShort(CPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&usValue, USHORT);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I2, &usValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_UShort(CPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue,
|
|
USHORT usDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&usValue, USHORT);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I2, &usValue, &usDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Long(CPropExchange* pPX, LPCTSTR pszPropName, long& lValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&lValue, long);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &lValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Long(CPropExchange* pPX, LPCTSTR pszPropName, long& lValue,
|
|
long lDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&lValue, long);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &lValue, &lDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_ULong(CPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&ulValue, ULONG);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_ULong(CPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue,
|
|
ULONG ulDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&ulValue, ULONG);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue, &ulDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Color(CPropExchange* pPX, LPCTSTR pszPropName, OLE_COLOR& clrValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&clrValue, OLE_COLOR);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &clrValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Color(CPropExchange* pPX, LPCTSTR pszPropName, OLE_COLOR& clrValue,
|
|
OLE_COLOR clrDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&clrValue, OLE_COLOR);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_I4, &clrValue, &clrDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Bool(CPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&bValue, BOOL);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Bool(CPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue,
|
|
BOOL bDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&bValue, BOOL);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue, &bDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&strValue, CString);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_BSTR, &strValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue,
|
|
const CString& strDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&strValue, CString);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_BSTR, &strValue, &strDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue,
|
|
LPCTSTR lpszDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&strValue, CString);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_LPSTR, &strValue, lpszDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Currency(CPropExchange* pPX, LPCTSTR pszPropName, CY& cyValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&cyValue, CY);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_CY, &cyValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Currency(CPropExchange* pPX, LPCTSTR pszPropName, CY& cyValue,
|
|
CY cyDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&cyValue, CY);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_CY, &cyValue, &cyDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Float(CPropExchange* pPX, LPCTSTR pszPropName, float& floatValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&floatValue, float);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Float(CPropExchange* pPX, LPCTSTR pszPropName, float& floatValue,
|
|
float floatDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&floatValue, float);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue, &floatDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Double(CPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&doubleValue, double);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Double(CPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue,
|
|
double doubleDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&doubleValue, double);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue, &doubleDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Blob(CPropExchange* pPX, LPCTSTR pszPropName, HGLOBAL& hBlob,
|
|
HGLOBAL hBlobDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&hBlob, HGLOBAL);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeBlobProp(pszPropName, &hBlob, hBlobDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Font(CPropExchange* pPX, LPCTSTR pszPropName, CFontHolder& font,
|
|
const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&font, CFontHolder);
|
|
ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
|
|
ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangeFontProp(pszPropName, font, pFontDesc,
|
|
pFontDispAmbient);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_IUnknown(CPropExchange* pPX, LPCTSTR pszPropName, LPUNKNOWN& pUnk,
|
|
REFIID iid, LPUNKNOWN pUnkDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&pUnk, LPUNKNOWN);
|
|
ASSERT_NULL_OR_POINTER(pUnk, IUnknown);
|
|
ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
return pPX->ExchangePersistentProp(pszPropName, &pUnk, iid, pUnkDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Picture(CPropExchange* pPX, LPCTSTR pszPropName, CPictureHolder& pict)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&pict, CPictureHolder);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
LPUNKNOWN& pUnk = (LPUNKNOWN&)pict.m_pPict;
|
|
return PX_IUnknown(pPX, pszPropName, pUnk, IID_IPicture);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_Picture(CPropExchange* pPX, LPCTSTR pszPropName, CPictureHolder& pict,
|
|
CPictureHolder& pictDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
ASSERT_POINTER(&pict, CPictureHolder);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
LPUNKNOWN& pUnk = (LPUNKNOWN&)pict.m_pPict;
|
|
return PX_IUnknown(pPX, pszPropName, pUnk, IID_IPicture,
|
|
pictDefault.m_pPict);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_VBXFontConvert(CPropExchange* pPX, CFontHolder& font)
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT_POINTER(&font, CFontHolder);
|
|
|
|
if (pPX->IsAsynchronous())
|
|
return TRUE;
|
|
if (font.m_pFont != NULL)
|
|
{
|
|
CString strName;
|
|
if (PX_String(pPX, _T("FontName"), strName))
|
|
{
|
|
BSTR bstrName;
|
|
bstrName = SysAllocString(T2COLE(strName));
|
|
font.m_pFont->put_Name(bstrName);
|
|
SysFreeString(bstrName);
|
|
}
|
|
|
|
CY cySize;
|
|
if (PX_Currency(pPX, _T("FontSize"), cySize))
|
|
font.m_pFont->put_Size(cySize);
|
|
|
|
BOOL bFlag;
|
|
if (PX_Bool(pPX, _T("FontBold"), bFlag))
|
|
font.m_pFont->put_Bold(bFlag);
|
|
if (PX_Bool(pPX, _T("FontItalic"), bFlag))
|
|
font.m_pFont->put_Italic(bFlag);
|
|
if (PX_Bool(pPX, _T("FontUnderline"), bFlag))
|
|
font.m_pFont->put_Underline(bFlag);
|
|
if (PX_Bool(pPX, _T("FontStrikethru"), bFlag))
|
|
font.m_pFont->put_Strikethrough(bFlag);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#ifndef _MAC
|
|
|
|
static
|
|
BOOL _afxPX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
|
|
CDataPathProperty& dataPathProp, VARTYPE vtDefault, const void* pvDefault)
|
|
{
|
|
ASSERT_POINTER(pPX, CPropExchange);
|
|
ASSERT(AfxIsValidString(pszPropName));
|
|
|
|
const BOOL bIsLoading = pPX->IsLoading();
|
|
|
|
COleControl* pControl = dataPathProp.GetControl();
|
|
if (!pControl)
|
|
TRACE0("No control in PX_DataPath!");
|
|
|
|
BOOL bHasClientSite = pControl ? NULL != pControl->GetClientSite() : FALSE;
|
|
|
|
if (!pPX->IsAsynchronous())
|
|
{
|
|
CString strPath;
|
|
if (!bIsLoading)
|
|
strPath = dataPathProp.GetPath();
|
|
if (((pvDefault != NULL) && !pPX->ExchangeProp(pszPropName, vtDefault, &strPath, pvDefault)) ||
|
|
((pvDefault == NULL) && !pPX->ExchangeProp(pszPropName, VT_BSTR, &strPath)))
|
|
return FALSE;
|
|
if (bIsLoading)
|
|
dataPathProp.SetPath(strPath);
|
|
COleControl* pControl = dataPathProp.GetControl();
|
|
if (pControl && !bHasClientSite)
|
|
pControl->RequestAsynchronousExchange(pPX->GetVersion());
|
|
}
|
|
|
|
if (pPX->IsAsynchronous() || bHasClientSite)
|
|
{
|
|
#ifdef _DEBUG
|
|
{
|
|
if (!bHasClientSite)
|
|
TRACE0("No client site in PX_DataPath!");
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
if (bIsLoading)
|
|
return dataPathProp.Open();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
|
|
CDataPathProperty& dataPathProp, LPCTSTR pszDefault)
|
|
{
|
|
return _afxPX_DataPath(pPX, pszPropName, dataPathProp, VT_LPSTR, pszDefault);
|
|
}
|
|
|
|
BOOL AFX_CDECL PX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
|
|
CDataPathProperty& dataPathProp, const CString& strDefault)
|
|
{
|
|
return _afxPX_DataPath(pPX, pszPropName, dataPathProp, VT_BSTR, strDefault);
|
|
}
|
|
|
|
#endif // !_MAC
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Force any extra compiler-generated code into AFX_INIT_SEG
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|