home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / ctlpropx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  29.5 KB  |  1,174 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_PROP_SEG
  14. #pragma code_seg(AFXCTL_PROP_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. #ifdef _DEBUG
  25. #define ASSERT_BUFFER_VALID(p, cb, bWrite) \
  26.     ASSERT(AfxIsValidAddress(p, cb, bWrite))
  27. #else
  28. #define ASSERT_BUFFER_VALID(p, cb, bWrite)
  29. #endif
  30.  
  31. // Old class ID for picture type
  32. AFX_STATIC_DATA const CLSID _afx_CLSID_StdPicture2_V1 =
  33.     { 0xfb8f0824,0x0164,0x101b, { 0x84,0xed,0x08,0x00,0x2b,0x2e,0xc7,0x13 } };
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // _AfxGetArchiveStream
  37.  
  38. LPSTREAM AFXAPI _AfxGetArchiveStream(CArchive& ar, CArchiveStream& stm)
  39. {
  40.     // Obtain direct access to the archive's LPSTREAM.
  41.     ar.Flush();
  42.     CFile* pFile = ar.GetFile();
  43.     ASSERT(pFile != NULL);
  44.     LPSTREAM pstm;
  45.     if (pFile->IsKindOf(RUNTIME_CLASS(COleStreamFile)))
  46.     {
  47.         pstm = ((COleStreamFile*)pFile)->m_lpStream;
  48.         ASSERT(pstm != NULL);
  49.     }
  50.     else
  51.     {
  52.         ASSERT(stm.m_pArchive == NULL || stm.m_pArchive == &ar);
  53.         stm.m_pArchive = &ar;
  54.         pstm = &stm;
  55.     }
  56.     return pstm;
  57. }
  58.  
  59. /////////////////////////////////////////////////////////////////////////////
  60. // _AfxInitBlob
  61.  
  62. BOOL AFXAPI _AfxInitBlob(HGLOBAL* phDst, void* pvSrc)
  63. {
  64.     BOOL bResult = FALSE;
  65.     ULONG cb;
  66.     if ((cb = *(long*)pvSrc) > 0)
  67.     {
  68.         ASSERT_BUFFER_VALID(pvSrc, sizeof(cb) + cb, TRUE);
  69.         *phDst = WCE_FCTN(GlobalAlloc)(GMEM_MOVEABLE, sizeof(cb) + cb);
  70.         if (*phDst != NULL)
  71.         {
  72.             void* pvDst = WCE_FCTN(GlobalLock)(*phDst);
  73.             ASSERT(pvDst != NULL);
  74.             memcpy(pvDst, pvSrc, sizeof(cb) + cb);
  75.             bResult = TRUE;
  76.             WCE_FCTN(GlobalUnlock)(*phDst);
  77.         }
  78.     }
  79.     return bResult;
  80. }
  81.  
  82. /////////////////////////////////////////////////////////////////////////////
  83. // _AfxCopyBlob
  84.  
  85. BOOL AFXAPI _AfxCopyBlob(HGLOBAL* phDst, HGLOBAL hSrc)
  86. {
  87.     BOOL bResult = FALSE;
  88.     void* pvSrc = WCE_FCTN(GlobalLock)(hSrc);
  89.     if (pvSrc != NULL)
  90.     {
  91.         bResult = _AfxInitBlob(phDst, pvSrc);
  92.         WCE_FCTN(GlobalUnlock)(hSrc);
  93.     }
  94.     return bResult;
  95. }
  96.  
  97. /////////////////////////////////////////////////////////////////////////////
  98. // _AfxCopyPropValue
  99.  
  100. BOOL AFXAPI _AfxCopyPropValue(VARTYPE vtProp, void* pvDest, const void * pvSrc)
  101. {
  102.     ASSERT(AfxIsValidAddress(pvDest, 1));
  103.  
  104.     if (pvSrc != NULL)
  105.     {
  106.         ASSERT(AfxIsValidAddress(pvSrc, 1, FALSE));
  107.  
  108.         switch (vtProp)
  109.         {
  110.         case VT_UI1:
  111.             *(BYTE*)pvDest = *(BYTE*)pvSrc;
  112.             break;
  113.         case VT_I2:
  114.             *(short*)pvDest = *(short*)pvSrc;
  115.             break;
  116.         case VT_I4:
  117.             *(long*)pvDest = *(long*)pvSrc;
  118.             break;
  119.         case VT_BOOL:
  120.             *(BOOL*)pvDest = *(BOOL*)pvSrc;
  121.             break;
  122.         case VT_BSTR:
  123.             *(CString*)pvDest = *(CString*)pvSrc;
  124.             break;
  125.         case VT_LPSTR:
  126.             *(CString*)pvDest = (LPCTSTR)pvSrc;
  127.             break;
  128.         case VT_CY:
  129.             *(CY*)pvDest = *(CY*)pvSrc;
  130.             break;
  131.         case VT_R4:
  132.             *(_AFX_FLOAT*)pvDest = *(_AFX_FLOAT*)pvSrc;
  133.             break;
  134.         case VT_R8:
  135.             *(_AFX_DOUBLE*)pvDest = *(_AFX_DOUBLE*)pvSrc;
  136.             break;
  137.         default:
  138.             return FALSE;
  139.         }
  140.     }
  141.     return pvSrc != NULL;
  142. }
  143.  
  144. /////////////////////////////////////////////////////////////////////////////
  145. // COleControl::ExchangeExtent
  146.  
  147. BOOL COleControl::ExchangeExtent(CPropExchange* pPX)
  148. {
  149.     // Save extent
  150.     SIZEL szl;
  151.     szl.cx = m_cxExtent;
  152.     szl.cy = m_cyExtent;
  153.  
  154.     if (PX_Long(pPX, _T("_ExtentX"), szl.cx) &&
  155.         PX_Long(pPX, _T("_ExtentY"), szl.cy))
  156.     {
  157.         if ((pPX->IsLoading()) &&
  158.             ((m_cxExtent != szl.cx) || (m_cyExtent != szl.cy)))
  159.         {
  160.             m_xOleObject.SetExtent(DVASPECT_CONTENT, &szl);
  161.         }
  162.         return TRUE;
  163.     }
  164.     return FALSE;
  165. }
  166.  
  167. /////////////////////////////////////////////////////////////////////////////
  168. // Serialization for version number
  169.  
  170. DWORD COleControl::SerializeVersion(CArchive& ar, DWORD dwVersionDefault,
  171.     BOOL bConvert)
  172. {
  173.     DWORD dwVersion;
  174.  
  175.     if (ar.IsLoading())
  176.     {
  177.         ar >> m_dwVersionLoaded;
  178.         dwVersion = m_dwVersionLoaded;
  179.     }
  180.     else
  181.     {
  182.         dwVersion = bConvert ? dwVersionDefault : m_dwVersionLoaded;
  183.         ar << dwVersion;
  184.     }
  185.  
  186.     return dwVersion;
  187. }
  188.  
  189. /////////////////////////////////////////////////////////////////////////////
  190. // Initialization for version number
  191.  
  192. void COleControl::ResetVersion(DWORD dwVersionDefault)
  193. {
  194.     m_dwVersionLoaded = dwVersionDefault;
  195. }
  196.  
  197. /////////////////////////////////////////////////////////////////////////////
  198. // Serialization for extent
  199.  
  200. void COleControl::SerializeExtent(CArchive& ar)
  201. {
  202.     if (ar.IsLoading())
  203.     {
  204.         SIZEL szl;
  205.         ar >> szl.cx;
  206.         ar >> szl.cy;
  207.         if ((m_cxExtent != szl.cx) || (m_cyExtent != szl.cy))
  208.             m_xOleObject.SetExtent(DVASPECT_CONTENT, &szl);
  209.     }
  210.     else
  211.     {
  212.         ar << m_cxExtent;
  213.         ar << m_cyExtent;
  214.     }
  215. }
  216.  
  217. /////////////////////////////////////////////////////////////////////////////
  218. // CPropExchange member functions
  219.  
  220. BOOL CPropExchange::ExchangeVersion(DWORD& dwVersionLoaded,
  221.     DWORD dwVersionDefault, BOOL bConvert)
  222. {
  223.     BOOL bResult;
  224.     if (m_bLoading)
  225.     {
  226.         bResult = PX_ULong(this, _T("_Version"), m_dwVersion,
  227.             dwVersionDefault);
  228.         dwVersionLoaded = m_dwVersion;
  229.     }
  230.     else
  231.     {
  232.         m_dwVersion = bConvert ? dwVersionDefault : dwVersionLoaded;
  233.         bResult = PX_ULong(this, _T("_Version"), m_dwVersion);
  234.     }
  235.     return bResult;
  236. }
  237.  
  238. /////////////////////////////////////////////////////////////////////////////
  239. // CArchivePropExchange member functions
  240.  
  241. CArchivePropExchange::CArchivePropExchange(CArchive& ar) :
  242.     m_ar(ar)
  243. {
  244.     ASSERT_POINTER(&ar, CArchive);
  245.     m_bLoading = m_ar.IsLoading();
  246. }
  247.  
  248. BOOL CArchivePropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
  249.         void* pvProp, const void* pvDefault)
  250. {
  251.     UNUSED(pszPropName);     // unused in release builds
  252.     UNUSED(pvDefault);       // unused in release builds
  253.  
  254.     ASSERT(AfxIsValidString(pszPropName));
  255.     ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
  256.     ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));
  257.  
  258.     if (m_bLoading)
  259.     {
  260.         switch (vtProp)
  261.         {
  262.         case VT_UI1:
  263.             m_ar >> *(BYTE*)pvProp;
  264.             break;
  265.         case VT_I2:
  266.             m_ar >> *(WORD*)pvProp;
  267.             break;
  268.         case VT_I4:
  269.             m_ar >> *(long*)pvProp;
  270.             break;
  271.         case VT_BOOL:
  272.             *(BOOL*)pvProp = 0;
  273.             m_ar >> *(BYTE*)pvProp;
  274.             break;
  275.         case VT_LPSTR:
  276.         case VT_BSTR:
  277.             m_ar >> *(CString*)pvProp;
  278.             break;
  279.         case VT_CY:
  280.             m_ar >> ((CY*)pvProp)->Lo;
  281.             m_ar >> ((CY*)pvProp)->Hi;
  282.             break;
  283.         case VT_R4:
  284.             m_ar >> *(float*)pvProp;
  285.             break;
  286.         case VT_R8:
  287.             m_ar >> *(double*)pvProp;
  288.             break;
  289.         }
  290.     }
  291.     else
  292.     {
  293.         switch (vtProp)
  294.         {
  295.         case VT_UI1:
  296.             m_ar << *(BYTE*)pvProp;
  297.             break;
  298.         case VT_I2:
  299.             m_ar << *(WORD*)pvProp;
  300.             break;
  301.         case VT_I4:
  302.             m_ar << *(long*)pvProp;
  303.             break;
  304.         case VT_BOOL:
  305.             m_ar << *(BYTE*)pvProp;
  306.             break;
  307.         case VT_LPSTR:
  308.         case VT_BSTR:
  309.             m_ar << *(CString*)pvProp;
  310.             break;
  311.         case VT_CY:
  312.             m_ar << ((CY*)pvProp)->Lo;
  313.             m_ar << ((CY*)pvProp)->Hi;
  314.             break;
  315.         case VT_R4:
  316.             m_ar << *(float*)pvProp;
  317.             break;
  318.         case VT_R8:
  319.             m_ar << *(double*)pvProp;
  320.             break;
  321.         }
  322.     }
  323.  
  324.     return TRUE;
  325. }
  326.  
  327. BOOL CArchivePropExchange::ExchangeBlobProp(LPCTSTR pszPropName,
  328.     HGLOBAL* phBlob, HGLOBAL /*hBlobDefault*/)
  329. {
  330.     UNUSED(pszPropName);     // unused in release builds
  331.  
  332.     ASSERT(AfxIsValidString(pszPropName));
  333.     ASSERT_POINTER(phBlob, HGLOBAL);
  334.  
  335.     DWORD cb;
  336.  
  337.     if (m_bLoading)
  338.     {
  339.         // free previous memory block
  340.         if (*phBlob != NULL)
  341.         {
  342.             WCE_FCTN(GlobalFree)(*phBlob);
  343.             *phBlob = NULL;
  344.         }
  345.  
  346.         // read new size
  347.         m_ar >> cb;
  348.  
  349.         // allocate and fill new memory block
  350.         *phBlob = WCE_FCTN(GlobalAlloc)(GMEM_MOVEABLE, sizeof(cb)+cb);
  351.         if (*phBlob != NULL)
  352.         {
  353.             void* pvBlob = WCE_FCTN(GlobalLock)(*phBlob);
  354.             ASSERT(pvBlob != NULL);
  355.             *(long*)pvBlob = cb;
  356.             if (m_ar.Read((BYTE*)pvBlob+sizeof(cb), cb) != cb)
  357.                 AfxThrowArchiveException(CArchiveException::endOfFile);
  358.             WCE_FCTN(GlobalUnlock)(*phBlob);
  359.         }
  360.     }
  361.     else
  362.     {
  363.         if (*phBlob != NULL)
  364.         {
  365.             void* pvBlob = WCE_FCTN(GlobalLock)(*phBlob);
  366.             ASSERT(pvBlob != NULL);
  367.             cb = *(long*)pvBlob;
  368.             ASSERT_BUFFER_VALID(pvBlob, sizeof(cb)+cb, FALSE);
  369.             m_ar.Write(pvBlob, sizeof(cb)+cb);
  370.             WCE_FCTN(GlobalUnlock)(*phBlob);
  371.         }
  372.         else
  373.             m_ar << (DWORD)0;
  374.     }
  375.     return TRUE;
  376. }
  377.  
  378. BOOL AFXAPI _AfxPeekAtClassIDInStream(LPSTREAM pstm, LPCLSID lpClassID)
  379. {
  380.     // Read the class ID, then restore the seek pointer.
  381.     LARGE_INTEGER li;
  382.     li.LowPart = (DWORD)(-(long)sizeof(CLSID));
  383.     li.HighPart = -1;
  384.  
  385.     return (SUCCEEDED(ReadClassStm(pstm, lpClassID)) &&
  386.         SUCCEEDED(pstm->Seek(li, STREAM_SEEK_CUR, NULL)));
  387. }
  388.  
  389. BOOL AFXAPI _AfxIsSameUnknownObject(REFIID iid, LPUNKNOWN pUnk1, LPUNKNOWN pUnk2)
  390. {
  391.     if (pUnk1 == pUnk2)
  392.         return TRUE;
  393.  
  394.     if (pUnk1 == NULL || pUnk2 == NULL)
  395.         return FALSE;
  396.  
  397.     LPUNKNOWN pI1 = NULL;
  398.     LPUNKNOWN pI2 = NULL;
  399.     BOOL bResult = FALSE;
  400.     if (SUCCEEDED(pUnk1->QueryInterface(iid, (void**)&pI1)))
  401.     {
  402.         ASSERT_POINTER(pI1, IUnknown);
  403.         if (SUCCEEDED(pUnk2->QueryInterface(iid, (void**)&pI2)))
  404.         {
  405.             ASSERT_POINTER(pI2, IUnknown);
  406.             bResult = (pI1 == pI2);
  407.             pI2->Release();
  408.         }
  409.         pI1->Release();
  410.     }
  411.     return bResult;
  412. }
  413.  
  414. BOOL CArchivePropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
  415.         LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
  416. {
  417.     UNUSED(pszPropName);     // unused in release builds
  418.  
  419.     ASSERT(AfxIsValidString(pszPropName));
  420.     ASSERT_POINTER(ppUnk, LPUNKNOWN);
  421.     ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
  422.  
  423.     BOOL bResult = FALSE;
  424.     CArchiveStream stm(&m_ar);
  425.  
  426.     if (m_bLoading)
  427.     {
  428.         RELEASE(*ppUnk);
  429.         *ppUnk = NULL;
  430.  
  431.         BYTE bFlag;
  432.         m_ar >> bFlag;
  433.         if (bFlag != 0xFF)
  434.         {
  435.             // read the CLSID
  436.             CLSID clsid;
  437.             m_ar >> clsid.Data1;
  438.             m_ar >> clsid.Data2;
  439.             m_ar >> clsid.Data3;
  440.             m_ar.Read(&clsid.Data4[0], sizeof clsid.Data4);
  441.  
  442.             // check for GUID_NULL first and skip if found
  443.             if (IsEqualCLSID(clsid, GUID_NULL))
  444.                 bResult = TRUE;
  445.             else
  446.             {
  447.                 // otherwise will need a stream
  448.                 LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
  449. #if !defined(_WIN32_WCE)
  450.                 if (IsEqualCLSID(clsid, CLSID_StdPicture) ||
  451.                     IsEqualCLSID(clsid, _afx_CLSID_StdPicture2_V1))
  452.                 {
  453.                     // special case for pictures
  454.                     bResult = SUCCEEDED(::OleLoadPicture(pstm, 0, FALSE, iid,
  455.                         (void**)ppUnk));
  456.                 }
  457.                 else
  458. #endif // _WIN32_WCE
  459.                 {
  460.                     // otherwise, seek back to the CLSID
  461.                     LARGE_INTEGER li;
  462.                     li.LowPart = (DWORD)(-(long)sizeof(CLSID));
  463.                     li.HighPart = -1;
  464.                     VERIFY(SUCCEEDED(pstm->Seek(li, STREAM_SEEK_CUR, NULL)));
  465.  
  466.                     // and load the object normally
  467.  
  468.                     CLSID clsid;
  469.                     if (SUCCEEDED(::ReadClassStm(pstm, &clsid)) &&
  470.                             (SUCCEEDED(::CoCreateInstance(clsid, NULL,
  471.                                 CLSCTX_SERVER | CLSCTX_REMOTE_SERVER,
  472.                                 iid, (void**)ppUnk)) ||
  473.                             SUCCEEDED(::CoCreateInstance(clsid, NULL,
  474.                                 CLSCTX_SERVER & ~CLSCTX_REMOTE_SERVER,
  475.                                 iid, (void**)ppUnk))))
  476.                     {
  477.                         LPPERSISTSTREAM pps = NULL;
  478.                         if (SUCCEEDED((*ppUnk)->QueryInterface(
  479.                                 IID_IPersistStream, (void**)&pps)) ||
  480.                             SUCCEEDED((*ppUnk)->QueryInterface(
  481.                                 IID_IPersistStreamInit, (void**)&pps)))
  482.                         {
  483.                             ASSERT_POINTER(pps, IPersistStream);
  484.                             bResult = SUCCEEDED(pps->Load(pstm));
  485.                             pps->Release();
  486.                         }
  487.  
  488.                         if (!bResult)
  489.                         {
  490.                             (*ppUnk)->Release();
  491.                             *ppUnk = NULL;
  492.                         }
  493.                     }
  494.                 }
  495.             }
  496.         }
  497.         else
  498.         {
  499.             // Use default value.
  500.             bResult = pUnkDefault == NULL ||
  501.                 SUCCEEDED(pUnkDefault->QueryInterface(iid, (LPVOID*)ppUnk));
  502.         }
  503.     }
  504.     else
  505.     {
  506.         ASSERT_NULL_OR_POINTER(*ppUnk, IUnknown);
  507.  
  508.         // Check if *ppUnk and pUnkDefault are the same thing.  If so, don't
  509.         // bother saving the object; just write a special flag instead.
  510.  
  511.         if (_AfxIsSameUnknownObject(iid, *ppUnk, pUnkDefault))
  512.         {
  513.             m_ar << (BYTE)0xFF;
  514.             bResult = TRUE;
  515.         }
  516.         else
  517.         {
  518.             m_ar << (BYTE)0x00;
  519.             if (*ppUnk != NULL)
  520.             {
  521.                 LPPERSISTSTREAM pps = NULL;
  522.                 if (SUCCEEDED((*ppUnk)->QueryInterface(
  523.                         IID_IPersistStream, (void**)&pps)) ||
  524.                     SUCCEEDED((*ppUnk)->QueryInterface(
  525.                         IID_IPersistStreamInit, (void**)&pps)))
  526.                 {
  527.                     ASSERT_POINTER(pps, IPersistStream);
  528.                     LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
  529.                     bResult = SUCCEEDED(::WCE_FCTN(OleSaveToStream)(pps, pstm));
  530.                     pps->Release();
  531.                 }
  532.             }
  533.             else
  534.             {
  535.                 // If no object, write null class ID.
  536.                 m_ar.Write(&GUID_NULL, sizeof(GUID));
  537.             }
  538.         }
  539.     }
  540.  
  541.     // throw exception in case of unthrown errors
  542.     if (!bResult)
  543.         AfxThrowArchiveException(CArchiveException::generic);
  544.  
  545.     return TRUE;
  546. }
  547.  
  548. BOOL CArchivePropExchange::ExchangeFontProp(LPCTSTR pszPropName,
  549.     CFontHolder& font, const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
  550. {
  551.     UNUSED(pszPropName);     // unused in release builds
  552.  
  553.     ASSERT(AfxIsValidString(pszPropName));
  554.     ASSERT_POINTER(&font, CFontHolder);
  555.     ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
  556.     ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
  557.  
  558.     BOOL bResult = FALSE;
  559.     CArchiveStream stm(&m_ar);
  560.     LPFONT pFont;
  561.  
  562.     if (m_bLoading)
  563.     {
  564.         BYTE bFlag;
  565.         m_ar >> bFlag;
  566.         if (bFlag != 0xFF)
  567.         {
  568.             LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
  569.             pFont = _AfxCreateFontFromStream(pstm);
  570.             if (pFont != NULL)
  571.             {
  572.                 font.SetFont(pFont);
  573.                 bResult = TRUE;
  574.             }
  575.         }
  576.         if (!bResult)
  577.         {
  578.             font.InitializeFont(pFontDesc, pFontDispAmbient);
  579.             bResult = TRUE;
  580.         }
  581.     }
  582.     else
  583.     {
  584.         pFont = font.m_pFont;
  585.         if (pFont != NULL)
  586.         {
  587.             // If same as ambient font (or error), write 0xFF for the flag
  588.             if (!_AfxIsSameFont(font, pFontDesc, pFontDispAmbient))
  589.             {
  590.                 LPPERSISTSTREAM pps = NULL;
  591.                 if (SUCCEEDED(pFont->QueryInterface(IID_IPersistStream,
  592.                     (LPVOID*)&pps)))
  593.                 {
  594.                     ASSERT_POINTER(pps, IPersistStream);
  595.                     m_ar << (BYTE)0x00;
  596.                     LPSTREAM pstm = _AfxGetArchiveStream(m_ar, stm);
  597.                     bResult = SUCCEEDED(::WCE_FCTN(OleSaveToStream)(pps, pstm));
  598.                     pps->Release();
  599.                     if (!bResult)
  600.                         AfxThrowArchiveException(CArchiveException::generic);
  601.                 }
  602.             }
  603.         }
  604.         if (!bResult)
  605.         {
  606.             m_ar << (BYTE)0xFF;
  607.             bResult = TRUE;
  608.         }
  609.     }
  610.     return bResult;
  611. }
  612.  
  613. /////////////////////////////////////////////////////////////////////////////
  614. // CResetPropExchange member functions
  615.  
  616. CResetPropExchange::CResetPropExchange()
  617. {
  618.     m_bLoading = TRUE;
  619. }
  620.  
  621. BOOL CResetPropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
  622.         void* pvProp, const void* pvDefault)
  623. {
  624.     UNUSED(pszPropName);     // unused in release builds
  625.  
  626.     ASSERT(AfxIsValidString(pszPropName));
  627.     ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
  628.     ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));
  629.  
  630.     return _AfxCopyPropValue(vtProp, pvProp, pvDefault);
  631. }
  632.  
  633. BOOL CResetPropExchange::ExchangeBlobProp(LPCTSTR pszPropName,
  634.     HGLOBAL* phBlob, HGLOBAL hBlobDefault)
  635. {
  636.     UNUSED(pszPropName);     // unused in release builds
  637.  
  638.     ASSERT(AfxIsValidString(pszPropName));
  639.     ASSERT_POINTER(phBlob, HGLOBAL);
  640.  
  641.     // free the previous memory block
  642.     if (*phBlob != NULL)
  643.     {
  644.         WCE_FCTN(GlobalFree)(*phBlob);
  645.         *phBlob = NULL;
  646.     }
  647.  
  648.     // copy the memory block
  649.     BOOL bResult = TRUE;
  650.     if (hBlobDefault != NULL)
  651.         bResult = _AfxCopyBlob(phBlob, hBlobDefault);
  652.     return bResult;
  653. }
  654.  
  655. BOOL CResetPropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
  656.         LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
  657. {
  658.     UNUSED(pszPropName);     // unused in release builds
  659.  
  660.     ASSERT(AfxIsValidString(pszPropName));
  661.     ASSERT_POINTER(ppUnk, LPUNKNOWN);
  662.     ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
  663.  
  664.     RELEASE(*ppUnk);
  665.  
  666.     BOOL bResult = TRUE;
  667.     if (pUnkDefault != NULL)
  668.     {
  669.         bResult = SUCCEEDED(pUnkDefault->QueryInterface(iid,
  670.             (LPVOID*)ppUnk));
  671.     }
  672.     return bResult;
  673. }
  674.  
  675. BOOL CResetPropExchange::ExchangeFontProp(
  676.     LPCTSTR pszPropName, CFontHolder& font, const FONTDESC* pFontDesc,
  677.     LPFONTDISP pFontDispAmbient)
  678. {
  679.     UNUSED(pszPropName);     // unused in release builds
  680.  
  681.     ASSERT(AfxIsValidString(pszPropName));
  682.     ASSERT_POINTER(&font, CFontHolder);
  683.     ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
  684.     ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
  685.  
  686.     font.InitializeFont(pFontDesc, pFontDispAmbient);
  687.     return TRUE;
  688. }
  689.  
  690. /////////////////////////////////////////////////////////////////////////////
  691. // CAsyncPropExchange member functions
  692.  
  693. CAsyncPropExchange::CAsyncPropExchange(DWORD dwVersion)
  694. {
  695.     m_bAsync = TRUE;
  696.     m_bLoading = TRUE;
  697.     m_dwVersion = dwVersion;
  698. }
  699.  
  700. BOOL CAsyncPropExchange::ExchangeVersion(DWORD& dwVersionLoaded,
  701.     DWORD dwVersionDefault, BOOL bConvert)
  702. {
  703.     if (m_bLoading)
  704.     {
  705.         dwVersionLoaded = m_dwVersion;
  706.         return TRUE;
  707.     }
  708.     else
  709.     {
  710.         return m_dwVersion == (bConvert ? dwVersionDefault : dwVersionLoaded);
  711.     }
  712. }
  713.  
  714. BOOL CAsyncPropExchange::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
  715.     void* pvProp, const void* pvDefault)
  716. {
  717.     // Should never be called
  718.     UNUSED_ALWAYS(pszPropName);
  719.     UNUSED_ALWAYS(vtProp);
  720.     UNUSED_ALWAYS(pvProp);
  721.     UNUSED_ALWAYS(pvDefault);
  722.     ASSERT(FALSE);
  723.     return FALSE;
  724. }
  725.  
  726. BOOL CAsyncPropExchange::ExchangeBlobProp(LPCTSTR pszPropName, HGLOBAL* phBlob,
  727.     HGLOBAL hBlobDefault)
  728. {
  729.     // Should never be called
  730.     UNUSED_ALWAYS(pszPropName);
  731.     UNUSED_ALWAYS(phBlob);
  732.     UNUSED_ALWAYS(hBlobDefault);
  733.     ASSERT(FALSE);
  734.     return FALSE;
  735. }
  736.  
  737. BOOL CAsyncPropExchange::ExchangeFontProp(LPCTSTR pszPropName,
  738.     CFontHolder& font, const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
  739. {
  740.     // Should never be called
  741.     UNUSED_ALWAYS(pszPropName);
  742.     UNUSED_ALWAYS(font);
  743.     UNUSED_ALWAYS(pFontDesc);
  744.     UNUSED_ALWAYS(pFontDispAmbient);
  745.     ASSERT(FALSE);
  746.     return FALSE;
  747. }
  748.  
  749. BOOL CAsyncPropExchange::ExchangePersistentProp(LPCTSTR pszPropName,
  750.     LPUNKNOWN* ppUnk, REFIID iid, LPUNKNOWN pUnkDefault)
  751. {
  752.     // Should never be called
  753.     UNUSED_ALWAYS(pszPropName);
  754.     UNUSED_ALWAYS(ppUnk);
  755.     UNUSED_ALWAYS(iid);
  756.     UNUSED_ALWAYS(pUnkDefault);
  757.     ASSERT(FALSE);
  758.     return FALSE;
  759. }
  760.  
  761. /////////////////////////////////////////////////////////////////////////////
  762. // PX_ functions
  763.  
  764. BOOL AFX_CDECL PX_Short(CPropExchange* pPX, LPCTSTR pszPropName, short& sValue)
  765. {
  766.     ASSERT_POINTER(pPX, CPropExchange);
  767.     ASSERT(AfxIsValidString(pszPropName));
  768.     ASSERT_POINTER(&sValue, short);
  769.  
  770.     if (pPX->IsAsynchronous())
  771.         return TRUE;
  772.     return  pPX->ExchangeProp(pszPropName, VT_I2, &sValue);
  773. }
  774.  
  775. BOOL AFX_CDECL PX_Short(CPropExchange* pPX, LPCTSTR pszPropName, short& sValue,
  776.     short sDefault)
  777. {
  778.     ASSERT_POINTER(pPX, CPropExchange);
  779.     ASSERT(AfxIsValidString(pszPropName));
  780.     ASSERT_POINTER(&sValue, short);
  781.  
  782.     if (pPX->IsAsynchronous())
  783.         return TRUE;
  784.     return pPX->ExchangeProp(pszPropName, VT_I2, &sValue, &sDefault);
  785. }
  786.  
  787. BOOL AFX_CDECL PX_UShort(CPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue)
  788. {
  789.     ASSERT_POINTER(pPX, CPropExchange);
  790.     ASSERT(AfxIsValidString(pszPropName));
  791.     ASSERT_POINTER(&usValue, USHORT);
  792.  
  793.     if (pPX->IsAsynchronous())
  794.         return TRUE;
  795.     return pPX->ExchangeProp(pszPropName, VT_I2, &usValue);
  796. }
  797.  
  798. BOOL AFX_CDECL PX_UShort(CPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue,
  799.     USHORT usDefault)
  800. {
  801.     ASSERT_POINTER(pPX, CPropExchange);
  802.     ASSERT(AfxIsValidString(pszPropName));
  803.     ASSERT_POINTER(&usValue, USHORT);
  804.  
  805.     if (pPX->IsAsynchronous())
  806.         return TRUE;
  807.     return pPX->ExchangeProp(pszPropName, VT_I2, &usValue, &usDefault);
  808. }
  809.  
  810. BOOL AFX_CDECL PX_Long(CPropExchange* pPX, LPCTSTR pszPropName, long& lValue)
  811. {
  812.     ASSERT_POINTER(pPX, CPropExchange);
  813.     ASSERT(AfxIsValidString(pszPropName));
  814.     ASSERT_POINTER(&lValue, long);
  815.  
  816.     if (pPX->IsAsynchronous())
  817.         return TRUE;
  818.     return pPX->ExchangeProp(pszPropName, VT_I4, &lValue);
  819. }
  820.  
  821. BOOL AFX_CDECL PX_Long(CPropExchange* pPX, LPCTSTR pszPropName, long& lValue,
  822.     long lDefault)
  823. {
  824.     ASSERT_POINTER(pPX, CPropExchange);
  825.     ASSERT(AfxIsValidString(pszPropName));
  826.     ASSERT_POINTER(&lValue, long);
  827.  
  828.     if (pPX->IsAsynchronous())
  829.         return TRUE;
  830.     return pPX->ExchangeProp(pszPropName, VT_I4, &lValue, &lDefault);
  831. }
  832.  
  833. BOOL AFX_CDECL PX_ULong(CPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue)
  834. {
  835.     ASSERT_POINTER(pPX, CPropExchange);
  836.     ASSERT(AfxIsValidString(pszPropName));
  837.     ASSERT_POINTER(&ulValue, ULONG);
  838.  
  839.     if (pPX->IsAsynchronous())
  840.         return TRUE;
  841.     return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue);
  842. }
  843.  
  844. BOOL AFX_CDECL PX_ULong(CPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue,
  845.     ULONG ulDefault)
  846. {
  847.     ASSERT_POINTER(pPX, CPropExchange);
  848.     ASSERT(AfxIsValidString(pszPropName));
  849.     ASSERT_POINTER(&ulValue, ULONG);
  850.  
  851.     if (pPX->IsAsynchronous())
  852.         return TRUE;
  853.     return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue, &ulDefault);
  854. }
  855.  
  856. BOOL AFX_CDECL PX_Color(CPropExchange* pPX, LPCTSTR pszPropName, OLE_COLOR& clrValue)
  857. {
  858.     ASSERT_POINTER(pPX, CPropExchange);
  859.     ASSERT(AfxIsValidString(pszPropName));
  860.     ASSERT_POINTER(&clrValue, OLE_COLOR);
  861.  
  862.     if (pPX->IsAsynchronous())
  863.         return TRUE;
  864.     return pPX->ExchangeProp(pszPropName, VT_I4, &clrValue);
  865. }
  866.  
  867. BOOL AFX_CDECL PX_Color(CPropExchange* pPX, LPCTSTR pszPropName, OLE_COLOR& clrValue,
  868.     OLE_COLOR clrDefault)
  869. {
  870.     ASSERT_POINTER(pPX, CPropExchange);
  871.     ASSERT(AfxIsValidString(pszPropName));
  872.     ASSERT_POINTER(&clrValue, OLE_COLOR);
  873.  
  874.     if (pPX->IsAsynchronous())
  875.         return TRUE;
  876.     return pPX->ExchangeProp(pszPropName, VT_I4, &clrValue, &clrDefault);
  877. }
  878.  
  879. BOOL AFX_CDECL PX_Bool(CPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue)
  880. {
  881.     ASSERT_POINTER(pPX, CPropExchange);
  882.     ASSERT(AfxIsValidString(pszPropName));
  883.     ASSERT_POINTER(&bValue, BOOL);
  884.  
  885.     if (pPX->IsAsynchronous())
  886.         return TRUE;
  887.     return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue);
  888. }
  889.  
  890. BOOL AFX_CDECL PX_Bool(CPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue,
  891.     BOOL bDefault)
  892. {
  893.     ASSERT_POINTER(pPX, CPropExchange);
  894.     ASSERT(AfxIsValidString(pszPropName));
  895.     ASSERT_POINTER(&bValue, BOOL);
  896.  
  897.     if (pPX->IsAsynchronous())
  898.         return TRUE;
  899.     return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue, &bDefault);
  900. }
  901.  
  902. BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue)
  903. {
  904.     ASSERT_POINTER(pPX, CPropExchange);
  905.     ASSERT(AfxIsValidString(pszPropName));
  906.     ASSERT_POINTER(&strValue, CString);
  907.  
  908.     if (pPX->IsAsynchronous())
  909.         return TRUE;
  910.     return pPX->ExchangeProp(pszPropName, VT_BSTR, &strValue);
  911. }
  912.  
  913. BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue,
  914.     const CString& strDefault)
  915. {
  916.     ASSERT_POINTER(pPX, CPropExchange);
  917.     ASSERT(AfxIsValidString(pszPropName));
  918.     ASSERT_POINTER(&strValue, CString);
  919.  
  920.     if (pPX->IsAsynchronous())
  921.         return TRUE;
  922.     return pPX->ExchangeProp(pszPropName, VT_BSTR, &strValue, &strDefault);
  923. }
  924.  
  925. BOOL AFX_CDECL PX_String(CPropExchange* pPX, LPCTSTR pszPropName, CString& strValue,
  926.     LPCTSTR lpszDefault)
  927. {
  928.     ASSERT_POINTER(pPX, CPropExchange);
  929.     ASSERT(AfxIsValidString(pszPropName));
  930.     ASSERT_POINTER(&strValue, CString);
  931.  
  932.     if (pPX->IsAsynchronous())
  933.         return TRUE;
  934.     return pPX->ExchangeProp(pszPropName, VT_LPSTR, &strValue, lpszDefault);
  935. }
  936.  
  937. BOOL AFX_CDECL PX_Currency(CPropExchange* pPX, LPCTSTR pszPropName, CY& cyValue)
  938. {
  939.     ASSERT_POINTER(pPX, CPropExchange);
  940.     ASSERT(AfxIsValidString(pszPropName));
  941.     ASSERT_POINTER(&cyValue, CY);
  942.  
  943.     if (pPX->IsAsynchronous())
  944.         return TRUE;
  945.     return pPX->ExchangeProp(pszPropName, VT_CY, &cyValue);
  946. }
  947.  
  948. BOOL AFX_CDECL PX_Currency(CPropExchange* pPX, LPCTSTR pszPropName, CY& cyValue,
  949.     CY cyDefault)
  950. {
  951.     ASSERT_POINTER(pPX, CPropExchange);
  952.     ASSERT(AfxIsValidString(pszPropName));
  953.     ASSERT_POINTER(&cyValue, CY);
  954.  
  955.     if (pPX->IsAsynchronous())
  956.         return TRUE;
  957.     return pPX->ExchangeProp(pszPropName, VT_CY, &cyValue, &cyDefault);
  958. }
  959.  
  960. BOOL AFX_CDECL PX_Float(CPropExchange* pPX, LPCTSTR pszPropName, float& floatValue)
  961. {
  962.     ASSERT_POINTER(pPX, CPropExchange);
  963.     ASSERT(AfxIsValidString(pszPropName));
  964.     ASSERT_POINTER(&floatValue, float);
  965.  
  966.     if (pPX->IsAsynchronous())
  967.         return TRUE;
  968.     return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue);
  969. }
  970.  
  971. BOOL AFX_CDECL PX_Float(CPropExchange* pPX, LPCTSTR pszPropName, float& floatValue,
  972.     float floatDefault)
  973. {
  974.     ASSERT_POINTER(pPX, CPropExchange);
  975.     ASSERT(AfxIsValidString(pszPropName));
  976.     ASSERT_POINTER(&floatValue, float);
  977.  
  978.     if (pPX->IsAsynchronous())
  979.         return TRUE;
  980.     return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue, &floatDefault);
  981. }
  982.  
  983. BOOL AFX_CDECL PX_Double(CPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue)
  984. {
  985.     ASSERT_POINTER(pPX, CPropExchange);
  986.     ASSERT(AfxIsValidString(pszPropName));
  987.     ASSERT_POINTER(&doubleValue, double);
  988.  
  989.     if (pPX->IsAsynchronous())
  990.         return TRUE;
  991.     return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue);
  992. }
  993.  
  994. BOOL AFX_CDECL PX_Double(CPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue,
  995.     double doubleDefault)
  996. {
  997.     ASSERT_POINTER(pPX, CPropExchange);
  998.     ASSERT(AfxIsValidString(pszPropName));
  999.     ASSERT_POINTER(&doubleValue, double);
  1000.  
  1001.     if (pPX->IsAsynchronous())
  1002.         return TRUE;
  1003.     return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue, &doubleDefault);
  1004. }
  1005.  
  1006. BOOL AFX_CDECL PX_Blob(CPropExchange* pPX, LPCTSTR pszPropName, HGLOBAL& hBlob,
  1007.     HGLOBAL hBlobDefault)
  1008. {
  1009.     ASSERT_POINTER(pPX, CPropExchange);
  1010.     ASSERT(AfxIsValidString(pszPropName));
  1011.     ASSERT_POINTER(&hBlob, HGLOBAL);
  1012.  
  1013.     if (pPX->IsAsynchronous())
  1014.         return TRUE;
  1015.     return pPX->ExchangeBlobProp(pszPropName, &hBlob, hBlobDefault);
  1016. }
  1017.  
  1018. BOOL AFX_CDECL PX_Font(CPropExchange* pPX, LPCTSTR pszPropName, CFontHolder& font,
  1019.         const FONTDESC* pFontDesc, LPFONTDISP pFontDispAmbient)
  1020. {
  1021.     ASSERT_POINTER(pPX, CPropExchange);
  1022.     ASSERT(AfxIsValidString(pszPropName));
  1023.     ASSERT_POINTER(&font, CFontHolder);
  1024.     ASSERT_NULL_OR_POINTER(pFontDesc, FONTDESC);
  1025.     ASSERT_NULL_OR_POINTER(pFontDispAmbient, IFontDisp);
  1026.  
  1027.     if (pPX->IsAsynchronous())
  1028.         return TRUE;
  1029.     return pPX->ExchangeFontProp(pszPropName, font, pFontDesc,
  1030.         pFontDispAmbient);
  1031. }
  1032.  
  1033. BOOL AFX_CDECL PX_IUnknown(CPropExchange* pPX, LPCTSTR pszPropName, LPUNKNOWN& pUnk,
  1034.     REFIID iid, LPUNKNOWN pUnkDefault)
  1035. {
  1036.     ASSERT_POINTER(pPX, CPropExchange);
  1037.     ASSERT(AfxIsValidString(pszPropName));
  1038.     ASSERT_POINTER(&pUnk, LPUNKNOWN);
  1039.     ASSERT_NULL_OR_POINTER(pUnk, IUnknown);
  1040.     ASSERT_NULL_OR_POINTER(pUnkDefault, IUnknown);
  1041.  
  1042.     if (pPX->IsAsynchronous())
  1043.         return TRUE;
  1044.     return pPX->ExchangePersistentProp(pszPropName, &pUnk, iid, pUnkDefault);
  1045. }
  1046.  
  1047. BOOL AFX_CDECL PX_Picture(CPropExchange* pPX, LPCTSTR pszPropName, CPictureHolder& pict)
  1048. {
  1049.     ASSERT_POINTER(pPX, CPropExchange);
  1050.     ASSERT(AfxIsValidString(pszPropName));
  1051.     ASSERT_POINTER(&pict, CPictureHolder);
  1052.  
  1053.     if (pPX->IsAsynchronous())
  1054.         return TRUE;
  1055.     LPUNKNOWN& pUnk = (LPUNKNOWN&)pict.m_pPict;
  1056.     return PX_IUnknown(pPX, pszPropName, pUnk, IID_IPicture);
  1057. }
  1058.  
  1059. BOOL AFX_CDECL PX_Picture(CPropExchange* pPX, LPCTSTR pszPropName, CPictureHolder& pict,
  1060.     CPictureHolder& pictDefault)
  1061. {
  1062.     ASSERT_POINTER(pPX, CPropExchange);
  1063.     ASSERT(AfxIsValidString(pszPropName));
  1064.     ASSERT_POINTER(&pict, CPictureHolder);
  1065.  
  1066.     if (pPX->IsAsynchronous())
  1067.         return TRUE;
  1068.     LPUNKNOWN& pUnk = (LPUNKNOWN&)pict.m_pPict;
  1069.     return PX_IUnknown(pPX, pszPropName, pUnk, IID_IPicture,
  1070.         pictDefault.m_pPict);
  1071. }
  1072.  
  1073. BOOL AFX_CDECL PX_VBXFontConvert(CPropExchange* pPX, CFontHolder& font)
  1074. {
  1075.     USES_CONVERSION;
  1076.  
  1077.     ASSERT_POINTER(pPX, CPropExchange);
  1078.     ASSERT_POINTER(&font, CFontHolder);
  1079.  
  1080.     if (pPX->IsAsynchronous())
  1081.         return TRUE;
  1082.     if (font.m_pFont != NULL)
  1083.     {
  1084.         CString strName;
  1085.         if (PX_String(pPX, _T("FontName"), strName))
  1086.         {
  1087.             BSTR bstrName;
  1088.             bstrName = SysAllocString(T2COLE(strName));
  1089.             font.m_pFont->put_Name(bstrName);
  1090.             SysFreeString(bstrName);
  1091.         }
  1092.  
  1093.         CY cySize;
  1094.         if (PX_Currency(pPX, _T("FontSize"), cySize))
  1095.             font.m_pFont->put_Size(cySize);
  1096.  
  1097.         BOOL bFlag;
  1098.         if (PX_Bool(pPX, _T("FontBold"), bFlag))
  1099.             font.m_pFont->put_Bold(bFlag);
  1100.         if (PX_Bool(pPX, _T("FontItalic"), bFlag))
  1101.             font.m_pFont->put_Italic(bFlag);
  1102.         if (PX_Bool(pPX, _T("FontUnderline"), bFlag))
  1103.             font.m_pFont->put_Underline(bFlag);
  1104.         if (PX_Bool(pPX, _T("FontStrikethru"), bFlag))
  1105.             font.m_pFont->put_Strikethrough(bFlag);
  1106.     }
  1107.     return TRUE;
  1108. }
  1109.  
  1110. #if !defined(_WIN32_WCE)
  1111. AFX_STATIC BOOL AFXAPI _Afx_PX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
  1112.     CDataPathProperty& dataPathProp, VARTYPE vtDefault, const void* pvDefault)
  1113. {
  1114.     ASSERT_POINTER(pPX, CPropExchange);
  1115.     ASSERT(AfxIsValidString(pszPropName));
  1116.  
  1117.     const BOOL bIsLoading = pPX->IsLoading();
  1118.  
  1119.     COleControl* pControl = dataPathProp.GetControl();
  1120.     if (!pControl)
  1121.         TRACE0("No control in PX_DataPath!");
  1122.  
  1123.     BOOL bHasClientSite = pControl ? NULL != pControl->GetClientSite() : FALSE;
  1124.  
  1125.     if (!pPX->IsAsynchronous())
  1126.     {
  1127.         CString strPath;
  1128.         if (!bIsLoading)
  1129.             strPath = dataPathProp.GetPath();
  1130.         if (((pvDefault != NULL) && !pPX->ExchangeProp(pszPropName, vtDefault, &strPath, pvDefault)) ||
  1131.             ((pvDefault == NULL) && !pPX->ExchangeProp(pszPropName, VT_BSTR, &strPath)))
  1132.             return FALSE;
  1133.         if (bIsLoading)
  1134.             dataPathProp.SetPath(strPath);
  1135.         if (pControl && !bHasClientSite)
  1136.             pControl->RequestAsynchronousExchange(pPX->GetVersion());
  1137.     }
  1138.  
  1139.     if (pPX->IsAsynchronous() || bHasClientSite)
  1140.     {
  1141. #ifdef _DEBUG
  1142.         {
  1143.             if (!bHasClientSite)
  1144.                 TRACE0("No client site in PX_DataPath!");
  1145.         }
  1146. #endif // _DEBUG
  1147.  
  1148.         if (bIsLoading)
  1149.             return dataPathProp.Open();
  1150.     }
  1151.  
  1152.     return TRUE;
  1153. }
  1154.  
  1155. BOOL AFX_CDECL PX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
  1156.     CDataPathProperty& dataPathProp, LPCTSTR pszDefault)
  1157. {
  1158.     return _Afx_PX_DataPath(pPX, pszPropName, dataPathProp, VT_LPSTR, pszDefault);
  1159. }
  1160.  
  1161. BOOL AFX_CDECL PX_DataPath(CPropExchange* pPX, LPCTSTR pszPropName,
  1162.     CDataPathProperty& dataPathProp, const CString& strDefault)
  1163. {
  1164.     return _Afx_PX_DataPath(pPX, pszPropName, dataPathProp, VT_BSTR, &strDefault);
  1165. }
  1166. #endif // _WIN32_WCE
  1167.  
  1168. /////////////////////////////////////////////////////////////////////////////
  1169. // Force any extra compiler-generated code into AFX_INIT_SEG
  1170.  
  1171. #ifdef AFX_INIT_SEG
  1172. #pragma code_seg(AFX_INIT_SEG)
  1173. #endif
  1174.