Article ID: 131993
Article Last Modified on 11/21/2006
DDX_Text(CDataExchange* pDX, int nIDC, float& value)
DDX_Text(CDataExchange* pDX, int nIDC, double& value)
function returns exponential format for all numbers of the format 0.0<x>,where x is any sequence of digits.
Signed value printed in f or e format, whichever is more compact
for the given value and precision. The e format is used only when
the exponent of the value is less than -4 or greater than or equal
to the precision argument. . .
// include header files.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//............
//............
//............
// The function prototypes
void AFXAPI DDX_MyFloatText(CDataExchange* pDX, int nIDC,
float& value);
char *double_to_char (double number);
static BOOL PASCAL NEAR _AfxSimpleFloatParse(const char* pszText,
double& d);
//............
//............
//............
// Change the DoDataExchange to use DDX_MyFloatText
void CDlgfloatView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgfloatView)
DDX_MyFloatText(pDX, IDC_EDIT1, m_eFloat);
//}}AFX_DATA_MAP
}
//............
//............
//............
// Implementation of DDX_MyFloatText and other helper functions
void AFXAPI DDX_MyFloatText(CDataExchange* pDX, int nIDC,
float& value)
{
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
char szT[64];
if (pDX->m_bSaveAndValidate)
{
::GetWindowText(hWndCtrl, szT, sizeof(szT));
double d;
if (!_AfxSimpleFloatParse(szT, d))
{
AfxMessageBox(AFX_IDP_PARSE_REAL);
pDX->Fail(); // throws exception
}
value = (float)d;
}
else
{
char * pszCvt = double_to_char(value);
if (pszCvt)
{
int nNewLen = lstrlen(pszCvt);
char szOld[64];
// fast check to see if text really changes (reduces
// flash in controls)
if (nNewLen > sizeof(szOld) ||
::GetWindowText(hWndCtrl, szOld, sizeof(szOld)) !=
nNewLen ||
lstrcmp(szOld, pszCvt) != 0)
{
// change it
::SetWindowText(hWndCtrl, pszCvt);
}
delete pszCvt;
}
else
{
TRACE("DDX_MyFloatText() failed to convert float
value.\n");
pDX->Fail(); // throws exception
}
}
}
#define PRECISION 5
char *double_to_char (double number)
{
char *buffer,*temp ;
int decimal_spot,
sign,
count,
current_location = 0,
zeropos;
temp = _fcvt (number, PRECISION, &decimal_spot, &sign) ;
if (strlen (temp) > PRECISION)
buffer = new char[(strlen (temp) + 3)];
else
buffer = new char[(PRECISION + 3)];
if (buffer == NULL)
{
OutputDebugString("Memory allocating attempt has failed in"
"'double_to_char'\n") ;
return (NULL) ;
}
/* Add negative sign if required. */
if (sign)
buffer [current_location++] = '-' ;
/* Place decimal point in the correct location. */
if (decimal_spot > 0)
{
strncpy (&buffer [current_location], temp, decimal_spot) ;
buffer [decimal_spot + current_location] = '.' ;
strcpy (&buffer [decimal_spot + current_location + 1],
&temp [decimal_spot]) ;
}
else
{
buffer [current_location++] = '0';
buffer [current_location] = '.' ;
for(count = current_location-(1+sign);
count<abs(decimal_spot); count++)
buffer [count + (current_location+1)] = '0' ;
strcpy (&buffer [count + (current_location+1)], temp) ;
}
zeropos = strlen(buffer)-3;
if (buffer[zeropos+2] == '0')
{
while (buffer[zeropos--] == '0')
buffer[zeropos+2] = '\0';
if (buffer[zeropos+1] != '.')
buffer[zeropos+2] = '\0';
}
return (buffer) ;
}
static BOOL PASCAL NEAR _AfxSimpleFloatParse(const char* pszText,
double& d)
{
ASSERT(pszText != NULL);
while (*pszText == ' ' || *pszText == '\t')
pszText++;
ASSERT(!::IsDBCSLeadByte(*pszText));
char chFirst = pszText[0];
d = strtod(pszText, (char**)&pszText);
if (d == 0.0 && chFirst != '0')
return FALSE; // could not convert
while (*pszText == ' ' || *pszText == '\t')
pszText++;
ASSERT(!::IsDBCSLeadByte(*pszText));
if (*pszText != '\0')
return FALSE; // not terminated properly
return TRUE;
}
Sample Code II - for Visual C++ 32-bit 4.0
------------------------------------------
//............
//............
//............
// The function prototypes
void AFXAPI DDX_MyFloatText(CDataExchange* pDX, int nIDC, float& value);
void AFXAPI DDX_MyDoubleText(CDataExchange* pDX, int nIDC, double& value);
void AFXAPI _MyAfxTextFloatFormat(CDataExchange* pDX, int nIDC,
void* pData, double value, int nSizeGcvt,
int nSizeType);
//............
//............
//............
// Change the DoDataExchange to use DDX_MyFloatText or DDX_MyDoubleText
void CDlgfloatView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgfloatView)
DDX_MyFloatText(pDX, IDC_EDIT1, m_eFloat);
DDX_MyDoubleText(pDX, IDC_EDIT2, m_eDouble);
//}}AFX_DATA_MAP
}
//............
//............
//............
// Implementation of DDX_MyFloatText, DDX_MyDoubleText and
// _MyAfxTextFloatFormat.
#include <float.h>
#define PRECISION 8
void AFXAPI DDX_MyFloatText(CDataExchange* pDX, int nIDC, float& value)
{
_MyAfxTextFloatFormat(pDX, nIDC, &value, value, PRECISION, FLT_DIG);
}
void AFXAPI DDX_MyDoubleText(CDataExchange* pDX, int nIDC, double& value)
{
_MyAfxTextFloatFormat(pDX, nIDC, &value, value, PRECISION, DBL_DIG);
}
void AFXAPI _MyAfxTextFloatFormat(CDataExchange* pDX, int nIDC,
void* pData, double value, int nSizeGcvt,
int nSizeType)
{
ASSERT(pData != NULL);
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
// Make sure your buffer is big enough. Strings returned by
// _stprintf() using the "f" specifier tend to be longer
// than those returned using the "g" specifier.
TCHAR szBuffer[64];
if (pDX->m_bSaveAndValidate)
{
::GetWindowText(hWndCtrl, szBuffer, _countof(szBuffer));
double d;
if (!AfxSimpleFloatParse(szBuffer, d))
{
AfxMessageBox(AFX_IDP_PARSE_REAL);
pDX->Fail(); // throws exception
}
if (nSizeType == FLT_DIG)
*((float*)pData) = (float)d;
else
*((double*)pData) = d;
}
else
{
_stprintf(szBuffer, _T("%.*f"), nSizeGcvt, value);
AfxSetWindowText(hWndCtrl, szBuffer);
}
}
Additional query words: 1.50 2.00 2.10 4.00
Keywords: kbcode kbdlg kbprb KB131993