?? numfrm.cpp
字號:
FRM_THOUSAND_SEP,
_T(']'), 0 };
int nLen;
m_nDec = 0;
m_pTmpBuffer[0] = 0;
_stscanf(sFrm, szSScanfFormat1, m_pTmpBuffer); // INTEGER PART
if(nLen = lstrlen(m_pTmpBuffer))
sFrm = sFrm.Mid(nLen);
ProcessNumFlags(m_pTmpBuffer, m_nLeftFlags);
if(sFrm.GetLength() && sFrm[0] == FRM_DEC_POINT)
{
sFrm = sFrm.Mid(1);
m_pTmpBuffer[0] = 0;
_stscanf(sFrm, szSScanfFormat2, m_pTmpBuffer); // DEC PART
ProcessNumFlags(m_pTmpBuffer, m_nRightFlags);
m_nDec = lstrlen(m_pTmpBuffer);
if(m_nDec)
sFrm = sFrm.Mid(m_nDec);
m_pTmpBuffer[0] = 0;
_stscanf(sFrm, szSScanfFormat3, m_pTmpBuffer); // POWER PART
if(nLen = lstrlen(m_pTmpBuffer))
sFrm = sFrm.Mid(nLen);
}
ProcessPower(m_pTmpBuffer);
return TRUE;
}
void CNumFrmNode::ProcessNumFlags(LPCTSTR pBuff, int& nFlags)
{
if(_tcschr(pBuff, FRM_DIGIT)) nFlags |= DF_DIGIT;
if(_tcschr(pBuff, FRM_DIGIT_ZERO)) nFlags |= DF_DIGIT_ZERO;
if(_tcschr(pBuff, FRM_DIGIT_BALNKS)) nFlags |= DF_DIGIT_BALNKS;
if(_tcschr(pBuff, FRM_THOUSAND_SEP)) nFlags |= DF_THOUSANDS;
}
void CNumFrmNode::ProcessPower(LPCTSTR pBuff)
{
int nLen = lstrlen(pBuff);
int i;
if(nLen)
{
int nPowers = 0;
for(i = nLen - 1; i >= 0; i--)
{
if(pBuff[i] == FRM_THOUSAND_SEP)
nPowers++;
else
break;
}
if(nPowers)
{
m_nCommonFlags |= CF_USE_POWER;
m_nPowered = m_nPowered / pow(10.0, (double)(nPowers * INTL_GROUP_DIGIT_LEN));
}
}
}
static COLORREF colOldColor;
void CNumFrmNode::BeforePrint(double nVal, CDC* pDC, LPCRECT lpRect, int nForceDec, BOOL bFull) const
{
int nLenBuffer;
int nNumDec;
m_pTmpBuffer[0] = 0;
if(nForceDec != -1)
nNumDec = nForceDec;
else
nNumDec = m_nDec;
if(bFull) // BEFORE MAIN NUMBER
{
if(m_nCommonFlags & (CF_USE_POWER | CF_USE_PERCENT))
nVal = nVal * m_nPowered;
lstrcpy(m_pTmpBuffer, m_sText1);
}
if( (m_nLeftFlags & (DF_DIGIT | DF_DIGIT_BALNKS | DF_DIGIT_ZERO ) ) |
(m_nRightFlags & (DF_DIGIT | DF_DIGIT_BALNKS | DF_DIGIT_ZERO ) ) )
{
if(bFull)
{
WinFormat(m_pTmpBuffer + m_sText1.GetLength(),
MAX_NFORMAT_LEN - m_sText1.GetLength() - m_sText2.GetLength() - 1,
nVal, nNumDec, m_nLeftFlags & DF_THOUSANDS,
m_nLeftFlags & DF_DIGIT_ZERO);
if( (m_nCommonFlags & CF_PURGE_SIGN) && nVal < 0.0 )
{
PTCHAR pch;
pch = _tcsstr(m_pTmpBuffer + m_sText1.GetLength(), INTL_NEGATIVE_STR);
if(pch)
memmove(pch, pch + 1, (lstrlen(pch + 1) + 1) * sizeof(TCHAR));
}
}
else
WinFormat(m_pTmpBuffer, MAX_NFORMAT_LEN - 1,
nVal, nNumDec, m_nLeftFlags & DF_THOUSANDS, m_nLeftFlags & DF_DIGIT_ZERO );
}
if(m_nDec)
{
int i;
if(m_nRightFlags & DF_DIGIT)
{
nLenBuffer = lstrlen(m_pTmpBuffer);
for(i = nLenBuffer - 1; i >= 0; i--)
{
if(m_pTmpBuffer[i] == _T('0'))
m_pTmpBuffer[i] = 0;
else
break;
}
}
//if(m_nRightFlags & DF_DIGIT_ZERO)
//{ /* Nothing to do */ }
if(m_nRightFlags & DF_DIGIT_BALNKS)
{
nLenBuffer = lstrlen(m_pTmpBuffer);
for(i = nLenBuffer - 1; i >= 0; i--)
{
if(m_pTmpBuffer[i] == _T('0'))
m_pTmpBuffer[i] = OUTCHAR_BLANK;
else
break;
}
}
}
if(bFull) // AFTER MAIN NUMBER
{
lstrcat(m_pTmpBuffer, m_sText2);
if( m_nCommonFlags & CF_USE_PERCENT )
{
int nCurrLength = lstrlen(m_pTmpBuffer);
m_pTmpBuffer[nCurrLength] = FRM_PERSENT;
m_pTmpBuffer[nCurrLength + 1] = _T('\0');
}
}
if(pDC && lpRect && (m_nCommonFlags & CF_USE_COLOR))
colOldColor = pDC->SetTextColor(m_Color);
}
void CNumFrmNode::AfterPrint(CDC* pDC, LPCRECT lpRect) const
{
if(pDC && lpRect && (m_nCommonFlags & CF_USE_COLOR))
pDC->SetTextColor(colOldColor);
}
LPCTSTR CNumFrmNode::PrintNumFormat(double nVal, CDC* pDC, LPRECT lpRect, UINT nFormat, int nForceDec, BOOL bFull) const
{
BeforePrint(nVal, pDC, lpRect, nForceDec, bFull);
if(pDC && lpRect)
pDC->DrawText(m_pTmpBuffer, -1, lpRect, nFormat);
AfterPrint(pDC, lpRect);
return (LPCTSTR)m_pTmpBuffer;
}
LPCTSTR CNumFrmNode::PrintNumFormatETO(double nVal, CDC* pDC, int x, int y, UINT nOptions, LPCRECT lpRect, int nForceDec, BOOL bFull) const
{
BeforePrint(nVal, pDC, lpRect, nForceDec, bFull);
if(pDC && lpRect)
pDC->ExtTextOut(x, y, nOptions, lpRect, m_pTmpBuffer, lstrlen(m_pTmpBuffer), NULL );
AfterPrint(pDC, lpRect);
return (LPCTSTR)m_pTmpBuffer;
}
LPCTSTR CNumFrmNode::PrintSimpleNumFormat(double nOut, int nForceDec) const
{
CString sSprintfFormat;
m_pTmpBuffer[0] = 0;
sSprintfFormat.Format(_T("%%16.%dlf"),
nForceDec == -1 ? m_nDec : nForceDec);
_stprintf(m_pTmpBuffer, sSprintfFormat, nOut);
return (LPCTSTR)m_pTmpBuffer;
}
BOOL CNumFrmNode::WinFormat(LPTSTR szOutput, int nOutBufferLen, double nNumb, int nDec, BOOL bThousandSepareted, BOOL bIntZeroObligated)
{
const int nBufferLen = 16;
if(!m_bLocaleInitialized)
{
// Locale initialzation
if(!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, m_sThousand.GetBuffer(nBufferLen), nBufferLen))
m_sThousand = _T(" ");
m_sThousand.ReleaseBuffer();
if(!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, m_sDecimal.GetBuffer(nBufferLen), nBufferLen))
m_sDecimal = _T(".");
m_sDecimal.ReleaseBuffer();
m_bLocaleInitialized = TRUE;
}
int nPosDecimal;
int nSign;
LPTSTR pfcvtBuffer;
LPTSTR pPos;
if( fabs(nNumb) > 1.0e+030 )
{
lstrcpy(szOutput, _T("Overflow"));
return FALSE;
}
#ifdef _UNICODE
LPCSTR pAStr = fcvt(nNumb, nDec, &nPosDecimal, &nSign );
USES_CONVERSION;
pfcvtBuffer = A2W(pAStr);
#else
pfcvtBuffer = fcvt(nNumb, nDec, &nPosDecimal, &nSign );
#endif
int nfcvtLen = lstrlen(pfcvtBuffer);
// Calculating approximate length of result
int nEstimatedLength =
(nSign ? lstrlen(INTL_NEGATIVE_STR) : 0) +
max(nfcvtLen, nDec + 1) +
(nDec ? m_sDecimal.GetLength() : 0) +
(bThousandSepareted ? ((nPosDecimal / INTL_GROUP_DIGIT_LEN) * m_sThousand.GetLength()) : 0);
if(nEstimatedLength > nOutBufferLen)
{
lstrcpy(szOutput, _T("Overflow"));
return FALSE;
}
pPos = szOutput;
if(nSign && NonZero(nNumb))
{
lstrcpy(pPos, INTL_NEGATIVE_STR);
pPos += lstrlen(INTL_NEGATIVE_STR);
}
// zero length
if(nPosDecimal <= 0 && bIntZeroObligated)
*pPos++ = _T('0');
if(nPosDecimal < 0 && nDec > 0)
{
lstrcpy(pPos, m_sDecimal);
pPos += m_sDecimal.GetLength();
for(int pos = nPosDecimal; pos < 0 && (pos - nPosDecimal) < nDec; pos++)
*pPos++ = _T('0');
}
for(int i = 0; i < nfcvtLen; i++)
{
// Check for thousand separator insertion
if( i > 0 && i < nPosDecimal &&
bThousandSepareted &&
(nPosDecimal - i) % INTL_GROUP_DIGIT_LEN == 0)
{
lstrcpy(pPos, m_sThousand);
pPos += m_sThousand.GetLength();
}
// Check for decimal separator insertion
else if(i == nPosDecimal)
{
lstrcpy(pPos, m_sDecimal);
pPos += m_sDecimal.GetLength();
}
*pPos++ = pfcvtBuffer[i];
}
*pPos = _T('\0');
return TRUE;
}
//_________________________________________________________________
//
CNumericFormat::CNumericFormat()
{
m_pNodes = NULL;
m_nNodeCount = 0;
}
CNumericFormat::CNumericFormat(const CString& sFormat)
{
m_pNodes = NULL;
m_nNodeCount = 0;
SetFormat(sFormat);
}
CNumericFormat::~CNumericFormat()
{
if(m_pNodes)
delete [] m_pNodes;
}
CString CNumericFormat::GetFormat() const
{
return m_sFormat;
}
BOOL CNumericFormat::SetFormat(const CString& sFormat)
{
if(sFormat.IsEmpty())
return FALSE;
if(sFormat != m_sFormat)
{
CString sFrm = sFormat;
// Check for old style format (sprintf style),
// and automatic convertion into new style if
// nessesory.
if(sFrm[0] == _T('%') && sFrm.Right(2) == _T("lf"))
{
int pos = sFrm.Find(_T('.'));
int nNumDec;
if(pos != -1)
{
nNumDec = _ttoi(&(((LPCTSTR)sFrm)[pos + 1]));
sFrm = CString(FRM_DIGIT) + FRM_THOUSAND_SEP;
sFrm += CString(FRM_DIGIT, INTL_GROUP_DIGIT_LEN);
if(nNumDec)
{
sFrm += FRM_DEC_POINT;
sFrm += CString(FRM_DIGIT_ZERO, nNumDec);
}
}
}
CString sNode;
int i;
// Calculate number of sections in new format string
m_nNodeCount = 0;
for(i = 0; i < sFrm.GetLength(); i++)
{
if(sFrm[i] == FRM_SECTION_DELIM)
m_nNodeCount++;
}
if(sFrm[sFrm.GetLength() - 1] != FRM_SECTION_DELIM)
m_nNodeCount++;
// Obligatory clean up old content of array
if(m_pNodes)
delete [] m_pNodes;
m_pNodes = new CNumFrmNode[m_nNodeCount];
if(!m_pNodes)
return FALSE;
BOOL bConditionalFormat = FALSE;
for(i = 0; i < m_nNodeCount; i++)
{
sNode = GetLine(sFrm, FRM_SECTION_DELIM);
if( !(m_pNodes[i].SetFormat(sNode)) )
return FALSE;
if(m_pNodes[i].IsConditional())
bConditionalFormat = TRUE;
}
// Set up default conditions (if requered)
if(!bConditionalFormat && m_nNodeCount > 1)
{
if(m_nNodeCount == 2)
{
m_pNodes[0].SetCondition(SGN_GREATER_OR_EQUAL_1, 0.0);
}
else /* m_nNodeCount >= 3 */
{
m_pNodes[0].SetCondition(SGN_GREATER, 0.0);
m_pNodes[1].SetCondition(SGN_LESS, 0.0);
}
}
m_sFormat = sFormat;
}
return TRUE;
}
LPCTSTR CNumericFormat::SPrintNumber(double nVal, BOOL bFull) const
{
LPCTSTR lpszBuffer = NULL;
if(bFull)
lpszBuffer = PrintNumber(nVal, NULL, NULL, 0, -1);
else
lpszBuffer = m_pNodes[0].PrintNumFormat(nVal, NULL, NULL, 0, -1, bFull);
return lpszBuffer;
}
LPCTSTR CNumericFormat::SPrintNumberSimple(double nOut, int nForceDec) const
{
LPCTSTR lpszBuffer = NULL;
if(!m_sFormat.IsEmpty())
{
lpszBuffer = m_pNodes[0].PrintSimpleNumFormat(nOut, nForceDec);
}
else
TRACE(_T("CNumericFormat: Attemption to print on noninitialized format !\n"));
return lpszBuffer;
}
LPCTSTR CNumericFormat::PrintNumber(double nVal, CDC* pDC, LPRECT lpRect, UINT nFormat, int nForceDec) const
{
LPCTSTR lpszBuffer = NULL;
if(!m_sFormat.IsEmpty() && m_pNodes != NULL)
{
for(int i = 0; i < m_nNodeCount; i++)
{
if(m_pNodes[i].Satisfied(nVal))
{
lpszBuffer = m_pNodes[i].PrintNumFormat(nVal, pDC, lpRect, nFormat, nForceDec, TRUE);
return lpszBuffer;
}
}
}
else
TRACE(_T("CNumericFormat: Attemption to print by uninitialized format !\n"));
return lpszBuffer;
}
LPCTSTR CNumericFormat::PrintNumberETO(double nVal, CDC* pDC, int x, int y, UINT nOptions, LPCRECT lpRect, int nForceDec) const
{
LPCTSTR lpszBuffer = NULL;
if(!m_sFormat.IsEmpty() && m_pNodes != NULL)
{
for(int i = 0; i < m_nNodeCount; i++)
{
if(m_pNodes[i].Satisfied(nVal))
{
lpszBuffer = m_pNodes[i].PrintNumFormatETO(nVal, pDC, x, y, nOptions, lpRect, nForceDec, TRUE);
return lpszBuffer;
}
}
}
else
TRACE(_T("CNumericFormat: Attemption to print by uninitialized format !\n"));
return lpszBuffer;
}
CArchive& operator<<(CArchive& ar, const CNumericFormat& frmt)
{
return ar << frmt.m_sFormat;
}
CArchive& operator>>(CArchive& ar, CNumericFormat& frmt)
{
CString sFormat;
ar >> sFormat;
frmt.SetFormat(sFormat);
return ar;
}
BOOL CNumericFormat::LoadString(UINT nRes)
{
CString sStr;
if(sStr.LoadString(nRes))
return SetFormat(sStr);
else
return FALSE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -