You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2964 lines
61 KiB
C++
2964 lines
61 KiB
C++
2 years ago
|
// XTPPropExchange.cpp: implementation of the CXTPPropExchange class.
|
||
|
//
|
||
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
||
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
||
|
//
|
||
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
//
|
||
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
// SINGLE COMPUTER.
|
||
|
//
|
||
|
// CONTACT INFORMATION:
|
||
|
// support@codejock.com
|
||
|
// http://www.codejock.com
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "XTPMacros.h"
|
||
|
#include "XTPPropExchange.h"
|
||
|
#include "XTPVC80Helpers.h"
|
||
|
|
||
|
#include "XTPResourceManager.h"
|
||
|
|
||
|
#include <afxole.h>
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#define new DEBUG_NEW
|
||
|
#endif
|
||
|
|
||
|
#pragma warning(disable : 4310)
|
||
|
|
||
|
#ifdef _UNICODE
|
||
|
#define CT2BSTR(x) (BSTR)(LPCWSTR)x
|
||
|
#else
|
||
|
#define CT2BSTR(x) (BSTR)XTP_CT2CW(x)
|
||
|
#endif
|
||
|
|
||
|
enum VARTYPE_EX
|
||
|
{
|
||
|
VT_EX_RECT = 100,
|
||
|
VT_EX_SIZE = 101
|
||
|
};
|
||
|
|
||
|
LCID CXTPPropExchange::m_lcidDateTime = XTP_LOCALE_ISO8601;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL ParseDateTimeISO8601(COleDateTime& rDT, LPCTSTR pcszDateTime)
|
||
|
{
|
||
|
SYSTEMTIME st;
|
||
|
ZeroMemory(&st, sizeof(SYSTEMTIME));
|
||
|
|
||
|
int nResult = SCANF_S(pcszDateTime, _T("%hu-%hu-%huT%hu:%hu:%hu"),
|
||
|
&st.wYear, &st.wDay, &st.wMonth, &st.wHour, &st.wMinute, &st.wSecond);
|
||
|
|
||
|
if (nResult == 3 || nResult == 5 || nResult == 6)
|
||
|
{
|
||
|
COleDateTime dtTemp(st);
|
||
|
if (dtTemp.GetStatus() != COleDateTime::valid)
|
||
|
return FALSE;
|
||
|
|
||
|
rDT = dtTemp;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
ZeroMemory(&st, sizeof(SYSTEMTIME));
|
||
|
|
||
|
nResult = SCANF_S(pcszDateTime, _T("%hu:%hu:%hu"),
|
||
|
&st.wHour, &st.wMinute, &st.wSecond);
|
||
|
|
||
|
if (nResult == 2 || nResult == 3)
|
||
|
{
|
||
|
double dblTime = (((long)st.wHour * 3600L) + // hrs in seconds
|
||
|
((long)st.wMinute * 60L) + // mins in seconds
|
||
|
((long)st.wSecond)) / 86400.;
|
||
|
|
||
|
rDT = dblTime;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CString FormatDateTimeISO8601(const COleDateTime& dt)
|
||
|
{
|
||
|
ASSERT(dt.m_status == COleDateTime::valid);
|
||
|
|
||
|
CString strValue;
|
||
|
|
||
|
if ((DWORD)dt == 0)
|
||
|
{
|
||
|
strValue = dt.Format(_T("%H:%M:%S"));
|
||
|
}
|
||
|
else if ((double)(DWORD)(dt) == (double)dt)
|
||
|
{
|
||
|
strValue = dt.Format(_T("%Y-%d-%m"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strValue = dt.Format(_T("%Y-%d-%mT%H:%M:%S"));
|
||
|
}
|
||
|
|
||
|
return strValue;
|
||
|
}
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPPropExchangeEnumerator
|
||
|
|
||
|
CXTPPropExchangeEnumerator::CXTPPropExchangeEnumerator(CXTPPropExchange* pContainer, LPCTSTR lpszSection)
|
||
|
{
|
||
|
m_pContainer = pContainer;
|
||
|
m_strSectionName = lpszSection;
|
||
|
m_nCount = 0;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeEnumerator::~CXTPPropExchangeEnumerator()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
POSITION CXTPPropExchangeEnumerator::GetPosition(DWORD dwCount /*= 0*/, BOOL bCompactMode /*= TRUE*/)
|
||
|
{
|
||
|
m_nCount = dwCount;
|
||
|
|
||
|
if (!m_pContainer)
|
||
|
return NULL;
|
||
|
|
||
|
if (!bCompactMode)
|
||
|
{
|
||
|
PX_DWord(m_pContainer, _T("Count"), m_nCount, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_pContainer->IsStoring())
|
||
|
m_pContainer->WriteCount(m_nCount);
|
||
|
else
|
||
|
m_nCount = m_pContainer->ReadCount();
|
||
|
}
|
||
|
|
||
|
return m_nCount == 0 ? NULL : (POSITION)1;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* CXTPPropExchangeEnumerator::GetNext(POSITION& pos)
|
||
|
{
|
||
|
CString strSection;
|
||
|
strSection.Format(_T("%s%i"), (LPCTSTR)m_strSectionName, (DWORD)(DWORD_PTR)pos - 1);
|
||
|
|
||
|
CXTPPropExchange* pSection = m_pContainer->GetSection(strSection);
|
||
|
|
||
|
pos++;
|
||
|
if ((DWORD)(DWORD_PTR)pos > m_nCount) pos = NULL;
|
||
|
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Construction/Destruction
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CXTPPropExchange, CCmdTarget)
|
||
|
|
||
|
CXTPPropExchange::CXTPPropExchange()
|
||
|
{
|
||
|
m_bLoading = FALSE;
|
||
|
m_dwData = 0;
|
||
|
m_pOwner = NULL;
|
||
|
m_nSchema = _XTP_SCHEMA_CURRENT;
|
||
|
m_bChildSection = FALSE;
|
||
|
m_bInitialized = FALSE;
|
||
|
m_bEmptySection = FALSE;
|
||
|
m_bUseDefaultOnLoad = TRUE;
|
||
|
m_bUseDefaultOnSave = TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange::~CXTPPropExchange()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::InitSection(CXTPPropExchange* pRootSection)
|
||
|
{
|
||
|
ASSERT(m_bLoading == pRootSection->m_bLoading);
|
||
|
|
||
|
m_bChildSection = TRUE;
|
||
|
m_nSchema = pRootSection->m_nSchema;
|
||
|
m_dwData = pRootSection->m_dwData;
|
||
|
m_bEmptySection = pRootSection->m_bEmptySection;
|
||
|
m_bUseDefaultOnLoad = pRootSection->m_bUseDefaultOnLoad;
|
||
|
m_bUseDefaultOnSave = pRootSection->m_bUseDefaultOnSave;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void CXTPPropExchange::EmptySection()
|
||
|
{
|
||
|
m_bEmptySection = TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD CXTPPropExchange::GetSizeOfVarType(VARTYPE vt)
|
||
|
{
|
||
|
switch (vt)
|
||
|
{
|
||
|
case VT_BOOL: return sizeof(BOOL);
|
||
|
case VT_UI1: return sizeof(BYTE);
|
||
|
case VT_I2: return 2;
|
||
|
case VT_I4: return 4;
|
||
|
case VT_R4:
|
||
|
ASSERT(sizeof(float) == 4);
|
||
|
return 4;
|
||
|
case VT_R8:
|
||
|
ASSERT(sizeof(double) == 8);
|
||
|
return 8;
|
||
|
case VT_EX_RECT: return sizeof(RECT);
|
||
|
case VT_EX_SIZE: return sizeof(SIZE);
|
||
|
case VT_CY: return sizeof(CURRENCY);
|
||
|
case VT_BSTR:return sizeof(BSTR);
|
||
|
case VT_VARIANT: return sizeof(VARIANT);
|
||
|
case VT_DATE: return sizeof(COleDateTime);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::Write (LPCTSTR pszPropName, const void* lpBuf, UINT nCount)
|
||
|
{
|
||
|
ASSERT(IsStoring());
|
||
|
ASSERT(lpBuf != NULL);
|
||
|
ExchangeBlobProp(pszPropName, (BYTE*&)lpBuf, (DWORD&)nCount);
|
||
|
}
|
||
|
|
||
|
UINT CXTPPropExchange::Read (LPCTSTR pszPropName, void* lpBuf, UINT nCount)
|
||
|
{
|
||
|
ASSERT(IsLoading());
|
||
|
ASSERT(lpBuf != NULL);
|
||
|
if (!ExchangeBlobProp(pszPropName, (BYTE*&)lpBuf, (DWORD&)nCount))
|
||
|
return 0;
|
||
|
|
||
|
return nCount;
|
||
|
}
|
||
|
|
||
|
AFX_INLINE int REPLACEW_S(BSTR& strReplace, LPCWSTR lpszOld, LPCWSTR lpszNew)
|
||
|
{
|
||
|
int nOldLength = (strReplace == NULL) ? 0 : (int)wcslen(strReplace);
|
||
|
int nSourceLen = (lpszOld == NULL) ? 0 : (int)wcslen(lpszOld);
|
||
|
|
||
|
if (nSourceLen == 0 || nOldLength == 0)
|
||
|
return 0;
|
||
|
|
||
|
int nReplacementLen = (lpszNew == NULL) ? 0 : (int)wcslen(lpszNew);
|
||
|
|
||
|
// loop once to figure out the size of the result string
|
||
|
int nCount = 0;
|
||
|
LPWSTR lpszStart = strReplace;
|
||
|
LPWSTR lpszTarget;
|
||
|
|
||
|
while ((lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
|
||
|
{
|
||
|
nCount++;
|
||
|
lpszStart = lpszTarget + nSourceLen;
|
||
|
}
|
||
|
|
||
|
|
||
|
// if any changes were made, make them
|
||
|
if (nCount > 0)
|
||
|
{
|
||
|
int nNewLength = nOldLength + (nReplacementLen-nSourceLen)*nCount;
|
||
|
ASSERT(nNewLength <= nOldLength); // not implemented
|
||
|
|
||
|
lpszStart = strReplace;
|
||
|
|
||
|
// loop again to actually do the work
|
||
|
while ((lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
|
||
|
{
|
||
|
int nBalance = nOldLength - int(lpszTarget - strReplace + nSourceLen);
|
||
|
MEMMOVE_S(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
|
||
|
nBalance * sizeof(WORD));
|
||
|
MEMCPY_S(lpszTarget, lpszNew, nReplacementLen*sizeof(WORD));
|
||
|
lpszStart = lpszTarget + nReplacementLen;
|
||
|
lpszStart[nBalance] = '\0';
|
||
|
nOldLength += (nReplacementLen - nSourceLen);
|
||
|
}
|
||
|
|
||
|
ASSERT(strReplace[nNewLength] == '\0');
|
||
|
}
|
||
|
|
||
|
return nCount;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::PreformatString(BSTR bstrValue)
|
||
|
{
|
||
|
ASSERT(bstrValue && m_bLoading);
|
||
|
|
||
|
REPLACEW_S(bstrValue, L"\\\\", L"\001\001");
|
||
|
REPLACEW_S(bstrValue, L"\\n", L"\n");
|
||
|
REPLACEW_S(bstrValue, L"\\r", L"\r");
|
||
|
REPLACEW_S(bstrValue, L"\\t", L"\t");
|
||
|
REPLACEW_S(bstrValue, L"\001\001", L"\\");
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::PreformatString(CString& strValue, BOOL bLoading)
|
||
|
{
|
||
|
if (bLoading)
|
||
|
{
|
||
|
if (strValue.Find(_T('\\')) == -1)
|
||
|
return;
|
||
|
|
||
|
strValue.Replace(_T("\\\\"), _T("\001\001"));
|
||
|
strValue.Replace(_T("\\n"), _T("\n"));
|
||
|
strValue.Replace(_T("\\r"), _T("\r"));
|
||
|
strValue.Replace(_T("\\t"), _T("\t"));
|
||
|
strValue.Replace(_T("\001\001"), _T("\\"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strValue.Replace(_T("\\"), _T("\\\\"));
|
||
|
strValue.Replace(_T("\n"), _T("\\n"));
|
||
|
strValue.Replace(_T("\r"), _T("\\r"));
|
||
|
strValue.Replace(_T("\t"), _T("\\t"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::PreformatString(CString& strValue)
|
||
|
{
|
||
|
PreformatString(strValue, m_bLoading);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchange::ExchangePropDateHelper(CString& strValue, COleDateTime& dt)
|
||
|
{
|
||
|
if (m_lcidDateTime == XTP_LOCALE_ISO8601)
|
||
|
{
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
return ParseDateTimeISO8601(dt, strValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strValue = FormatDateTimeISO8601(dt);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
if (!dt.ParseDateTime(strValue, 0, m_lcidDateTime))
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRY
|
||
|
{
|
||
|
strValue = dt.Format(0, m_lcidDateTime);
|
||
|
}
|
||
|
CATCH_ALL(e)
|
||
|
{
|
||
|
VERIFY(strValue.LoadString(AFX_IDS_INVALID_DATETIME));
|
||
|
}
|
||
|
END_CATCH_ALL
|
||
|
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchange::ExchangePropStringHelper(CString& strValue, VARTYPE vtProp,
|
||
|
void* pvProp, const void* pvDefault)
|
||
|
{
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_BOOL:
|
||
|
{
|
||
|
int dwValue = _ttoi(strValue);
|
||
|
return CopyPropValue(vtProp, pvProp, &dwValue);
|
||
|
}
|
||
|
case VT_R4:
|
||
|
{
|
||
|
TCHAR* pChar = NULL;
|
||
|
float fValue = (float)_tcstod(strValue, &pChar);
|
||
|
return CopyPropValue(vtProp, pvProp, &fValue);
|
||
|
}
|
||
|
case VT_R8:
|
||
|
{
|
||
|
TCHAR* pChar = NULL;
|
||
|
double fValue = _tcstod(strValue, &pChar);
|
||
|
return CopyPropValue(vtProp, pvProp, &fValue);
|
||
|
}
|
||
|
case VT_DATE:
|
||
|
{
|
||
|
COleDateTime dt;
|
||
|
|
||
|
if (!ExchangePropDateHelper(strValue, dt))
|
||
|
return FALSE;
|
||
|
|
||
|
*(COleDateTime*)pvProp = dt;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE);
|
||
|
return FALSE;
|
||
|
|
||
|
case VT_LPSTR:
|
||
|
case VT_EX_SIZE:
|
||
|
case VT_EX_RECT:
|
||
|
{
|
||
|
if (vtProp == VT_EX_SIZE)
|
||
|
{
|
||
|
SIZE sz = {0, 0};
|
||
|
if (SCANF_S(strValue, _T("%i, %i"), &sz.cx, &sz.cy) != 2)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
*((LPSIZE)pvProp) = sz;
|
||
|
}
|
||
|
else if (vtProp == VT_EX_RECT)
|
||
|
{
|
||
|
RECT rc = {0, 0, 0, 0};
|
||
|
if (SCANF_S(strValue, _T("%i, %i, %i, %i"), &rc.left, &rc.top, &rc.right, &rc.bottom) != 4)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
*((LPRECT)pvProp) = rc;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PreformatString(strValue);
|
||
|
*(CString*)pvProp = strValue;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
case VT_VARIANT:
|
||
|
{
|
||
|
COleVariant varValue(strValue);
|
||
|
if (m_lcidDateTime == XTP_LOCALE_ISO8601)
|
||
|
{
|
||
|
COleDateTime dt;
|
||
|
if (ParseDateTimeISO8601(dt, strValue))
|
||
|
{
|
||
|
varValue = dt;
|
||
|
}
|
||
|
}
|
||
|
return CopyPropValue(vtProp, pvProp, &varValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_BOOL:
|
||
|
{
|
||
|
int nValue = 0;
|
||
|
memcpy(&nValue, pvProp, GetSizeOfVarType(vtProp));
|
||
|
|
||
|
strValue.Format(_T("%i"), nValue);
|
||
|
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE);
|
||
|
return FALSE;
|
||
|
|
||
|
case VT_LPSTR:
|
||
|
{
|
||
|
strValue = *(CString*)pvProp;
|
||
|
PreformatString(strValue);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_DATE:
|
||
|
{
|
||
|
COleDateTime& dt = *(COleDateTime*)pvProp;
|
||
|
ExchangePropDateHelper(strValue, dt);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_R4:
|
||
|
{
|
||
|
double d = (double) *(float*)pvProp;
|
||
|
strValue.Format(_T("%g"), d);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
case VT_R8:
|
||
|
|
||
|
strValue.Format(_T("%g"), *(double*)pvProp);
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_EX_SIZE:
|
||
|
{
|
||
|
strValue.Format(_T("%i, %i"), ((LPSIZE)pvProp)->cx, ((LPSIZE)pvProp)->cy);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_EX_RECT:
|
||
|
{
|
||
|
strValue.Format(_T("%i, %i, %i, %i"), ((LPRECT)pvProp)->left, ((LPRECT)pvProp)->top, ((LPRECT)pvProp)->right, ((LPRECT)pvProp)->bottom);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case VT_VARIANT:
|
||
|
|
||
|
LCID lcidID = m_lcidDateTime;
|
||
|
COleVariant& varProp = *((COleVariant*)pvProp);
|
||
|
|
||
|
if (lcidID == XTP_LOCALE_ISO8601 && varProp.vt == VT_DATE)
|
||
|
{
|
||
|
strValue = FormatDateTimeISO8601(varProp.date);
|
||
|
return TRUE;
|
||
|
}
|
||
|
if (lcidID == XTP_LOCALE_ISO8601)
|
||
|
{
|
||
|
lcidID = LOCALE_NEUTRAL;
|
||
|
}
|
||
|
COleVariant var;
|
||
|
HRESULT hr = VariantChangeTypeEx(&var, &varProp, lcidID, 0, VT_BSTR);
|
||
|
|
||
|
if (FAILED(hr) || var.vt != VT_BSTR)
|
||
|
return FALSE;
|
||
|
|
||
|
strValue = var.bstrVal;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::BinToString(BYTE* pData, DWORD nBytes, CString& str)
|
||
|
{
|
||
|
if (nBytes > 0)
|
||
|
{
|
||
|
LPTSTR lpsz = str.GetBuffer(nBytes * 2);
|
||
|
|
||
|
for (UINT i = 0; i < nBytes; i++)
|
||
|
{
|
||
|
*lpsz++ = (TCHAR)((pData[i] & 0x0F) + 'A'); //low nibble
|
||
|
*lpsz++ = (TCHAR)(((pData[i] >> 4) & 0x0F) + 'A'); //high nibble
|
||
|
}
|
||
|
|
||
|
str.ReleaseBuffer(nBytes * 2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
str.Empty();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchange::StringToBin(const CString& str, BYTE*& pData, DWORD& nBytes)
|
||
|
{
|
||
|
if (str.GetLength() > 0)
|
||
|
{
|
||
|
int nLen = str.GetLength();
|
||
|
if ((nLen == 0) || (nLen % 2 != 0))
|
||
|
return FALSE;
|
||
|
|
||
|
DWORD nCount = nLen/2;
|
||
|
if (pData == NULL)
|
||
|
{
|
||
|
pData = (BYTE*)malloc(nCount);
|
||
|
nBytes = nCount;
|
||
|
}
|
||
|
if (pData == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
if (nBytes < nCount)
|
||
|
return FALSE;
|
||
|
|
||
|
for (int i = 0; i < nLen; i += 2)
|
||
|
{
|
||
|
(pData)[i/2] = (BYTE)
|
||
|
(((str[i + 1] - 'A') << 4) + (str[i] - 'A'));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nBytes = 0;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchange::ExchangeBlobProp(LPCTSTR pszPropName, BYTE*& pData, DWORD& nBytes)
|
||
|
{
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
CString str;
|
||
|
BinToString(pData, nBytes, str);
|
||
|
|
||
|
PX_String(this, pszPropName, str, _T(""));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CString str;
|
||
|
if (!PX_String(this, pszPropName, str))
|
||
|
return FALSE;
|
||
|
|
||
|
return StringToBin(str, pData, nBytes);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchange::IsSamePropValue(VARTYPE vtProp, const void* pv1, const void* pv2)
|
||
|
{
|
||
|
if (pv1 == pv2)
|
||
|
return TRUE;
|
||
|
|
||
|
if ((pv1 == NULL) || (pv2 == NULL))
|
||
|
return FALSE;
|
||
|
|
||
|
BOOL bSame = FALSE;
|
||
|
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_BSTR:
|
||
|
bSame = wcscmp(*(BSTR*)pv1, (BSTR)pv2) == 0;
|
||
|
break;
|
||
|
|
||
|
case VT_LPSTR:
|
||
|
bSame = ((CString*)pv1)->Compare((LPCTSTR)pv2) == 0;
|
||
|
break;
|
||
|
|
||
|
case VT_BOOL:
|
||
|
case VT_UI1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_CY:
|
||
|
case VT_R4:
|
||
|
case VT_R8:
|
||
|
case VT_EX_RECT:
|
||
|
case VT_EX_SIZE:
|
||
|
bSame = memcmp(pv1, pv2, GetSizeOfVarType(vtProp)) == 0;
|
||
|
break;
|
||
|
|
||
|
case VT_VARIANT:
|
||
|
bSame = *((COleVariant*)pv1) == *((COleVariant*)pv2);
|
||
|
break;
|
||
|
|
||
|
case VT_DATE:
|
||
|
bSame = *((COleDateTime*)pv1) == *((COleDateTime*)pv2);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return bSame;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchange::CopyPropValue(VARTYPE vtProp, void* pvDest, const void* pvSrc)
|
||
|
{
|
||
|
ASSERT(AfxIsValidAddress(pvDest, 1));
|
||
|
|
||
|
if (pvSrc != NULL)
|
||
|
{
|
||
|
ASSERT(AfxIsValidAddress(pvSrc, 1, FALSE));
|
||
|
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
*(BYTE*)pvDest = *(BYTE*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
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:
|
||
|
*(BSTR*)pvDest = SysAllocString((BSTR)pvSrc);
|
||
|
break;
|
||
|
|
||
|
case VT_LPSTR:
|
||
|
*(CString*)pvDest = (LPCTSTR)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_CY:
|
||
|
*(CY*)pvDest = *(CY*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_R4:
|
||
|
*(float*)pvDest = *(float*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_R8:
|
||
|
*(double*)pvDest = *(double*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_EX_RECT:
|
||
|
*(RECT*)pvDest = *(RECT*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_EX_SIZE:
|
||
|
*(SIZE*)pvDest = *(SIZE*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_DATE:
|
||
|
*(COleDateTime*)pvDest = *(COleDateTime*)pvSrc;
|
||
|
break;
|
||
|
|
||
|
case VT_VARIANT:
|
||
|
TRY
|
||
|
{
|
||
|
*(COleVariant*)pvDest = *(COleVariant*)pvSrc;
|
||
|
}
|
||
|
CATCH_ALL(e)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
END_CATCH_ALL
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return pvSrc != NULL;
|
||
|
}
|
||
|
|
||
|
CRuntimeClass* CXTPPropExchange::FindRuntimeClass(LPCSTR szClassName)
|
||
|
{
|
||
|
|
||
|
CRuntimeClass* pClass;
|
||
|
// search app specific classes
|
||
|
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
|
||
|
|
||
|
for (pClass = pModuleState->m_classList; pClass != NULL;
|
||
|
pClass = pClass->m_pNextClass)
|
||
|
{
|
||
|
if (lstrcmpA(szClassName, pClass->m_lpszClassName) == 0)
|
||
|
{
|
||
|
return pClass;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef _AFXDLL
|
||
|
// search classes in shared DLLs
|
||
|
for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
|
||
|
pDLL = pDLL->m_pNextDLL)
|
||
|
{
|
||
|
for (pClass = pDLL->m_classList; pClass != NULL;
|
||
|
pClass = pClass->m_pNextClass)
|
||
|
{
|
||
|
if (lstrcmpA(szClassName, pClass->m_lpszClassName) == 0)
|
||
|
{
|
||
|
return pClass;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
ASSERT(FALSE);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchange::ExchangeRuntimeClass(LPCTSTR pszPropName, CRuntimeClass*& pClass, CRuntimeClass* pDefaultClass)
|
||
|
{
|
||
|
CString strClassName;
|
||
|
|
||
|
if (!IsLoading())
|
||
|
{
|
||
|
strClassName = CString(pClass->m_lpszClassName);
|
||
|
PX_String(this, pszPropName, strClassName, CString(pDefaultClass->m_lpszClassName));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!PX_String(this, pszPropName, strClassName))
|
||
|
{
|
||
|
pClass = pDefaultClass;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
pClass = FindRuntimeClass(XTP_CT2CA(strClassName));
|
||
|
if (!pClass)
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchange::ExchangeObjectInstance(CObject*& pObject, CRuntimeClass* pObjectRuntime)
|
||
|
{
|
||
|
if (!IsLoading())
|
||
|
{
|
||
|
CRuntimeClass* pClass = pObject->GetRuntimeClass();
|
||
|
PX_RuntimeClass(this, _T("Class"), pClass, pObjectRuntime);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CRuntimeClass* pClass = NULL;
|
||
|
PX_RuntimeClass(this, _T("Class"), pClass, pObjectRuntime);
|
||
|
if (!pClass)
|
||
|
return FALSE;
|
||
|
|
||
|
pObject = (CObject*)AfxDynamicDownCast(pObjectRuntime, pClass->CreateObject());
|
||
|
if (!pObject)
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
void CXTPPropExchange::WriteCount (DWORD dwCount)
|
||
|
{
|
||
|
PX_DWord(this, _T("Count"), dwCount, 0);
|
||
|
}
|
||
|
|
||
|
DWORD CXTPPropExchange::ReadCount()
|
||
|
{
|
||
|
DWORD nCount = 0;
|
||
|
PX_DWord(this, _T("Count"), nCount, 0);
|
||
|
return nCount;
|
||
|
}
|
||
|
|
||
|
CArchive* CXTPPropExchange::GetArchive(LPCTSTR pszPropName)
|
||
|
{
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
|
||
|
CMemFile* pMemFile = new CMemFile();
|
||
|
CArchive* pArchive = new CArchive(pMemFile, CArchive::store);
|
||
|
|
||
|
return pArchive;
|
||
|
}
|
||
|
|
||
|
DWORD nBytes = 0;
|
||
|
BYTE* pData = NULL;
|
||
|
PX_Blob(this, pszPropName, pData, nBytes);
|
||
|
|
||
|
if (nBytes == 0)
|
||
|
return NULL;
|
||
|
|
||
|
CMemFile* pMemFile = new CMemFile(pData, nBytes);
|
||
|
CArchive* pArchive = new CArchive(pMemFile, CArchive::load);
|
||
|
|
||
|
return pArchive;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::ReleaseArchive(LPCTSTR pszPropName, CArchive* pArchive)
|
||
|
{
|
||
|
ASSERT(pArchive);
|
||
|
if (!pArchive)
|
||
|
return;
|
||
|
|
||
|
CMemFile* pFile = DYNAMIC_DOWNCAST(CMemFile, pArchive->GetFile());
|
||
|
ASSERT(pFile);
|
||
|
if (!pFile)
|
||
|
return;
|
||
|
|
||
|
BYTE* pData = NULL;
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
pArchive->Flush();
|
||
|
|
||
|
DWORD nBytes = (DWORD)pFile->GetPosition();
|
||
|
pData = pFile->Detach();
|
||
|
PX_Blob(this, pszPropName, pData, nBytes);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pData = pFile->Detach();
|
||
|
}
|
||
|
|
||
|
pArchive->Abort();
|
||
|
pFile->Close();
|
||
|
free(pData);
|
||
|
|
||
|
delete pFile;
|
||
|
delete pArchive;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::ExchangeSchema()
|
||
|
{
|
||
|
PX_Long(this, _T("Schema"), (long&)m_nSchema, _XTP_SCHEMA_CURRENT);
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::ExchangeSchemaSafe()
|
||
|
{
|
||
|
PX_Long(this, _T("Schema"), (long&)m_nSchema, _XTP_SCHEMA_1122);
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchange::ExchangeLocale()
|
||
|
{
|
||
|
PX_DWord(this, _T("Locale"), (DWORD&)CXTPPropExchange::m_lcidDateTime, XTP_LOCALE_ISO8601);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
CXTPPropExchangeEnumerator* CXTPPropExchange::GetEnumerator(LPCTSTR lpszSection)
|
||
|
{
|
||
|
return new CXTPPropExchangeEnumerator(this, lpszSection);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPPropExchangeArchive
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CXTPPropExchangeArchive, CXTPPropExchange)
|
||
|
|
||
|
CXTPPropExchangeArchive::CXTPPropExchangeArchive(CArchive& ar) :
|
||
|
m_ar((CSelfArchive&)ar)
|
||
|
{
|
||
|
ASSERT_POINTER(&ar, CArchive);
|
||
|
m_bLoading = m_ar.IsLoading();
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* CXTPPropExchangeArchive::GetSection(LPCTSTR /*pszSection*/)
|
||
|
{
|
||
|
CXTPPropExchangeArchive* pSection = new CXTPPropExchangeArchive(m_ar);
|
||
|
pSection->InitSection(this);
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchangeArchive::ExchangeRuntimeClass(LPCTSTR /*pszPropName*/, CRuntimeClass*& pClass, CRuntimeClass* pDefaultClass)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (!IsLoading())
|
||
|
{
|
||
|
m_ar.WriteClass(pClass);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pClass = m_ar.ReadClass(pDefaultClass, &m_nSchema);
|
||
|
|
||
|
if (!pClass)
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeArchive::ExchangeObjectInstance(CObject*& pObject, CRuntimeClass* pObjectRuntime)
|
||
|
{
|
||
|
if (!CXTPPropExchange::ExchangeObjectInstance(pObject, pObjectRuntime))
|
||
|
return FALSE;
|
||
|
|
||
|
if (IsLoading())
|
||
|
{
|
||
|
m_ar.CheckCount();
|
||
|
m_ar.m_pLoadArray->InsertAt(m_ar.m_nMapCount++, pObject);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ar.MapObject(NULL);
|
||
|
m_ar.CheckCount();
|
||
|
m_ar.m_pStoreMap->SetAt(pObject, (LPVOID)(DWORD_PTR)m_ar.m_nMapCount++);
|
||
|
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeArchive::ExchangeProp(LPCTSTR /*pszPropName*/, VARTYPE vtProp,
|
||
|
void* pvProp, const void* pvDefault)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
UNUSED(pvDefault); // unused in release builds
|
||
|
|
||
|
ASSERT(AfxIsValidAddress(pvProp, 1, FALSE));
|
||
|
ASSERT((pvDefault == NULL) || AfxIsValidAddress(pvDefault, 1, FALSE));
|
||
|
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
m_ar >> *(BYTE*)pvProp;
|
||
|
break;
|
||
|
case VT_I2:
|
||
|
m_ar >> *(WORD*)pvProp;
|
||
|
break;
|
||
|
case VT_I4:
|
||
|
m_ar >> *(long*)pvProp;
|
||
|
break;
|
||
|
case VT_BOOL:
|
||
|
m_ar >> *(BOOL*)pvProp;
|
||
|
break;
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE);
|
||
|
break;
|
||
|
case VT_LPSTR:
|
||
|
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;
|
||
|
case VT_EX_RECT:
|
||
|
m_ar >> *(RECT*)pvProp;
|
||
|
break;
|
||
|
case VT_EX_SIZE:
|
||
|
m_ar >> *(SIZE*)pvProp;
|
||
|
break;
|
||
|
case VT_VARIANT:
|
||
|
m_ar >> *(COleVariant*)pvProp;
|
||
|
break;
|
||
|
case VT_DATE:
|
||
|
m_ar >> *(COleDateTime*)pvProp;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
m_ar << *(BYTE*)pvProp;
|
||
|
break;
|
||
|
case VT_I2:
|
||
|
m_ar << *(WORD*)pvProp;
|
||
|
break;
|
||
|
case VT_I4:
|
||
|
m_ar << *(long*)pvProp;
|
||
|
break;
|
||
|
case VT_BOOL:
|
||
|
m_ar << *(BOOL*)pvProp;
|
||
|
break;
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE);
|
||
|
break;
|
||
|
case VT_LPSTR:
|
||
|
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;
|
||
|
case VT_EX_RECT:
|
||
|
m_ar << *(RECT*)pvProp;
|
||
|
break;
|
||
|
case VT_EX_SIZE:
|
||
|
m_ar << *(SIZE*)pvProp;
|
||
|
break;
|
||
|
case VT_VARIANT:
|
||
|
m_ar << *(COleVariant*)pvProp;
|
||
|
break;
|
||
|
case VT_DATE:
|
||
|
m_ar << *(COleDateTime*)pvProp;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeArchive::WriteCount (DWORD dwCount)
|
||
|
{
|
||
|
m_ar.WriteCount(dwCount);
|
||
|
}
|
||
|
DWORD CXTPPropExchangeArchive::ReadCount()
|
||
|
{
|
||
|
return (DWORD)m_ar.ReadCount();
|
||
|
}
|
||
|
void CXTPPropExchangeArchive::Write (LPCTSTR /*pszPropName*/, const void* lpBuf, UINT nCount)
|
||
|
{
|
||
|
ASSERT(lpBuf);
|
||
|
m_ar.Write(lpBuf, nCount);
|
||
|
}
|
||
|
|
||
|
UINT CXTPPropExchangeArchive::Read (LPCTSTR /*pszPropName*/, void* lpBuf, UINT nCount)
|
||
|
{
|
||
|
ASSERT(lpBuf);
|
||
|
return m_ar.Read(lpBuf, nCount);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeArchive::ExchangeBlobProp(LPCTSTR /*pszPropName*/, BYTE*& pData, DWORD& nBytes)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
WriteCount(nBytes);
|
||
|
m_ar.Write(pData, nBytes);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DWORD nCount = ReadCount();
|
||
|
|
||
|
if (pData == NULL)
|
||
|
{
|
||
|
pData = (BYTE*)malloc(nCount);
|
||
|
nBytes = nCount;
|
||
|
}
|
||
|
|
||
|
if (nBytes < nCount)
|
||
|
return FALSE;
|
||
|
|
||
|
return m_ar.Read(pData, nCount) == nCount;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CArchive* CXTPPropExchangeArchive::GetArchive(LPCTSTR /*pszPropName*/)
|
||
|
{
|
||
|
return &m_ar;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeArchive::ReleaseArchive(LPCTSTR /*pszPropName*/, CArchive* /*pArchive*/)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeArchive::ExchangeSchemaSafe()
|
||
|
{
|
||
|
DWORD dwSafe = 0xFF0ADBF;
|
||
|
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
m_ar << dwSafe;
|
||
|
m_ar << m_nSchema;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_ar.m_lpBufCur + sizeof(DWORD) > m_ar.m_lpBufMax)
|
||
|
m_ar.FillBuffer(sizeof(DWORD));
|
||
|
|
||
|
DWORD dw = *(DWORD*)m_ar.m_lpBufCur;
|
||
|
|
||
|
if (dw == dwSafe)
|
||
|
{
|
||
|
m_ar >> dwSafe;
|
||
|
m_ar >> m_nSchema;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_nSchema = _XTP_SCHEMA_100;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPPropExchangeRegistry
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CXTPPropExchangeRegistry, CXTPPropExchange)
|
||
|
|
||
|
CXTPPropExchangeRegistry::CXTPPropExchangeRegistry(BOOL bLoading, HKEY hParentKey, LPCTSTR lpszSection)
|
||
|
{
|
||
|
ASSERT(lpszSection != NULL);
|
||
|
if (hParentKey == 0)
|
||
|
{
|
||
|
m_hParentKey = AfxGetApp()->GetAppRegistryKey();
|
||
|
m_bCloseParentKey = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_hParentKey = hParentKey;
|
||
|
m_bCloseParentKey = FALSE;
|
||
|
}
|
||
|
|
||
|
m_bLoading = bLoading;
|
||
|
m_strSectionName = lpszSection;
|
||
|
m_hSectionKey = NULL;
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeRegistry::~CXTPPropExchangeRegistry()
|
||
|
{
|
||
|
if (m_hSectionKey)
|
||
|
{
|
||
|
RegCloseKey(m_hSectionKey);
|
||
|
}
|
||
|
if (m_bCloseParentKey && m_hParentKey)
|
||
|
{
|
||
|
RegCloseKey(m_hParentKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* CXTPPropExchangeRegistry::GetSection(LPCTSTR lpszSection)
|
||
|
{
|
||
|
OnBeforeExchange();
|
||
|
|
||
|
CXTPPropExchangeRegistry* pSection = new CXTPPropExchangeRegistry(IsLoading(), m_hSectionKey, lpszSection);
|
||
|
pSection->InitSection(this);
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeRegistry::IsPropertyExists(LPCTSTR pszPropName)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
return RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeRegistry::IsSectionExists(LPCTSTR lpszSection)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
HKEY hSectionKey = 0;
|
||
|
|
||
|
if (RegOpenKeyEx(m_hSectionKey, lpszSection, 0, m_bLoading ? KEY_READ : KEY_WRITE, &hSectionKey) == ERROR_SUCCESS)
|
||
|
{
|
||
|
RegCloseKey(hSectionKey);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchangeRegistry::OnBeforeExchange()
|
||
|
{
|
||
|
if (m_hParentKey == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
if (!m_bInitialized)
|
||
|
{
|
||
|
ASSERT(m_hSectionKey == 0);
|
||
|
|
||
|
VERIFY(RegCreateKeyEx(m_hParentKey, m_strSectionName, 0, REG_NONE, REG_OPTION_NON_VOLATILE, m_bLoading ? KEY_READ : KEY_WRITE, NULL, &m_hSectionKey, NULL) == ERROR_SUCCESS);
|
||
|
|
||
|
m_bInitialized = TRUE;
|
||
|
}
|
||
|
return m_hSectionKey != NULL;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeRegistry::EmptySection()
|
||
|
{
|
||
|
CXTPPropExchange::EmptySection();
|
||
|
|
||
|
if (m_hSectionKey)
|
||
|
{
|
||
|
RegCloseKey(m_hSectionKey);
|
||
|
m_hSectionKey = 0;
|
||
|
}
|
||
|
|
||
|
AfxDelRegTreeHelper(m_hParentKey, m_strSectionName);
|
||
|
m_bInitialized = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchangeRegistry::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
||
|
void* pvProp, const void* pvDefault /*= NULL*/)
|
||
|
{
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
if (!m_bUseDefaultOnLoad)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
ASSERT(m_hSectionKey);
|
||
|
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_R4:
|
||
|
case VT_R8:
|
||
|
case VT_DATE:
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE); // Not Implemented
|
||
|
return FALSE;
|
||
|
|
||
|
case VT_VARIANT:
|
||
|
return FALSE; // Not Implemented
|
||
|
|
||
|
case VT_UI1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_BOOL:
|
||
|
{
|
||
|
|
||
|
DWORD dwValue;
|
||
|
DWORD dwType;
|
||
|
DWORD dwCount = sizeof(DWORD);
|
||
|
LONG lResult = RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, &dwType,
|
||
|
(LPBYTE)&dwValue, &dwCount);
|
||
|
|
||
|
if (lResult == ERROR_SUCCESS)
|
||
|
{
|
||
|
ASSERT(dwType == REG_DWORD);
|
||
|
ASSERT(dwCount == sizeof(DWORD));
|
||
|
|
||
|
return CopyPropValue(vtProp, pvProp, &dwValue);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
}
|
||
|
}
|
||
|
case VT_LPSTR:
|
||
|
case VT_EX_SIZE:
|
||
|
case VT_EX_RECT:
|
||
|
{
|
||
|
CString strValue;
|
||
|
DWORD dwType, dwCount;
|
||
|
LONG lResult = RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, &dwType,
|
||
|
NULL, &dwCount);
|
||
|
if (lResult == ERROR_SUCCESS)
|
||
|
{
|
||
|
ASSERT(dwType == REG_SZ);
|
||
|
lResult = RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, &dwType,
|
||
|
(LPBYTE)strValue.GetBuffer(dwCount/sizeof(TCHAR)), &dwCount);
|
||
|
strValue.ReleaseBuffer();
|
||
|
}
|
||
|
if (lResult == ERROR_SUCCESS)
|
||
|
{
|
||
|
ASSERT(dwType == REG_SZ);
|
||
|
|
||
|
if (vtProp == VT_EX_SIZE)
|
||
|
{
|
||
|
SIZE sz = {0, 0};
|
||
|
if (SCANF_S(strValue, _T("%i, %i"), &sz.cx, &sz.cy) != 2)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
*((LPSIZE)pvProp) = sz;
|
||
|
}
|
||
|
else if (vtProp == VT_EX_RECT)
|
||
|
{
|
||
|
RECT rc = {0, 0, 0, 0};
|
||
|
if (SCANF_S(strValue, _T("%i, %i, %i, %i"), &rc.left, &rc.top, &rc.right, &rc.bottom) != 4)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
*((LPRECT)pvProp) = rc;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*(CString*)pvProp = strValue;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!m_bUseDefaultOnSave)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (IsSamePropValue(vtProp, pvProp, pvDefault))
|
||
|
{
|
||
|
if (m_hSectionKey && !m_bEmptySection)
|
||
|
RegDeleteValue(m_hSectionKey, pszPropName);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
LONG lResult = -1;
|
||
|
|
||
|
switch (vtProp)
|
||
|
{
|
||
|
case VT_UI1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_BOOL:
|
||
|
{
|
||
|
DWORD dwValue = 0;
|
||
|
CopyPropValue(vtProp, &dwValue, pvProp);
|
||
|
lResult = RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case VT_LPSTR:
|
||
|
{
|
||
|
CString& strValue = *(CString*)pvProp;
|
||
|
lResult = RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_SZ,
|
||
|
(LPBYTE)(LPCTSTR)strValue, (strValue.GetLength() + 1) * sizeof(TCHAR));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case VT_R4:
|
||
|
case VT_R8:
|
||
|
lResult = RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_BINARY, (LPBYTE)pvProp, GetSizeOfVarType(vtProp));
|
||
|
break;
|
||
|
|
||
|
case VT_DATE:
|
||
|
case VT_VARIANT:
|
||
|
case VT_BSTR:
|
||
|
ASSERT(FALSE); // Not Implemented
|
||
|
break;
|
||
|
|
||
|
case VT_EX_SIZE:
|
||
|
{
|
||
|
CString strValue;
|
||
|
strValue.Format(_T("%i, %i"), ((LPSIZE)pvProp)->cx, ((LPSIZE)pvProp)->cy);
|
||
|
lResult = RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_SZ,
|
||
|
(LPBYTE)(LPCTSTR)strValue, (strValue.GetLength() + 1) * sizeof(TCHAR));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case VT_EX_RECT:
|
||
|
CString strValue;
|
||
|
strValue.Format(_T("%i, %i, %i, %i"), ((LPRECT)pvProp)->left, ((LPRECT)pvProp)->top, ((LPRECT)pvProp)->right, ((LPRECT)pvProp)->bottom);
|
||
|
lResult = RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_SZ,
|
||
|
(LPBYTE)(LPCTSTR)strValue, (strValue.GetLength() + 1) * sizeof(TCHAR));
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return lResult == ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeRegistry::ExchangeBlobProp(LPCTSTR pszPropName, BYTE*& pData, DWORD& nBytes)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(m_hSectionKey != 0);
|
||
|
|
||
|
if (IsStoring())
|
||
|
{
|
||
|
LONG lResult = ::RegSetValueEx(m_hSectionKey, pszPropName, NULL, REG_BINARY,
|
||
|
pData, nBytes);
|
||
|
return lResult == ERROR_SUCCESS;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DWORD dwType, dwCount;
|
||
|
LONG lResult = RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, &dwType,
|
||
|
NULL, &dwCount);
|
||
|
|
||
|
if (lResult != ERROR_SUCCESS)
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(dwType == REG_BINARY);
|
||
|
|
||
|
|
||
|
if (pData == NULL)
|
||
|
{
|
||
|
pData = (BYTE*)malloc(dwCount);
|
||
|
nBytes = dwCount;
|
||
|
}
|
||
|
|
||
|
if (nBytes < dwCount)
|
||
|
return FALSE;
|
||
|
|
||
|
lResult = RegQueryValueEx(m_hSectionKey, (LPTSTR)pszPropName, NULL, &dwType,
|
||
|
(LPBYTE)pData, &dwCount);
|
||
|
|
||
|
if (lResult != ERROR_SUCCESS)
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPPropExchangeXMLNode
|
||
|
|
||
|
#ifndef _XTP_EXCLUDE_XML
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CXTPPropExchangeXMLNode, CXTPPropExchange)
|
||
|
|
||
|
CXTPPropExchangeXMLNode::CXTPPropExchangeXMLNode(BOOL bLoading, CXTPDOMNodePtr xmlParentNode, LPCTSTR lpszSection)
|
||
|
{
|
||
|
m_bLoading = bLoading;
|
||
|
m_strSectionName = lpszSection;
|
||
|
m_xmlParentNode = xmlParentNode;
|
||
|
m_xmlSectionNode = NULL;
|
||
|
m_bCompactMode = TRUE;
|
||
|
|
||
|
if (xmlParentNode)
|
||
|
{
|
||
|
xmlParentNode->get_ownerDocument(&m_xmlDocPtr);
|
||
|
|
||
|
if (m_xmlDocPtr == 0)
|
||
|
{
|
||
|
m_xmlDocPtr = xmlParentNode;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_strEncoding = _T("UTF-8");
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::IsXMLSupported()
|
||
|
{
|
||
|
CXTPDOMDocumentPtr xmlDocPtr;
|
||
|
|
||
|
if (!SUCCEEDED(xmlDocPtr.CreateInstance(CLSID_XTPDOMDocument)))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::CreateDocumentInstance()
|
||
|
{
|
||
|
if (m_xmlDocPtr == NULL)
|
||
|
{
|
||
|
if (!SUCCEEDED(m_xmlDocPtr.CreateInstance(CLSID_XTPDOMDocument)))
|
||
|
{
|
||
|
TRACE(_T("Warning: CreateDocumentInstance failed in CXTPPropExchangeXMLNode --\n"));
|
||
|
TRACE(_T("\tperhaps AfxOleInit() has not been called, or msxml3.dll not found."));
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
m_xmlDocPtr->put_preserveWhiteSpace(VARIANT_TRUE);
|
||
|
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::TraceParseError()
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
XTPXML::IXMLDOMParseErrorPtr parseError = 0;
|
||
|
if (FAILED(m_xmlDocPtr->get_parseError(&parseError)))
|
||
|
return;
|
||
|
|
||
|
BSTR bstrReason = 0;
|
||
|
if (FAILED(parseError->get_reason(&bstrReason)))
|
||
|
return;
|
||
|
|
||
|
CString strReason(bstrReason);
|
||
|
TRACE(_T("Warning: CXTPPropExchangeXMLNode::LoadFromString failed. ParseError.Reason = %s"), (LPCTSTR)strReason);
|
||
|
|
||
|
SysFreeString(bstrReason);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromEncodedString(LPCWSTR lpszState)
|
||
|
{
|
||
|
return LoadFromEncodedString(XTP_CW2CA(lpszState));
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromEncodedString(LPCSTR lpszState)
|
||
|
{
|
||
|
if (!lpszState)
|
||
|
return FALSE;
|
||
|
|
||
|
if (!CreateDocumentInstance())
|
||
|
return FALSE;
|
||
|
|
||
|
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
VARIANT_BOOL bResult;
|
||
|
|
||
|
VARIANT va;
|
||
|
va.vt = VT_ARRAY | VT_UI1;
|
||
|
|
||
|
ULONG nLen = (ULONG)strlen(lpszState);
|
||
|
va.parray = SafeArrayCreateVector(VT_UI1, 0, nLen);
|
||
|
MEMCPY_S(va.parray->pvData, lpszState, nLen);
|
||
|
|
||
|
HRESULT hr = m_xmlDocPtr->load(va, &bResult);
|
||
|
VariantClear(&va);
|
||
|
|
||
|
if (FAILED(hr) || bResult == VARIANT_FALSE)
|
||
|
{
|
||
|
TraceParseError();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
m_xmlParentNode = m_xmlDocPtr;
|
||
|
m_xmlSectionNode = NULL;
|
||
|
m_bInitialized = FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromString(LPCSTR lpszState)
|
||
|
{
|
||
|
return LoadFromString((BSTR)XTP_CA2CW(lpszState));
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromString(LPCWSTR lpszState)
|
||
|
{
|
||
|
return LoadFromString((BSTR)(lpszState));
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromString(BSTR lpszState)
|
||
|
{
|
||
|
if (!CreateDocumentInstance())
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
VARIANT_BOOL bResult;
|
||
|
HRESULT hr = m_xmlDocPtr->loadXML(lpszState, &bResult);
|
||
|
if (FAILED(hr) || bResult == VARIANT_FALSE)
|
||
|
{
|
||
|
TraceParseError();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
m_xmlParentNode = m_xmlDocPtr;
|
||
|
m_xmlSectionNode = NULL;
|
||
|
m_bInitialized = FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromResource(HINSTANCE hInstance, LPCTSTR lpszResourceName, LPCTSTR lpszResourceType)
|
||
|
{
|
||
|
HRSRC hRsrc = ::FindResource(hInstance, lpszResourceName, lpszResourceType);
|
||
|
if (hRsrc == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
HGLOBAL hGlobal = LoadResource(hInstance, hRsrc);
|
||
|
if (hGlobal == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
LPCSTR pData = (LPCSTR)LockResource(hGlobal);
|
||
|
if (pData == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
DWORD dwSize = (DWORD)SizeofResource(hInstance, hRsrc);
|
||
|
if (dwSize == 0)
|
||
|
return FALSE;
|
||
|
|
||
|
LPSTR lpstr = (LPSTR)malloc(dwSize + 1);
|
||
|
if (!lpstr)
|
||
|
return FALSE;
|
||
|
|
||
|
MEMCPY_S(lpstr, pData, dwSize);
|
||
|
lpstr[dwSize] = 0;
|
||
|
|
||
|
BOOL bResult = LoadFromEncodedString(lpstr);
|
||
|
|
||
|
UnlockResource(hGlobal);
|
||
|
FreeResource(hGlobal);
|
||
|
|
||
|
free(lpstr);
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::LoadFromFile(LPCTSTR strFileName)
|
||
|
{
|
||
|
if (!FILEEXISTS_S(strFileName))
|
||
|
return FALSE;
|
||
|
|
||
|
if (!CreateDocumentInstance())
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
VARIANT_BOOL bResult;
|
||
|
HRESULT hr = m_xmlDocPtr->load(COleVariant(strFileName), &bResult);
|
||
|
if (FAILED(hr) || bResult == VARIANT_FALSE)
|
||
|
{
|
||
|
TraceParseError();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
m_xmlParentNode = m_xmlDocPtr;
|
||
|
m_xmlSectionNode = NULL;
|
||
|
m_bInitialized = FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::FormatString(CString& str)
|
||
|
{
|
||
|
const LPCTSTR lpszCrLf = _T("\r\n");
|
||
|
|
||
|
#define ADDINDENT(str, i, strOffset)\
|
||
|
str.Insert(i, lpszCrLf);\
|
||
|
str.Insert(i + 2, strOffset);\
|
||
|
i += strOffset.GetLength() + 2;
|
||
|
|
||
|
|
||
|
CString strOffset(_T('\t'));
|
||
|
|
||
|
for (int i = 1; i < str.GetLength(); i++)
|
||
|
{
|
||
|
if (((str[i] == _T('>')) && (str[i - 1] == _T('/'))) || ((str[i] == _T('<')) && (str[i + 1] == _T('/'))))
|
||
|
{
|
||
|
strOffset.Delete(strOffset.GetLength() - 1);
|
||
|
if (str[i] == _T('<') && str[i - 1] == _T('>'))
|
||
|
{
|
||
|
ADDINDENT(str, i, strOffset);
|
||
|
}
|
||
|
}
|
||
|
else if (str[i] == _T('<'))
|
||
|
{
|
||
|
ADDINDENT(str, i, strOffset);
|
||
|
strOffset += _T('\t');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
CString CXTPPropExchangeXMLNode::GetEncodedXML(BOOL bFormatted)
|
||
|
{
|
||
|
CString str;
|
||
|
if (!OnBeforeExchange())
|
||
|
return str;
|
||
|
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
if (IsRootSection())
|
||
|
{
|
||
|
UpdateDocumentEncoding();
|
||
|
|
||
|
COleStreamFile stream;
|
||
|
if(!stream.CreateMemoryStream())
|
||
|
return str;
|
||
|
|
||
|
VARIANT var;
|
||
|
var.vt = VT_UNKNOWN;
|
||
|
var.punkVal = stream.GetStream();
|
||
|
|
||
|
if (FAILED(m_xmlDocPtr->save(var)))
|
||
|
return str;
|
||
|
|
||
|
stream.SeekToBegin();
|
||
|
DWORD dwLength = (DWORD)stream.GetLength();
|
||
|
|
||
|
char* lpszBuffer = new char[dwLength + 1];
|
||
|
stream.Read(lpszBuffer, dwLength);
|
||
|
|
||
|
if (dwLength > 0 && lpszBuffer[dwLength - 1] <= 13) dwLength--; // Remove /n
|
||
|
if (dwLength > 0 && lpszBuffer[dwLength - 1] <= 13) dwLength--; // Remove /r
|
||
|
|
||
|
lpszBuffer[dwLength] = 0;
|
||
|
|
||
|
str = lpszBuffer;
|
||
|
|
||
|
delete[] lpszBuffer;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(FALSE);
|
||
|
}
|
||
|
|
||
|
if (bFormatted)
|
||
|
{
|
||
|
FormatString(str);
|
||
|
}
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
CString CXTPPropExchangeXMLNode::GetXML(BOOL bFormatted)
|
||
|
{
|
||
|
CString str;
|
||
|
if (!OnBeforeExchange())
|
||
|
return str;
|
||
|
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
BSTR bstrXML = 0;
|
||
|
|
||
|
if (IsRootSection())
|
||
|
{
|
||
|
if (FAILED(m_xmlDocPtr->get_xml(&bstrXML)))
|
||
|
return str;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (FAILED(m_xmlSectionNode->get_xml(&bstrXML)))
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
str = bstrXML;
|
||
|
SysFreeString(bstrXML);
|
||
|
|
||
|
if (bFormatted)
|
||
|
{
|
||
|
FormatString(str);
|
||
|
}
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::FormatFile(LPCTSTR lpszFileName)
|
||
|
{
|
||
|
const LPCSTR lpszCrLf = "\r\n";
|
||
|
const LPCSTR lpszOffset = "\t";
|
||
|
|
||
|
#define WRITEINDENT\
|
||
|
fileBuffer.Write(lpszBegin, int(lpszCurrent - lpszBegin) - nWhiteSpace);\
|
||
|
fileBuffer.Write(lpszCrLf, 2);\
|
||
|
for (int j = 0; j < nOffset; j++) fileBuffer.Write(lpszOffset, 1);\
|
||
|
lpszBegin = lpszCurrent
|
||
|
|
||
|
|
||
|
CFile file;
|
||
|
if (!file.Open(lpszFileName, CFile::modeRead))
|
||
|
return;
|
||
|
|
||
|
DWORD dwLength = (DWORD)file.GetLength();
|
||
|
|
||
|
if (dwLength < 3)
|
||
|
return;
|
||
|
|
||
|
BYTE* lpszBuffer = new BYTE[dwLength + 1];
|
||
|
|
||
|
file.Read(lpszBuffer, dwLength);
|
||
|
lpszBuffer[dwLength] = 0;
|
||
|
file.Close();
|
||
|
|
||
|
if (!file.Open(lpszFileName, CFile::modeWrite | CFile::modeCreate))
|
||
|
{
|
||
|
delete[] lpszBuffer;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CMemFile fileBuffer;
|
||
|
|
||
|
int nOffset = 1, nWhiteSpace = 0;
|
||
|
if (dwLength > 2 && lpszBuffer[dwLength - 2] == '\r')
|
||
|
lpszBuffer[dwLength - 2] = 0;
|
||
|
|
||
|
BYTE *lpszCurrent = lpszBuffer + 1, *lpszBegin = lpszBuffer;
|
||
|
|
||
|
while (*lpszCurrent++)
|
||
|
{
|
||
|
BYTE& chCurrent = *lpszCurrent;
|
||
|
|
||
|
if (((chCurrent == _T('>')) && (*(lpszCurrent - 1) == '/' || *(lpszCurrent - 1) == '?'))
|
||
|
|| ((chCurrent == _T('<')) && (*(lpszCurrent + 1) == '/')))
|
||
|
{
|
||
|
nOffset--;
|
||
|
if (chCurrent == '<' && *(lpszCurrent - 1 - nWhiteSpace) == '>')
|
||
|
{
|
||
|
WRITEINDENT;
|
||
|
}
|
||
|
}
|
||
|
else if (chCurrent == '<')
|
||
|
{
|
||
|
WRITEINDENT;
|
||
|
nOffset++;
|
||
|
}
|
||
|
|
||
|
nWhiteSpace = (chCurrent == '\r' || chCurrent == '\n' || chCurrent == '\t') ? nWhiteSpace + 1 : 0;
|
||
|
}
|
||
|
|
||
|
fileBuffer.Write(lpszBegin, int(lpszCurrent - lpszBegin) - 1);
|
||
|
fileBuffer.Write(lpszCrLf, 2);
|
||
|
|
||
|
delete[] lpszBuffer;
|
||
|
|
||
|
dwLength = (DWORD)fileBuffer.GetLength();
|
||
|
BYTE* lpszFileBuffer = fileBuffer.Detach();
|
||
|
|
||
|
file.Write(lpszFileBuffer, dwLength);
|
||
|
file.Close();
|
||
|
|
||
|
free(lpszFileBuffer);
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::UpdateDocumentEncoding()
|
||
|
{
|
||
|
ASSERT(m_xmlDocPtr != 0);
|
||
|
|
||
|
CString strInstruction = _T("version=\"1.0\" encoding=\"") + m_strEncoding + _T("\"");
|
||
|
|
||
|
BOOL bInstructionExists = FALSE;
|
||
|
|
||
|
CXTPDOMNodePtr ptrBaseInstruction = 0;
|
||
|
if (SUCCEEDED(m_xmlDocPtr->selectSingleNode(L"/node()", &ptrBaseInstruction)) && ptrBaseInstruction != 0)
|
||
|
{
|
||
|
BSTR bstrNodeName = 0;
|
||
|
ptrBaseInstruction->get_nodeName(&bstrNodeName);
|
||
|
|
||
|
if (wcscmp(bstrNodeName, L"xml") == 0)
|
||
|
{
|
||
|
bInstructionExists = TRUE;
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrNodeName);
|
||
|
}
|
||
|
|
||
|
XTPXML::IXMLDOMProcessingInstructionPtr ptrInstruction = 0;
|
||
|
if (!bInstructionExists && SUCCEEDED(m_xmlDocPtr->createProcessingInstruction(L"xml", CT2BSTR(strInstruction), &ptrInstruction)))
|
||
|
{
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
if (SUCCEEDED(m_xmlDocPtr->selectSingleNode(L"/node()", &xmlNodePtr)))
|
||
|
{
|
||
|
m_xmlDocPtr->insertBefore(ptrInstruction, _variant_t(xmlNodePtr.GetInterfacePtr()), 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CXTPPropExchangeXMLNode::SaveToFile(LPCTSTR strFileName, BOOL bFormatted)
|
||
|
{
|
||
|
CString str;
|
||
|
if (!OnBeforeExchange())
|
||
|
return E_FAIL;
|
||
|
|
||
|
UpdateDocumentEncoding();
|
||
|
|
||
|
HRESULT hr = m_xmlDocPtr->save(COleVariant(strFileName));
|
||
|
if (FAILED(hr))
|
||
|
return hr;
|
||
|
|
||
|
if (bFormatted)
|
||
|
{
|
||
|
FormatFile(strFileName);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* CXTPPropExchangeXMLNode::GetSection(LPCTSTR lpszSection)
|
||
|
{
|
||
|
OnBeforeExchange();
|
||
|
|
||
|
CXTPPropExchangeXMLNode* pSection = new CXTPPropExchangeXMLNode(IsLoading(), m_xmlSectionNode, lpszSection);
|
||
|
pSection->m_bCompactMode = m_bCompactMode;
|
||
|
pSection->InitSection(this);
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::OnBeforeExchange()
|
||
|
{
|
||
|
if (!m_bInitialized)
|
||
|
{
|
||
|
m_bInitialized = TRUE;
|
||
|
|
||
|
if (m_xmlDocPtr == NULL && IsRootSection())
|
||
|
{
|
||
|
ASSERT(m_xmlParentNode == 0);
|
||
|
|
||
|
if (!CreateDocumentInstance())
|
||
|
return FALSE;
|
||
|
|
||
|
if (m_xmlDocPtr == 0)
|
||
|
return FALSE;
|
||
|
|
||
|
m_xmlParentNode = m_xmlDocPtr;
|
||
|
ASSERT(m_xmlParentNode != 0);
|
||
|
}
|
||
|
|
||
|
if ((m_xmlDocPtr == NULL) || (m_xmlParentNode == NULL))
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(m_xmlSectionNode == 0);
|
||
|
|
||
|
m_xmlSectionNode = GetProfileNode(m_strSectionName);
|
||
|
|
||
|
if (m_xmlSectionNode != NULL && IsRootSection())
|
||
|
{
|
||
|
PX_Bool(this, _T("CompactMode"), m_bCompactMode, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((m_xmlDocPtr == NULL) || (m_xmlParentNode == NULL))
|
||
|
return FALSE;
|
||
|
|
||
|
return m_xmlSectionNode != NULL;
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::EmptySection()
|
||
|
{
|
||
|
CXTPPropExchange::EmptySection();
|
||
|
|
||
|
OnBeforeExchange();
|
||
|
|
||
|
if (m_xmlSectionNode != 0 && m_xmlParentNode != 0)
|
||
|
{
|
||
|
m_xmlParentNode->removeChild(m_xmlSectionNode, NULL);
|
||
|
m_xmlSectionNode = 0;
|
||
|
m_bInitialized = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::SetCompactMode(BOOL bCompactMode)
|
||
|
{
|
||
|
m_bCompactMode = bCompactMode;
|
||
|
}
|
||
|
|
||
|
|
||
|
CXTPDOMNodePtr CXTPPropExchangeXMLNode::GetProfileNode(LPCTSTR strSection)
|
||
|
{
|
||
|
ASSERT(m_xmlParentNode != 0);
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
CXTPDOMElementPtr xmlElementPtr;
|
||
|
|
||
|
HRESULT hr = m_xmlParentNode->selectSingleNode(CT2BSTR(strSection), &xmlNodePtr);
|
||
|
|
||
|
if (FAILED(hr) || xmlNodePtr == NULL)
|
||
|
{
|
||
|
m_xmlDocPtr->createElement(CT2BSTR(strSection), &xmlElementPtr);
|
||
|
ASSERT(xmlElementPtr != 0);
|
||
|
if (xmlElementPtr)
|
||
|
{
|
||
|
m_xmlParentNode->appendChild(xmlElementPtr, &xmlNodePtr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return xmlNodePtr;
|
||
|
}
|
||
|
|
||
|
CXTPDOMNodePtr CXTPPropExchangeXMLNode::GetEntryNode(LPCTSTR lpszEntry, BOOL bCreate)
|
||
|
{
|
||
|
ASSERT(m_xmlSectionNode != 0);
|
||
|
|
||
|
CXTPDOMNodePtr xmlNodeEntryPtr;
|
||
|
|
||
|
if (lpszEntry == 0 || _tcslen(lpszEntry) == 0)
|
||
|
return m_xmlSectionNode;
|
||
|
|
||
|
if (m_bCompactMode)
|
||
|
{
|
||
|
XTPXML::IXMLDOMNamedNodeMapPtr map;
|
||
|
m_xmlSectionNode->get_attributes(&map);
|
||
|
HRESULT hr = map->getNamedItem(CT2BSTR(lpszEntry), &xmlNodeEntryPtr);
|
||
|
|
||
|
if (FAILED(hr) || xmlNodeEntryPtr == NULL)
|
||
|
{
|
||
|
if (bCreate)
|
||
|
{
|
||
|
XTPXML::IXMLDOMAttributePtr xmlElementPtr;
|
||
|
m_xmlDocPtr->createAttribute(CT2BSTR(lpszEntry), &xmlElementPtr);
|
||
|
if (xmlElementPtr)
|
||
|
{
|
||
|
map->setNamedItem(xmlElementPtr, &xmlNodeEntryPtr);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CXTPDOMNodePtr xmlNodeSectionPtr = m_xmlSectionNode;
|
||
|
|
||
|
HRESULT hr = xmlNodeSectionPtr->selectSingleNode(CT2BSTR(lpszEntry), &xmlNodeEntryPtr);
|
||
|
if (FAILED(hr) || xmlNodeEntryPtr == NULL)
|
||
|
{
|
||
|
if (bCreate)
|
||
|
{
|
||
|
|
||
|
CXTPDOMElementPtr xmlElementPtr;
|
||
|
m_xmlDocPtr->createElement(CT2BSTR(lpszEntry), &xmlElementPtr);
|
||
|
ASSERT(xmlElementPtr != 0);
|
||
|
if (xmlElementPtr)
|
||
|
{
|
||
|
xmlNodeSectionPtr->appendChild(xmlElementPtr, &xmlNodeEntryPtr);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
ASSERT(xmlNodeEntryPtr != 0);
|
||
|
return xmlNodeEntryPtr;
|
||
|
}
|
||
|
|
||
|
CString CXTPPropExchangeXMLNode::BstrToString(BSTR bstrVal)
|
||
|
{
|
||
|
return CString(XTP_CW2CT(bstrVal));
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
||
|
void* pvProp, const void* pvDefault)
|
||
|
{
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
if (!m_bUseDefaultOnLoad)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
CXTPDOMNodePtr xmlEntryPtr = GetEntryNode(pszPropName, FALSE);
|
||
|
if (xmlEntryPtr == 0)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
BSTR bstrValue = NULL;
|
||
|
xmlEntryPtr->get_text(&bstrValue);
|
||
|
|
||
|
if (vtProp == VT_BSTR)
|
||
|
{
|
||
|
PreformatString(bstrValue);
|
||
|
*(BSTR*)pvProp = bstrValue;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CString strValue(BstrToString(bstrValue));
|
||
|
if (bstrValue) SysFreeString(bstrValue);
|
||
|
|
||
|
return ExchangePropStringHelper(strValue, vtProp, pvProp, pvDefault);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!m_bUseDefaultOnSave)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (IsSamePropValue(vtProp, pvProp, pvDefault))
|
||
|
return TRUE;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
CXTPDOMNodePtr xmlEntryPtr = GetEntryNode(pszPropName, TRUE);
|
||
|
ASSERT(xmlEntryPtr != 0);
|
||
|
|
||
|
if (vtProp == VT_BSTR)
|
||
|
{
|
||
|
xmlEntryPtr->put_text(*(BSTR*)pvProp);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CString strValue;
|
||
|
if (!ExchangePropStringHelper(strValue, vtProp, pvProp, pvDefault))
|
||
|
return FALSE;
|
||
|
|
||
|
xmlEntryPtr->put_text(CT2BSTR(strValue));
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
CString CXTPPropExchangeXMLNode::GetSectionName()
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return _T("");
|
||
|
|
||
|
BSTR bstrValue = NULL;
|
||
|
m_xmlSectionNode->get_nodeName(&bstrValue);
|
||
|
|
||
|
CString strValue(bstrValue);
|
||
|
if (bstrValue) SysFreeString(bstrValue);
|
||
|
|
||
|
return strValue;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::IsSectionExists(LPCTSTR lpszSection)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
|
||
|
HRESULT hr = m_xmlSectionNode->selectSingleNode(CT2BSTR(lpszSection), &xmlNodePtr);
|
||
|
|
||
|
if (FAILED(hr) || xmlNodePtr == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::PutSection(CXTPPropExchangeXMLNode* pNode)
|
||
|
{
|
||
|
if (!pNode)
|
||
|
return FALSE;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (!pNode || !pNode->OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
ASSERT(m_xmlSectionNode != 0);
|
||
|
|
||
|
if (FAILED(m_xmlSectionNode->appendChild(pNode->m_xmlSectionNode, NULL)))
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeXMLNode* CXTPPropExchangeXMLNode::Clone(BOOL bRecursive)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return NULL;
|
||
|
|
||
|
ASSERT(m_xmlParentNode != 0);
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
|
||
|
VARIANT_BOOL vbRecursive;
|
||
|
vbRecursive = bRecursive ? VARIANT_TRUE : VARIANT_FALSE;
|
||
|
if (FAILED(m_xmlSectionNode->cloneNode(vbRecursive, &xmlNodePtr)))
|
||
|
return NULL;
|
||
|
|
||
|
CXTPPropExchangeXMLNode* pSection = (CXTPPropExchangeXMLNode*)GetSection(GetSectionName());
|
||
|
|
||
|
pSection->m_bInitialized = TRUE;
|
||
|
pSection->m_xmlSectionNode = xmlNodePtr;
|
||
|
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeXMLNode* CXTPPropExchangeXMLNode::CreateSection(LPCTSTR pszSection)
|
||
|
{
|
||
|
if (!pszSection || !OnBeforeExchange())
|
||
|
return NULL;
|
||
|
|
||
|
ASSERT(m_xmlParentNode != 0);
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
CXTPDOMElementPtr xmlElementPtr;
|
||
|
|
||
|
if (m_xmlSectionNode == 0 || m_xmlDocPtr == 0)
|
||
|
return NULL;
|
||
|
|
||
|
m_xmlDocPtr->createElement(CT2BSTR(pszSection), &xmlElementPtr);
|
||
|
if (xmlElementPtr == 0)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (FAILED(m_xmlSectionNode->appendChild(xmlElementPtr, &xmlNodePtr)))
|
||
|
return NULL;
|
||
|
|
||
|
CXTPPropExchangeXMLNode* pSection = (CXTPPropExchangeXMLNode*)GetSection(pszSection);
|
||
|
|
||
|
pSection->m_bInitialized = TRUE;
|
||
|
pSection->m_xmlSectionNode = xmlNodePtr;
|
||
|
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::SetLoading(BOOL bLoading)
|
||
|
{
|
||
|
m_bLoading = bLoading;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeXMLNode::IsPropertyExists(LPCTSTR pszPropName)
|
||
|
{
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (GetEntryNode(pszPropName, FALSE) != NULL)
|
||
|
return TRUE;
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
class CXTPPropExchangeXMLNode::CXMLEnumerator : public CXTPPropExchangeEnumerator
|
||
|
{
|
||
|
public:
|
||
|
CXMLEnumerator::CXMLEnumerator(CXTPPropExchangeXMLNode* pContainer, LPCTSTR lpszSection)
|
||
|
: CXTPPropExchangeEnumerator(pContainer, lpszSection)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
CXTPDOMNodePtr GetProfileNode(POSITION pos)
|
||
|
{
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
|
||
|
if (m_xmlNodes == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
if (SUCCEEDED(m_xmlNodes->get_item((int)(INT_PTR)pos, &xmlNodePtr)))
|
||
|
return xmlNodePtr;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
POSITION GetPosition(DWORD dwCount = 0, BOOL /*bCompactMode*/ = TRUE)
|
||
|
{
|
||
|
m_nCount = dwCount;
|
||
|
|
||
|
if (!m_pContainer)
|
||
|
return NULL;
|
||
|
|
||
|
if (m_pContainer->IsLoading())
|
||
|
{
|
||
|
if (!m_pContainer->OnBeforeExchange())
|
||
|
return NULL;
|
||
|
|
||
|
CString strNode;
|
||
|
strNode.Format(_T("%s"), m_strSectionName.IsEmpty() ? _T("*") : (LPCTSTR)m_strSectionName);
|
||
|
|
||
|
if (FAILED(((CXTPPropExchangeXMLNode*)m_pContainer)->m_xmlSectionNode->selectNodes(CT2BSTR(strNode), &m_xmlNodes)))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
m_xmlNextNode = GetProfileNode(0);
|
||
|
if (m_xmlNextNode == 0)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return (POSITION)1;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* GetNext(POSITION& pos)
|
||
|
{
|
||
|
CXTPPropExchangeXMLNode* pSection = (CXTPPropExchangeXMLNode*)m_pContainer->GetSection(m_strSectionName);
|
||
|
|
||
|
CXTPDOMNodePtr xmlNodePtr;
|
||
|
CXTPDOMElementPtr xmlElementPtr;
|
||
|
|
||
|
|
||
|
if (m_pContainer->IsStoring())
|
||
|
{
|
||
|
ASSERT((DWORD)(DWORD_PTR)pos <= m_nCount);
|
||
|
|
||
|
pSection->m_xmlDocPtr->createElement(CT2BSTR(m_strSectionName), &xmlElementPtr);
|
||
|
ASSERT(xmlElementPtr != 0);
|
||
|
if (xmlElementPtr)
|
||
|
{
|
||
|
((CXTPPropExchangeXMLNode*)m_pContainer)->m_xmlSectionNode->appendChild(xmlElementPtr, &xmlNodePtr);
|
||
|
}
|
||
|
|
||
|
pos++;
|
||
|
if ((DWORD)(DWORD_PTR)pos > m_nCount) pos = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(m_xmlNextNode != NULL);
|
||
|
ASSERT(m_xmlNodes != NULL);
|
||
|
|
||
|
xmlNodePtr = m_xmlNextNode;
|
||
|
|
||
|
m_xmlNextNode = GetProfileNode(pos);
|
||
|
if (m_xmlNextNode == NULL)
|
||
|
pos = NULL;
|
||
|
else
|
||
|
pos++;
|
||
|
|
||
|
}
|
||
|
|
||
|
pSection->m_bInitialized = TRUE;
|
||
|
pSection->m_xmlSectionNode = xmlNodePtr;
|
||
|
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
int GetCount() const
|
||
|
{
|
||
|
long nCount = m_nCount;
|
||
|
|
||
|
if (m_pContainer && m_pContainer->IsLoading() && SUCCEEDED(m_xmlNodes->get_length(&nCount)))
|
||
|
{
|
||
|
return nCount;
|
||
|
}
|
||
|
|
||
|
return nCount;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
CXTPDOMNodePtr m_xmlNextNode;
|
||
|
XTPXML::IXMLDOMNodeListPtr m_xmlNodes;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
CXTPPropExchangeEnumerator* CXTPPropExchangeXMLNode::GetEnumerator(LPCTSTR lpszSection)
|
||
|
{
|
||
|
if (IsStoring() || !IsPropertyExists(_T("Count")))
|
||
|
return new CXMLEnumerator(this, lpszSection);
|
||
|
|
||
|
return new CXTPPropExchangeEnumerator(this, lpszSection);
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeXMLNode::SetEncoding(LPCTSTR lpszEncoding)
|
||
|
{
|
||
|
m_strEncoding = lpszEncoding;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPPropExchangeIniFile
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CXTPPropExchangeIniFile, CXTPPropExchange)
|
||
|
|
||
|
CXTPPropExchangeIniFile::CXTPPropExchangeIniFile(BOOL bLoading, LPCTSTR lpszParentSection, LPCTSTR lpszSection)
|
||
|
{
|
||
|
ASSERT(lpszSection != NULL);
|
||
|
|
||
|
m_bLoading = bLoading;
|
||
|
m_bTempFile = TRUE;
|
||
|
m_bEmptySection = TRUE;
|
||
|
|
||
|
if (lpszParentSection == NULL)
|
||
|
{
|
||
|
m_strSectionName = lpszSection;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_strSectionName = CString(lpszParentSection) + _T("\\") + CString(lpszSection);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeIniFile::~CXTPPropExchangeIniFile()
|
||
|
{
|
||
|
if (IsRootSection() && !m_strFileName.IsEmpty() && m_bTempFile)
|
||
|
{
|
||
|
::DeleteFile((LPTSTR)(LPCTSTR)m_strFileName);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPPropExchangeIniFile::EmptySection()
|
||
|
{
|
||
|
if (m_bEmptySection || m_strSectionName.IsEmpty())
|
||
|
return;
|
||
|
|
||
|
CXTPPropExchange::EmptySection();
|
||
|
|
||
|
size_t nLength = (size_t)m_strSectionName.GetLength();
|
||
|
LPTSTR lpszBuffer = 0;
|
||
|
int nSize = 8000;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
lpszBuffer = new TCHAR[nSize];
|
||
|
int nResult = GetPrivateProfileSectionNames(lpszBuffer, nSize, m_strFileName);
|
||
|
|
||
|
if (nResult == 0)
|
||
|
{
|
||
|
delete[] lpszBuffer;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (nResult == nSize - 2)
|
||
|
{
|
||
|
nSize = nSize * 2;
|
||
|
delete[] lpszBuffer;
|
||
|
lpszBuffer = 0;
|
||
|
}
|
||
|
}
|
||
|
while (lpszBuffer == 0);
|
||
|
|
||
|
LPTSTR lpszSection = lpszBuffer;
|
||
|
size_t nSectionLen = _tcslen(lpszSection);
|
||
|
|
||
|
while (nSectionLen > 0)
|
||
|
{
|
||
|
if (nLength <= nSectionLen &&
|
||
|
(memcmp((LPCTSTR)m_strSectionName, lpszSection, nLength * sizeof(TCHAR)) == 0) &&
|
||
|
(nLength == nSectionLen || lpszSection[nLength] == _T('\\')))
|
||
|
{
|
||
|
WritePrivateProfileString(lpszSection, NULL, NULL, m_strFileName);
|
||
|
}
|
||
|
|
||
|
lpszSection = lpszSection + nSectionLen + 1;
|
||
|
nSectionLen = _tcslen(lpszSection);
|
||
|
}
|
||
|
|
||
|
|
||
|
delete[] lpszBuffer;
|
||
|
}
|
||
|
|
||
|
CXTPPropExchange* CXTPPropExchangeIniFile::GetSection(LPCTSTR lpszSection)
|
||
|
{
|
||
|
OnBeforeExchange();
|
||
|
|
||
|
CXTPPropExchangeIniFile* pSection = new CXTPPropExchangeIniFile(IsLoading(), m_strSectionName, lpszSection);
|
||
|
pSection->InitSection(this);
|
||
|
pSection->m_strFileName = m_strFileName;
|
||
|
pSection->m_bTempFile = m_bTempFile;
|
||
|
return pSection;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeIniFile::OnBeforeExchange()
|
||
|
{
|
||
|
if (!m_bInitialized)
|
||
|
{
|
||
|
if (m_strFileName.IsEmpty())
|
||
|
{
|
||
|
TCHAR lpszTempPath[MAX_PATH];
|
||
|
TCHAR lpszTempFileName[MAX_PATH];
|
||
|
|
||
|
if (GetTempPath(MAX_PATH, lpszTempPath) == 0)
|
||
|
return FALSE;
|
||
|
|
||
|
if (GetTempFileName(lpszTempPath, _T("xtp"), 0, lpszTempFileName) == 0)
|
||
|
return FALSE;
|
||
|
|
||
|
m_strFileName = lpszTempFileName;
|
||
|
m_bTempFile = TRUE;
|
||
|
}
|
||
|
|
||
|
m_bInitialized = TRUE;
|
||
|
}
|
||
|
return !m_strFileName.IsEmpty();
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPPropExchangeIniFile::ExchangeProp(LPCTSTR pszPropName, VARTYPE vtProp,
|
||
|
void* pvProp, const void* pvDefault /*= NULL*/)
|
||
|
{
|
||
|
if (m_bLoading)
|
||
|
{
|
||
|
if (!m_bUseDefaultOnLoad)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
CString strValue;
|
||
|
|
||
|
DWORD dwSize = GetPrivateProfileString(m_strSectionName, pszPropName, NULL, strValue.GetBuffer(256), 256, m_strFileName);
|
||
|
|
||
|
if (dwSize == 0)
|
||
|
return CopyPropValue(vtProp, pvProp, pvDefault);
|
||
|
|
||
|
if (dwSize == 256 - 1)
|
||
|
{
|
||
|
dwSize = GetPrivateProfileString(m_strSectionName, pszPropName, NULL, strValue.GetBuffer(16000), 16000, m_strFileName);
|
||
|
ASSERT(dwSize < 16000 - 1);
|
||
|
}
|
||
|
|
||
|
strValue.ReleaseBuffer(dwSize);
|
||
|
|
||
|
return ExchangePropStringHelper(strValue, vtProp, pvProp, pvDefault);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!m_bUseDefaultOnSave)
|
||
|
pvDefault = NULL;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
if (IsSamePropValue(vtProp, pvProp, pvDefault))
|
||
|
{
|
||
|
if (!m_bEmptySection)
|
||
|
WritePrivateProfileString (m_strSectionName, pszPropName, NULL, m_strFileName);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
CString strValue;
|
||
|
if (!ExchangePropStringHelper(strValue, vtProp, pvProp, pvDefault))
|
||
|
return FALSE;
|
||
|
|
||
|
if (!WritePrivateProfileString (m_strSectionName, pszPropName, strValue, m_strFileName))
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPPropExchangeIniFile::SaveToFile(LPCTSTR strFileName)
|
||
|
{
|
||
|
ASSERT(IsRootSection() && IsStoring());
|
||
|
|
||
|
if (m_strFileName.Compare(strFileName) != 0 && !m_strFileName.IsEmpty())
|
||
|
{
|
||
|
::DeleteFile(strFileName);
|
||
|
::CopyFile(m_strFileName, strFileName, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPPropExchangeIniFile::LoadFromFile(LPCTSTR strFileName)
|
||
|
{
|
||
|
ASSERT(IsRootSection() && IsLoading());
|
||
|
|
||
|
if (!FILEEXISTS_S(strFileName))
|
||
|
return FALSE;
|
||
|
|
||
|
if (!OnBeforeExchange())
|
||
|
return FALSE;
|
||
|
|
||
|
return ::CopyFile(strFileName, m_strFileName, FALSE);
|
||
|
}
|
||
|
|
||
|
void CXTPPropExchangeIniFile::AssignFile(LPCTSTR strFileName)
|
||
|
{
|
||
|
m_strFileName = strFileName;
|
||
|
m_bTempFile = FALSE;
|
||
|
m_bEmptySection = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// PX_ functions
|
||
|
|
||
|
BOOL AFX_CDECL PX_Byte(CXTPPropExchange* pPX, LPCTSTR pszPropName, BYTE& nValue, BYTE nDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&nValue, short);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_UI1, &nValue, &nDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Short(CXTPPropExchange* pPX, LPCTSTR pszPropName, short& sValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&sValue, short);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I2, &sValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Short(CXTPPropExchange* pPX, LPCTSTR pszPropName, short& sValue,
|
||
|
short sDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&sValue, short);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I2, &sValue, &sDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_UShort(CXTPPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&usValue, USHORT);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I2, &usValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_UShort(CXTPPropExchange* pPX, LPCTSTR pszPropName, USHORT& usValue,
|
||
|
USHORT usDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&usValue, USHORT);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I2, &usValue, &usDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Long(CXTPPropExchange* pPX, LPCTSTR pszPropName, long& lValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&lValue, long);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &lValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Long(CXTPPropExchange* pPX, LPCTSTR pszPropName, long& lValue,
|
||
|
long lDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&lValue, long);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &lValue, &lDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_DWord(CXTPPropExchange* pPX, LPCTSTR pszPropName, DWORD& dwValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&dwValue, DWORD);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &dwValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_DWord(CXTPPropExchange* pPX, LPCTSTR pszPropName, DWORD& dwValue,
|
||
|
DWORD dwDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&dwValue, DWORD);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &dwValue, &dwDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_UI8(CXTPPropExchange* pPX, LPCTSTR pszPropName,
|
||
|
ULONGLONG& ullValue, ULONGLONG ullDefault)
|
||
|
{
|
||
|
POINT ptData64 = {(LONG)(DWORD)(ullValue >> 32), (LONG)(DWORD)ullValue};
|
||
|
POINT ptDefault = {(LONG)(DWORD)(ullDefault >> 32), (LONG)(DWORD)ullDefault};
|
||
|
|
||
|
BOOL bResult = PX_Point(pPX, pszPropName, ptData64, ptDefault);
|
||
|
|
||
|
if (bResult && pPX->IsLoading())
|
||
|
{
|
||
|
ullValue = (DWORD)ptData64.x;
|
||
|
ullValue = ullValue << 32;
|
||
|
ullValue += (DWORD)ptData64.y;
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Int(CXTPPropExchange* pPX, LPCTSTR pszPropName, int& nValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&nValue, int);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &nValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Int(CXTPPropExchange* pPX, LPCTSTR pszPropName, int& nValue,
|
||
|
int nDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&nValue, int);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &nValue, &nDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_ULong(CXTPPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&ulValue, ULONG);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_ULong(CXTPPropExchange* pPX, LPCTSTR pszPropName, ULONG& ulValue,
|
||
|
ULONG ulDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&ulValue, ULONG);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_I4, &ulValue, &ulDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Bool(CXTPPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&bValue, BOOL);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Bool(CXTPPropExchange* pPX, LPCTSTR pszPropName, BOOL& bValue,
|
||
|
BOOL bDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&bValue, BOOL);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_BOOL, &bValue, &bDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_String(CXTPPropExchange* pPX, LPCTSTR pszPropName, CString& strValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&strValue, CString);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_LPSTR, &strValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_String(CXTPPropExchange* pPX, LPCTSTR pszPropName, CString& strValue,
|
||
|
LPCTSTR lpszDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&strValue, CString);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_LPSTR, &strValue, lpszDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Bstr(CXTPPropExchange* pPX, LPCTSTR pszPropName, BSTR& lpszValue,
|
||
|
BSTR lpszDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&lpszValue, BSTR);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_BSTR, &lpszValue, lpszDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Float(CXTPPropExchange* pPX, LPCTSTR pszPropName, float& floatValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&floatValue, float);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Float(CXTPPropExchange* pPX, LPCTSTR pszPropName, float& floatValue,
|
||
|
float floatDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&floatValue, float);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_R4, &floatValue, &floatDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Double(CXTPPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&doubleValue, double);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_DateTime(CXTPPropExchange* pPX, LPCTSTR pszPropName, COleDateTime& dtValue)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&dtValue, COleDateTime);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_DATE, &dtValue);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Double(CXTPPropExchange* pPX, LPCTSTR pszPropName, double& doubleValue,
|
||
|
double doubleDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT_POINTER(&doubleValue, double);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_R8, &doubleValue, &doubleDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Size(CXTPPropExchange* pPX, LPCTSTR pszPropName, SIZE& szValue, SIZE szDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_EX_SIZE, &szValue, &szDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Point(CXTPPropExchange* pPX, LPCTSTR pszPropName, POINT& ptValue, POINT ptDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
ASSERT(sizeof(POINT) == sizeof(SIZE));
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_EX_SIZE, &ptValue, &ptDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Rect(CXTPPropExchange* pPX, LPCTSTR pszPropName, RECT& rcValue, RECT rcDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_EX_RECT, &rcValue, &rcDefault);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Variant(CXTPPropExchange* pPX, LPCTSTR pszPropName, COleVariant& variant, COleVariant variantDefault)
|
||
|
{
|
||
|
ASSERT_POINTER(pPX, CXTPPropExchange);
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeProp(pszPropName, VT_VARIANT, &variant, &variantDefault);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL AFX_CDECL PX_RuntimeClass(CXTPPropExchange* pPX, LPCTSTR pszPropName, CRuntimeClass*& pClass, CRuntimeClass* pDefaultClass)
|
||
|
{
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeRuntimeClass(pszPropName, pClass, pDefaultClass);
|
||
|
}
|
||
|
|
||
|
BOOL AFX_CDECL PX_Blob(CXTPPropExchange* pPX, LPCTSTR pszPropName, BYTE*& pData, DWORD& nBytes)
|
||
|
{
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
return pPX->ExchangeBlobProp(pszPropName, pData, nBytes);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL AFX_CDECL PX_Serialize(CXTPPropExchange* pPX, LPCTSTR pszPropName, CObject* pObject)
|
||
|
{
|
||
|
if (!pPX)
|
||
|
return FALSE;
|
||
|
|
||
|
CArchive* pArchive = pPX->GetArchive(pszPropName);
|
||
|
|
||
|
if (!pArchive)
|
||
|
return FALSE;
|
||
|
|
||
|
BOOL bResult = FALSE;
|
||
|
try
|
||
|
{
|
||
|
pObject->Serialize(*pArchive);
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
catch (COleException* pEx)
|
||
|
{
|
||
|
pEx->Delete ();
|
||
|
|
||
|
}
|
||
|
catch (CArchiveException* pEx)
|
||
|
{
|
||
|
pEx->Delete ();
|
||
|
}
|
||
|
|
||
|
pPX->ReleaseArchive(pszPropName, pArchive);
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
|