#pragma once #include enum ResultType { ResultConstant = 0, ResultCenter, ResultFirst, ResultSecond, ResultLength, ResultAngle, ResultTypeCount }; enum OperatorType { OperatorNone = 0, OperatorPlus, OperatorMinus, OperatorMulti, OperatorDiv, OperatorTypeCount }; class AFX_EXT_CLASS CFormulaItem { public: CFormulaItem() { Reset(); } void Reset() { nType = ResultConstant; nOperator = OperatorNone; dValue = 0.0; nIndex = -1; } int nType; int nOperator; double dValue; int nIndex; }; typedef std::vector VectorFormulaItem; typedef std::vector::iterator VectorFormulaItemIt; class AFX_EXT_CLASS CRecipeFormula { public: CRecipeFormula(void); ~CRecipeFormula(void); void Reset() { m_strResultName = _T(""); m_strFormulation = _T(""); m_vectorFormulaItem.clear(); } int GetItemCount() const; void SetItemCount(int nCount); const CFormulaItem* GetItem(int nIndex) const; void SetItem(int nIndex, const CFormulaItem& formulaItem); void AddItem(const CFormulaItem& formulaItem); double CalculateFormula() const ; static BOOL GetRecipeFormula(const CString& strString, CRecipeFormula& recipeFormula); static CString SetFormulaString(const CRecipeFormula& formula); CString m_strResultName; CString m_strFormulation; protected: VectorFormulaItem m_vectorFormulaItem; }; typedef std::vector VectorRecipeFormula; typedef std::vector::iterator VectorRecipeFormulaIt; class AFX_EXT_CLASS CResultFormula { public: CResultFormula(void); ~CResultFormula(void); void Reset() { m_nResultCode = 0; m_strResultName = _T(""); m_dResultValue = 0.0; } int m_nResultCode; CString m_strResultName; double m_dResultValue; }; typedef std::vector VectorResultFormula; typedef std::vector::iterator VectorResultFormulaIt; static void SetFormulaString(const CRecipeFormula& formula, CString& strString) { strString = _T(""); CString strTemp = _T(""); for (UINT i=0; i<(UINT)formula.GetItemCount(); i++) { const CFormulaItem* pItem = formula.GetItem(i); if (pItem==NULL) continue; if (pItem->nIndex>=0 && pItem->nType!=ResultConstant) { strTemp.Format(_T("[%c%d"), '%', pItem->nIndex); strString += strTemp; } else { strTemp.Format(_T("[")); strString += strTemp; } switch(pItem->nType) { case ResultConstant: strTemp.Format(_T("%.3lf]"), pItem->dValue); break; case ResultCenter: strTemp.Format(_T("_C]")); break; case ResultFirst: strTemp.Format(_T("_F]")); break; case ResultSecond: strTemp.Format(_T("_S]")); break; case ResultLength: strTemp.Format(_T("_L]")); break; case ResultAngle: strTemp.Format(_T("_A]")); break; } strString += strTemp; switch(pItem->nOperator) { case OperatorNone: strTemp = _T(""); break; case OperatorPlus: strTemp = _T("+"); break; case OperatorMinus: strTemp = _T("-"); break; case OperatorMulti: strTemp = _T("*"); break; case OperatorDiv: strTemp = _T("/"); break; } strString += strTemp; } } static BOOL GetFormulaString(const CString& strString, CRecipeFormula& recipeFomula) { recipeFomula.Reset(); int nFirst = 0; int nSecond = 0; BOOL bReturn = FALSE; // VectorFormulaItem vectorItem; while(TRUE) { nFirst = strString.Find(_T('['), nSecond); if (nFirst<0) break; nSecond = strString.Find(_T(']'), nFirst+1); if (nSecond<0) break; CString strValue = strString.Mid(nFirst+1, nSecond-nFirst-1); CFormulaItem item; item.nOperator = OperatorNone; if (nSecond+1 < strString.GetLength()) { TCHAR operation = strString.GetAt(nSecond+1); switch(operation) { case _T('+'): item.nOperator = OperatorPlus; break; case _T('-'): item.nOperator = OperatorMinus; break; case _T('*'): item.nOperator = OperatorMulti; break; case _T('/'): item.nOperator = OperatorDiv; break; } } // formula int nPos1 = strValue.Find(_T('_')); if (nPos1<0) { item.nType = ResultConstant; item.dValue = _tcstod(strValue, NULL); } else { // operation CString strType = strValue.Mid(nPos1+1, strValue.GetLength()-nPos1); if (strType.CompareNoCase(_T("C"))==0) { item.nType = ResultCenter; } if (strType.CompareNoCase(_T("F"))==0) { item.nType = ResultFirst; } if (strType.CompareNoCase(_T("S"))==0) { item.nType = ResultSecond; } if (strType.CompareNoCase(_T("L"))==0) { item.nType = ResultLength; } if (strType.CompareNoCase(_T("A"))==0) { item.nType = ResultAngle; } else { bReturn = FALSE; } // index int nPos2 = strValue.Find(_T('%')); if (nPos2<0) { bReturn = FALSE; } else { CString strTemp = strValue.Mid(nPos2+1, nPos1-nPos2-1); item.nIndex = _ttoi(strTemp); } } recipeFomula.AddItem(item); bReturn = TRUE; } return bReturn; }