Интерфейс:
// ddxv.h - interface of the extended DDX/DDV routines
#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif // _MSC_VER
#if !defined(__ddxv_h)
#define __ddxv_h
// required CRT headers
#if !defined(_INC_LIMITS)
#pragma message(__FILE__ " : put <limits.h> in your PCH to speed up compilation")
#include <limits.h>
#endif // _INC_LIMITS
// helper routines
void FailMinMaxWithFormat(CDataExchange* pDX, LONGLONG minVal, LONGLONG maxVal, LPCTSTR pszFormat,
UINT idsPrompt);
// extra Dialog Data Exchange routines
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, WORD& value);
// extra Dialog Data Validation routines
void AFXAPI DDV_MinMaxWord(CDataExchange* pDX, WORD value, WORD minVal, WORD maxVal);
// combined Dialog Data Exchange/Validation routines (with numeric range validation)
template
<
typename _Int_t,
typename _TestInt_t,
_Int_t _MinRange,
_Int_t _MaxRange,
void(AFXAPI* _DDV_MinMax)(CDataExchange*, _Int_t, _Int_t, _Int_t)
>
void DDXV_Generic(CDataExchange* pDX, int nIDC, _Int_t& value, _Int_t minVal, _Int_t maxVal,
LPCTSTR pszFormat, UINT idsPrompt)
{
if (minVal == maxVal)
{
// no user-defined range validation
minVal = _MinRange;
maxVal = _MaxRange;
}
ASSERT(minVal < maxVal);
if (pDX->m_bSaveAndValidate)
{
_TestInt_t testVal = value;
DDX_Text(pDX, nIDC, testVal);
_Int_t minLimit = minVal > _MinRange ? minVal : _MinRange;
_Int_t maxLimit = maxVal < _MaxRange ? maxVal : _MaxRange;
if (testVal < minLimit || testVal > maxLimit)
{
FailMinMaxWithFormat(pDX, minLimit, maxLimit, pszFormat, idsPrompt);
}
else
{
value = static_cast<_Int_t>(testVal);
}
}
else
{
DDX_Text(pDX, nIDC, value);
(*_DDV_MinMax)(pDX, value, minVal, maxVal);
}
}
inline void DDXV_Short(CDataExchange* pDX, int nIDC, short& value, short minVal = 0, short maxVal = 0)
{
DDXV_Generic<short, LONGLONG, SHRT_MIN, SHRT_MAX, &DDV_MinMaxShort>
(pDX, nIDC, value, minVal, maxVal, _T("%I64d"), AFX_IDP_PARSE_INT_RANGE);
}
inline void DDXV_Word(CDataExchange* pDX, int nIDC, WORD& value, WORD minVal = 0, WORD maxVal = 0)
{
DDXV_Generic<WORD, ULONGLONG, 0, USHRT_MAX, &DDV_MinMaxWord>
(pDX, nIDC, value, minVal, maxVal, _T("%I64u"), AFX_IDP_PARSE_INT_RANGE);
}
inline void DDXV_Int(CDataExchange* pDX, int nIDC, int& value, int minVal = 0, int maxVal = 0)
{
DDXV_Generic<int, LONGLONG, INT_MIN, INT_MAX, &DDV_MinMaxInt>
(pDX, nIDC, value, minVal, maxVal, _T("%I64d"), AFX_IDP_PARSE_INT_RANGE);
}
inline void DDXV_UInt(CDataExchange* pDX, int nIDC, UINT& value, UINT minVal = 0, UINT maxVal = 0)
{
DDXV_Generic<UINT, ULONGLONG, 0, UINT_MAX, &DDV_MinMaxUInt>
(pDX, nIDC, value, minVal, maxVal, _T("%I64u"), AFX_IDP_PARSE_INT_RANGE);
}
inline void DDXV_Long(CDataExchange* pDX, int nIDC, long& value, long minVal = 0, long maxVal = 0)
{
DDXV_Generic<long, LONGLONG, LONG_MIN, LONG_MAX, &DDV_MinMaxLong>
(pDX, nIDC, value, minVal, maxVal, _T("%I64d"), AFX_IDP_PARSE_INT_RANGE);
}
inline void DDXV_DWord(CDataExchange* pDX, int nIDC, DWORD& value, DWORD minVal = 0, DWORD maxVal = 0)
{
DDXV_Generic<DWORD, ULONGLONG, 0, ULONG_MAX, &DDV_MinMaxDWord>
(pDX, nIDC, value, minVal, maxVal, _T("%I64u"), AFX_IDP_PARSE_INT_RANGE);
}
#endif // __ddxv_h
Реализация:
// ddxv.cpp - implementation of the extended DDX/DDV routines
#include "ddxv.h"
#if defined(_DEBUG)
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif // _DEBUG
// helper routines
void FailMinMaxWithFormat(CDataExchange* pDX, LONGLONG minVal, LONGLONG maxVal, LPCTSTR pszFormat,
UINT idsPrompt)
{
ASSERT(pDX != NULL);
ASSERT(pszFormat != NULL);
if (!pDX->m_bSaveAndValidate)
{
TRACE(traceAppMsg, 0, "Warning: initial dialog data is out of range.\n");
return;
}
TCHAR szMin[64] = { 0 };
_stprintf(szMin, pszFormat, minVal);
TCHAR szMax[64] = { 0 };
_stprintf(szMax, pszFormat, maxVal);
CString strPrompt;
AfxFormatString2(strPrompt, idsPrompt, szMin, szMax);
AfxMessageBox(strPrompt, MB_ICONEXCLAMATION, idsPrompt);
strPrompt.Empty();
pDX->Fail();
}
// extra Dialog Data Exchange routines
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, WORD& value)
{
HWND hEditWnd = pDX->PrepareEditCtrl(nIDC);
ASSERT(hEditWnd != NULL);
TCHAR szText[64] = { 0 };
if (pDX->m_bSaveAndValidate)
{
::GetWindowText(hEditWnd, szText, _countof(szText));
if (_stscanf(szText, _T("%hu"), &value) != 1)
{
AfxMessageBox(AFX_IDP_PARSE_UINT);
pDX->Fail();
}
}
else
{
_stprintf(szText, _T("%hu"), value);
AfxSetWindowText(hEditWnd, szText);
}
}
// extra Dialog Data Validation routines
void AFXAPI DDV_MinMaxWord(CDataExchange* pDX, WORD value, WORD minVal, WORD maxVal)
{
ASSERT(minVal <= maxVal);
if (value < minVal || value > maxVal)
{
FailMinMaxWithFormat(pDX, minVal, maxVal, _T("%I64u"), AFX_IDP_PARSE_INT_RANGE);
}
}
|