Интерфейс:

// 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);
   }
}
обновлено
12.01.2008
 
Проверка PR и ТИЦ