⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numfrm.cpp

📁 xiazai
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        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 + -