| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559 | // describe elements#include "stdafx.h"#include "LanguageID.h"#include "MultiLang.h"#include "OTSSTDLib.h"#include <algorithm>namespace OTSClassifyEngine{	// CSTDBase	// constructor	CSTDBase::CSTDBase()	{		// initialization		Init();	}	CSTDBase::CSTDBase(const CSTDBase& a_oSource)	{		if (this == &a_oSource)		{			return;		}		Duplicate(a_oSource);	}	CSTDBase::CSTDBase(CSTDBase* a_poSource)	{		if (!a_poSource)		{			return;		}		if (this == a_poSource)		{			return;		}		Duplicate(*a_poSource);	}	CSTDBase::~CSTDBase()	{		Cleanup();	}	// =operator	CSTDBase& CSTDBase::operator=(const CSTDBase& a_oSource)	{		Cleanup();		Duplicate(a_oSource);		return *this;	}	// ==operator			BOOL CSTDBase::operator==(const CSTDBase& a_oSource)	{		return (m_iID == a_oSource.m_iID && 			m_strName == a_oSource.m_strName &&			m_strFormula == a_oSource.m_strFormula);	}	void CSTDBase::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)	{		/*CPosXray::Serialize(isStoring, classDoc, rootNode);		xmls::xInt xid;		xmls::xString xstrname;		xmls::xString xstrformula;		xmls::xDouble xddensity;		xmls::xDouble xdaverz;		xmls::xDouble xdbulkmod;		xmls::xDouble xdrigiditymod;		xmls::xInt xibrpl;		xmls::xInt xikind;		xmls::Slo slo;		slo.Register("id", &xid);		slo.Register("name", &xstrname);		slo.Register("formula", &xstrformula);		slo.Register("density", &xddensity);		slo.Register("averz", &xdaverz);		if (isStoring)		{			xid = m_iID;			xstrname = m_strName;			xstrformula = m_strFormula;			xddensity = m_dDensity;			xdaverz = m_dAverz;			slo.Serialize(true, classDoc, rootNode);		}		else		{			int iBRPL = 0;			int iKind = 0;			slo.Serialize(false, classDoc, rootNode);			m_iID = xid.value();			m_strName = xstrname.value().c_str();			m_strFormula = xstrformula.value().c_str();			m_dDensity = xddensity.value();			m_dAverz = xdaverz.value();		}*/	}	void CSTDBase::SetID(int iID)	{		m_iID = iID;	}	int CSTDBase::GetID()	{		return m_iID;	}	void CSTDBase::SetName(CString strName)	{		m_strName = strName;	}	CString CSTDBase::GetName()	{		return m_strName;	}	void CSTDBase::SetFormula(CString strFormula)	{		m_strFormula = strFormula;	}	CString CSTDBase::GetFormula()	{		return m_strFormula;	}	void CSTDBase::SetDensity(std::string dDensity)	{		m_dDensity = dDensity;	}	std::string CSTDBase::GetDensity()	{		return m_dDensity;	}	void CSTDBase::SetAvAltomicWeight(double dAvAltomicWeight)	{		m_dAverz = dAvAltomicWeight;	}	double CSTDBase::GetAvAltomicWeight()	{		return m_dAverz;	}	void CSTDBase::SetBulkmod(double dBulkmod)	{		m_dBulkmod = dBulkmod;	}	double CSTDBase::GetBulkmod()	{		return m_dBulkmod;	}	void CSTDBase::SetRigiditymod(double dRigiditymod)	{		m_dRigiditymod = dRigiditymod;	}	double CSTDBase::GetRigiditymod()	{		return m_dRigiditymod;	}	void CSTDBase::SetMineralBRPL(int iBRPL)	{		m_iBRPL = (MINERAL_BRPL)iBRPL;	}	void CSTDBase::SetMineralBRPL(CString strBRPL)	{		std::vector<CString> vecstrnames;		GetBRPLNames(vecstrnames);		m_iBRPL = MINERAL_BRPL::MINERAL_BR;		for (int i = 0; i < (int)vecstrnames.size(); i++)		{			if (strBRPL == vecstrnames[i])			{				m_iBRPL = (MINERAL_BRPL)i;				return;			}		}	}	int CSTDBase::GetMineralBRPL()	{		return (int)m_iBRPL;	}	CString CSTDBase::GetMineralBRPLName()	{		//		AFX_MANAGE_STATE(AfxGetStaticModuleState());		CString str = _T("");		//		str.LoadString(IDS_MINERAL_BRPL + (int)m_iBRPL);		str = MultiLang::GetInstance().GetCStringByKey(10,IDS_MINERAL_BRPL + (int)m_iBRPL);		return str;	}	void CSTDBase::GetBRPLNames(std::vector<CString>& vecstrnames)	{		//		AFX_MANAGE_STATE(AfxGetStaticModuleState());		CString str = _T("");		vecstrnames.clear();		for (int i = 0; i < (int)MINERAL_BRPL::MAX; i++)		{			//			str.LoadString(IDS_MINERAL_BRPL + i);			str = MultiLang::GetInstance().GetCStringByKey(10,IDS_MINERAL_BRPL + i);			vecstrnames.push_back(str);		}	}	void CSTDBase::SetMineralKind(int iKind)	{		m_iKind = (MINERAL_KINDS)iKind;	}	void CSTDBase::SetMineralKind(CString strKind)	{		std::vector<CString> vecstrnames;		GetKindNames(vecstrnames);		m_iKind = MINERAL_KINDS::MINERAL_SI;		for (int i = 0; i < (int)vecstrnames.size(); i++)		{			if (strKind == vecstrnames[i])			{				m_iKind = (MINERAL_KINDS)i;				return;			}		}	}	int CSTDBase::GetMineralKind()	{		return (int)m_iKind;	}	CString CSTDBase::GetMineralKindName()	{		//		AFX_MANAGE_STATE(AfxGetStaticModuleState());		CString str = _T("");		//		str.LoadString(IDS_MINERAL_KINDS + (int)m_iKind);		str = MultiLang::GetInstance().GetCStringByKey(10,IDS_MINERAL_KINDS + (int)m_iKind);		return str;	}	void CSTDBase::GetKindNames(std::vector<CString>& vecstrnames)	{		//		AFX_MANAGE_STATE(AfxGetStaticModuleState());		CString str = _T("");		vecstrnames.clear();		for (int i = 0; i < (int)MINERAL_KINDS::MAX; i++)		{			//			str.LoadString(IDS_MINERAL_KINDS + i);			str = MultiLang::GetInstance().GetCStringByKey(10,IDS_MINERAL_KINDS + i);			vecstrnames.push_back(str);		}	}				void CSTDBase::SetElementsList(const CElementsList& elementlist)	{		//		m_listElements = elementlist;		m_listElements.clear();		for (int i = 0; i <(int) elementlist.size(); i++)		{			m_listElements.push_back(elementlist[i]);		}	}	const CElementsList& CSTDBase::GetElementsList()	{		return m_listElements;	}	void CSTDBase::AddElement(const CElement& element)	{		// 判断是否存在		int i = 0;		for (i = 0; i < (int)m_listElements.size(); i++)		{			if ((*m_listElements[i]) == element)			{				break;			}		}		// 不存在就添加		if (i >= (int)m_listElements.size())		{			CElementPtr pMineral(new CElement(element));			m_listElements.push_back(pMineral);		}	}	void CSTDBase::RemoveElement(const CElement& element)	{		std::vector<CElementPtr>::iterator it;		for (it = m_listElements.begin(); it < m_listElements.end(); it++)		{			if (*((*it).get()) == element)			{				m_listElements.erase(it);				break;			}		}	}	void CSTDBase::RemoveAllElements()	{		m_listElements.clear();	}	CElementPtr CSTDBase::GetElement(int iIndex)	{		if (iIndex < 0 || iIndex >= GetElementCount())		{			return nullptr;		}		return m_listElements[iIndex];	}	int CSTDBase::GetElementCount()	{		return m_listElements.size();	}	void CSTDBase::Clear()	{		m_listElements.clear();	}	// cleanup 	void CSTDBase::Cleanup()	{		// nothing needs to be done at the moment	}	// initialization	void CSTDBase::Init()	{		m_iID = -1;		m_strName = _T("");		m_strFormula = _T("-");		m_dDensity = DENSITY_DEFAULT;		m_dAverz = AVALTOMICWEIGHT_MIN;				m_listElements.clear();	}	// duplication	void CSTDBase::Duplicate(const CSTDBase& a_oSource)	{		Init();		m_iID = a_oSource.m_iID;		m_strName = a_oSource.m_strName;		m_strFormula = a_oSource.m_strFormula;		m_dDensity = a_oSource.m_dDensity;		m_dAverz = a_oSource.m_dAverz;				for (auto poElement : a_oSource.m_listElements)		{			m_listElements.push_back(poElement);		}	}	CStandardItem::CStandardItem()	{		// initialization		Init();	}	CStandardItem::CStandardItem(const CStandardItem& a_oSource)	{		if (this == &a_oSource)		{			return;		}		Duplicate(a_oSource);	}	CStandardItem::CStandardItem(CStandardItem* a_poSource)	{		if (!a_poSource)		{			return;		}		if (this == a_poSource)		{			return;		}		Duplicate(*a_poSource);	}	CStandardItem::~CStandardItem()	{		Cleanup();	}	CStandardItem& CStandardItem::operator=(const CStandardItem& a_oSource)	{		Cleanup();		Duplicate(a_oSource);		return *this;	}	BOOL CStandardItem::operator==(const CStandardItem& a_oSource)	{		return CSTDBase::operator==(a_oSource);	}	void CStandardItem::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)	{		CSTDBase::Serialize(isStoring, classDoc, rootNode);		int i = 0;		xmls::xInt xicolor;		xmls::xInt xibse;		xmls::xInt xiclassify;		xmls::Collection<CElement> xElementList;		xmls::Slo slo;		slo.Register("color", &xicolor);		slo.Register("bse", &xibse);		slo.Register("classify", &xiclassify);		slo.Register("elements", &xElementList);		if (isStoring)		{			xicolor = m_iColor;			xibse = m_iBSEvalue;			xiclassify = m_iClassify;			xElementList.Clear();			for (i = 0; i < (int)m_listElements.size(); i++)			{				xElementList.addItem(m_listElements[i].get());			}			slo.Serialize(true, classDoc, rootNode);		}		else		{			slo.Serialize(false, classDoc, rootNode);			m_iColor = xicolor.value();			m_iBSEvalue = xibse.value();			m_iClassify = xiclassify.value();			m_listElements.clear();			for (i = 0; i < (int)xElementList.size(); i++)			{				m_listElements.push_back(CElementPtr(xElementList.getItem(i)));			}		}	}	void CStandardItem::SetColor(COLORREF iColor)	{		m_iColor = iColor;	}	COLORREF CStandardItem::GetColor()	{		return m_iColor;	}	void CStandardItem::SetBSEValue(int iBSEvalue)	{		m_iBSEvalue = iBSEvalue;	}	int CStandardItem::GetBSEValue()	{		return m_iBSEvalue;	}	void CStandardItem::SetClassify(int iClassify)	{		m_iClassify = iClassify;	}	int CStandardItem::GetClassify()	{		return m_iClassify;	}	BOOL CStandardItem::DoFormulaParser()	{		std::vector<CString> vecStrElementName;		std::vector<double> vecDElementCount;		if (DoFormulaParser(m_strFormula, vecStrElementName, vecDElementCount) < 0)		{			return false;		}		// vecStrElementName存放了m_strFormula里面的每个元素, vecDElementCount存放了每个元素的个数		ASSERT(vecStrElementName.size() == vecDElementCount.size());		RemoveAllElements();		for (auto strName : vecStrElementName)		{			CElementPtr* pElementPtr = new CElementPtr(new CElement(strName));			AddElement(*pElementPtr->get());		}		ASSERT(m_listElements.size() == vecDElementCount.size());		double dAllAtomicNumber = 0;		double dAllElementCount = 0;		double dAllAutomicWeight = 0;		double dwAvAltomicWeight = 0;		for (int i = 0; i <(int) m_listElements.size(); i++)		{			dAllAtomicNumber += m_listElements[i]->GetAtomNum() * vecDElementCount[i];			dAllElementCount += vecDElementCount[i];			dAllAutomicWeight += m_listElements[i]->GetAtomWeight() * vecDElementCount[i];		}		dwAvAltomicWeight = (0 == dAllElementCount) ? dAllAtomicNumber : dAllAtomicNumber / dAllElementCount;		// check the data is valid or not		if (dAllElementCount <= 0 || dwAvAltomicWeight < AVALTOMICWEIGHT_MIN || dwAvAltomicWeight > AVALTOMICWEIGHT_MAX)		{			return FALSE;		}		SetAvAltomicWeight(dwAvAltomicWeight);		// calc every element's percentage of mineralstd		for (int i = 0; i < (int)m_listElements.size(); i++)		{			m_listElements[i]->SetPercentage(100 * m_listElements[i]->GetAtomWeight() * vecDElementCount[i] / dAllAutomicWeight);		}		return TRUE;	}	CString CStandardItem::GetSTDMineralPropName(int iPropid)	{		return GetPropName(IDS_MINERAL_PROP, iPropid);	}	CString CStandardItem::GetElementPropName(int iPropid)	{		return GetPropName(IDS_ELEMENT_PROP, iPropid);	}	void CStandardItem::Cleanup()	{	}	// initialization	void CStandardItem::Init()	{		CSTDBase::Init();		CPosXray::Init();		m_iColor = RGB(255, 255, 255);		m_iBSEvalue = 0;		m_iClassify = -1;	}	// duplication	void CStandardItem::Duplicate(const CStandardItem& a_oSource)	{		CSTDBase::Duplicate(a_oSource);		CPosXray::Duplicate(a_oSource);		m_iColor = a_oSource.m_iColor;		m_iBSEvalue = a_oSource.m_iBSEvalue;		m_iClassify = a_oSource.m_iClassify;	}	int CStandardItem::DoFormulaParser(CString strFormula, std::vector<CString>& vecStrElementName, std::vector<double>& vecDElementCount)	{		int i = 0;		CString strCryWater = _T("");		strFormula.Trim();		// first delete the formula's "+", for example change formula "Fe2+4Fe3+8Sb12O23S2" to "Fe4Fe8Sb12O23S2" 		strFormula.Replace(_T("2+"), _T(""));		strFormula.Replace(_T("3+"), _T(""));		strFormula.Replace(_T("4+"), _T(""));		strFormula.Replace(_T("5+"), _T(""));		strFormula.Replace(_T("?"), _T("·")); // when formula has "?",replace "·"		strFormula.Replace(_T("¡¤"), _T("·"));// when formula's "¡¤" replace "·", it can be added "Â"		strFormula.Replace(_T("Â"), _T(""));	// so replace "Â" to ""		// second delete crystal water, for example change formula "KAl(SO4)2·12H2O" to "KAl(SO4)2"		if (strFormula.Find(_T("·")) > 0)		{			strCryWater = strFormula.Right(strFormula.GetLength() - strFormula.Find(_T("·")) - 1);			strCryWater.Replace(_T("("), _T(""));			strCryWater.Replace(_T(")"), _T(""));			for (i = 0; i < strCryWater.GetLength(); i++)			{				if (('.' == strCryWater.GetAt(i)) || (strCryWater.GetAt(i) >= '0' && strCryWater.GetAt(i) <= '9'))				{					i++;				}				else				{					break;				}			}			if (0 == i)			{				strCryWater = GetSubFormulaWithoutSymbol(_T("H2O"), 1);			}			else			{				strCryWater = GetSubFormulaWithoutSymbol(_T("H2O"), _tstof(strCryWater.Mid(0, i)));			}			strFormula = strFormula.Left(strFormula.Find(_T("·")));		}		struct STACK		{			int iSymbolIndex[10];	// Symbol at most 10			int iTop;			STACK()			{				memset(&iSymbolIndex, 0, 10 * sizeof(int));				iTop = -1;			}		};		STACK stack;		TCHAR sz;		CString strSubFormulaWithSymbol;		CString strSubFormulaWithoutSymbol;		int iLeftIndex = 0;		int iDigitalCount = 0;		i = 0;		// delete "()", "[]", "{}" from strFormula		while (1)		{			if (i >= strFormula.GetLength())			{				break;			}			sz = strFormula.GetAt(i);			// sz is left symbol			if ('(' == sz || '[' == sz || '{' == sz)			{				// save the symbol to stack				stack.iTop = stack.iTop + 1;				ASSERT(stack.iTop < 10);				stack.iSymbolIndex[stack.iTop] = i;			}			// sz is right symbol			else if (')' == sz || ']' == sz || '}' == sz)			{				double dRatio = GetRatioAfterRightSymbol(strFormula, i, iDigitalCount);				if (dRatio <= 0 || stack.iTop < 0)				{					return -1;				}				strSubFormulaWithSymbol = strFormula.Mid(stack.iSymbolIndex[stack.iTop] + 1, i - stack.iSymbolIndex[stack.iTop] - 1);				//				strSubFormulaWithoutSymbol = GetSubFormulaWithoutSymbol(strSubFormulaWithSymbol, dRatio);				strSubFormulaWithoutSymbol = (1.0 == dRatio) ? strSubFormulaWithSymbol : GetSubFormulaWithoutSymbol(strSubFormulaWithSymbol, dRatio);				iLeftIndex = strFormula.GetLength() - i - 1;				strFormula = strFormula.Left(stack.iSymbolIndex[stack.iTop]) + strSubFormulaWithoutSymbol + strFormula.Right(strFormula.GetLength() - i - iDigitalCount - 1);				i = strFormula.GetLength() - iLeftIndex - 1;				stack.iTop = stack.iTop - 1;			}			i++;		}		// the formula (have deleted symbol) add crywater		strFormula = strFormula + strCryWater;		return DoFormulaParser_ext(strFormula, vecStrElementName, vecDElementCount);	}	int CStandardItem::DoFormulaParser_ext(CString strFormula, std::vector<CString>& vecStrElementName, std::vector<double>& vecDElementCount)	{		CString strElementName;		double dElementCount = 0;		int iIndex = 0;		int iDigitCount = 0;		vecStrElementName.clear();		vecDElementCount.clear();		///////////////////////////////////////////		// strFormula  may be CH, CH2, CH2.34, C2H, C2H3, C2H2.33, C2.34H, C2.34H2, C2.34H2.22, 		// CaH, CaH2, CaH2.34, Ca2H, Ca2H3, Ca2H2.33, Ca2.34H, Ca2.34H2, Ca2.34H2.22, 		//////////////////////////////////////////		while (1)		{			if (strFormula.GetLength() <= 0)			{				break;			}			iIndex = 0;			iDigitCount = 0;			if (strFormula.GetAt(0) >= 'A' && strFormula.GetAt(0) <= 'Z')			{				for (iIndex = 1; iIndex < strFormula.GetLength(); iIndex++)				{					if (('.' == strFormula.GetAt(iIndex)) || (strFormula.GetAt(iIndex) >= '0' && strFormula.GetAt(iIndex) <= '9'))					{						iDigitCount++;					}					else					{						break;					}				}				// strFormula's elementname is C or Ca or Ca2 or Ca0.33 or CH				if (1 == iIndex)				{					// it is only C					if (1 == strFormula.GetLength())					{						strElementName = strFormula.Mid(0, 1);						AddElementAndCount(vecStrElementName, vecDElementCount, strElementName, 1);						break;					}					// the length() >= 2, strFormula's elementname is Ca or Ca2 or Ca0.33 or CH					else					{						// Get the second char						// the second char is a-z, so strFormula's elementname is Ca or Ca2 or Ca0.33						if (strFormula.GetAt(1) >= 'a' && strFormula.GetAt(1) <= 'z')						{							for (iIndex = 2; iIndex < strFormula.GetLength(); iIndex++)							{								if (('.' == strFormula.GetAt(iIndex)) || (strFormula.GetAt(iIndex) >= '0' && strFormula.GetAt(iIndex) <= '9'))								{									iDigitCount++;								}								else								{									break;								}							}							// the second char is a-z, so strFormula's elementname is Ca							if (2 == iIndex)							{								strElementName = strFormula.Mid(0, 2);								AddElementAndCount(vecStrElementName, vecDElementCount, strElementName, 1);								// delete the elementname from strFormula								strFormula = strFormula.Right(strFormula.GetLength() - 2);							}							else							{								if (0 == iDigitCount)								{									return -1;								}								// the second char is a-z, so strFormula's elementname is Ca2 or Ca0.33								else								{									if (strFormula.GetAt(2) >= '0' && strFormula.GetAt(2) <= '9')									{										strElementName = strFormula.Mid(0, 2);										dElementCount = _tstof(strFormula.Mid(2, iDigitCount));										if (dElementCount <= 0)										{											return -1;										}										AddElementAndCount(vecStrElementName, vecDElementCount, strElementName, dElementCount);										strFormula = strFormula.Right(strFormula.GetLength() - 2 - iDigitCount);									}									else									{										return -1;									}								}							}						}						// the second char is A-Z, so strFormula's elementname is CH, Get C						else if (strFormula.GetAt(1) >= 'A' && strFormula.GetAt(1) <= 'Z')						{							strElementName = strFormula.Mid(0, 1);							AddElementAndCount(vecStrElementName, vecDElementCount, strElementName, 1);							// delete the elementname from strFormula							strFormula = strFormula.Right(strFormula.GetLength() - 1);						}						else						{							return -1;						}					}				}				// iIndex > 1				else				{					if (0 == iDigitCount)					{						return -1;					}					// the length() >= 2, strFormula's elementname is C2 or C2.33					else					{						// strFormula's elementname is C2 or C2.33						if (strFormula.GetAt(1) >= '0' && strFormula.GetAt(1) <= '9')						{							strElementName = strFormula.Mid(0, 1);							dElementCount = _tstof(strFormula.Mid(1, iDigitCount));							if (dElementCount <= 0)							{								return -1;							}							AddElementAndCount(vecStrElementName, vecDElementCount, strElementName, dElementCount);							strFormula = strFormula.Right(strFormula.GetLength() - 1 - iDigitCount);						}						else						{							return -1;						}					}				}			}			else			{				return -1;			}		}		return 0;	}	void CStandardItem::AddElementAndCount(std::vector<CString>& vecStrElementName, std::vector<double>& vecDElementCount, CString strElementName, double dElementCount)	{		size_t i = 0;		for (i = 0; i < vecStrElementName.size(); i++)		{			if (0 == vecStrElementName[i].Compare(strElementName))			{				break;			}		}		// the elementname has existed, only update elementcount		if (i < vecStrElementName.size())		{			vecDElementCount[i] = vecDElementCount[i] + dElementCount;		}		// the elementname has not exist, add it		else		{			vecStrElementName.push_back(strElementName);			vecDElementCount.push_back(dElementCount);		}	}	double CStandardItem::GetRatioAfterRightSymbol(CString strFormula, int iRightSymbolIndex, int& iDigitalCount)	{		CString strSubFormula = strFormula.Right(strFormula.GetLength() - iRightSymbolIndex - 1);		TCHAR sz;		sz = strSubFormula.GetAt(0);		iDigitalCount = 0;		// after formula' right symbol is 'A'-'Z'(1), '(', '[', '{'(1), '0'-'9'(??), other(-1,error)		// sz is 0-9		if (sz >= '0' && sz <= '9')		{			int i = 0;			for (i = 0; i < strSubFormula.GetLength(); i++)			{				if (('.' == strSubFormula.GetAt(i)) || (strSubFormula.GetAt(i) >= '0' && strSubFormula.GetAt(i) <= '9'))				{					iDigitalCount++;				}				else				{					break;				}			}			CString str = strSubFormula.Mid(0, iDigitalCount);			return _tstof(str);		}		// sz is A-Z		else if (sz >= 'A' && sz <= 'Z')		{			return 1;		}		// sz is '(', '[', '{'		else if ('(' == sz || '[' == sz || '{' == sz || '·' == sz || ')' == sz || ']' == sz || '}' == sz)		{			return 1;		}		// the last of formula is ')', so return 1		else if ('\0' == sz)		{			return 1;		}		// sz is other char		else		{			return -1;		}	}	CString CStandardItem::GetSubFormulaWithoutSymbol(CString strSubFormulaWithSymbol, double dRatio)	{		std::vector<CString> vecStrElementName;		std::vector<double> vecDElementCount;		if (DoFormulaParser_ext(strSubFormulaWithSymbol, vecStrElementName, vecDElementCount) < 0)		{			return _T("");		}		ASSERT(vecStrElementName.size() == vecDElementCount.size());		CString strSubFormula;		CString strSubFormulaWithoutSymbol = _T("");		for (size_t i = 0; i < vecStrElementName.size(); i++)		{			strSubFormula.Format(_T("%s%.2f"), vecStrElementName[i], vecDElementCount[i] * dRatio);			strSubFormulaWithoutSymbol = strSubFormulaWithoutSymbol + strSubFormula;		}		return strSubFormulaWithoutSymbol;	}	CString CStandardItem::GetPropName(int iStartPropid, int iPropid)	{		return MultiLang::GetInstance().GetCStringByKey(10,iStartPropid + iPropid);	}	CClassify::CClassify()	{		Init();	}	CClassify::CClassify(const CClassify& a_oSource)	{		// 自赋值		if (this == &a_oSource)		{			return;		}		Duplicate(a_oSource);	}	CClassify::CClassify(CClassify* a_poSource)	{		if (!a_poSource)		{			return;		}		if (this == a_poSource)		{			return;		}		Duplicate(*a_poSource);	}	CClassify::~CClassify()	{		Cleanup();	}	CClassify& CClassify::operator=(const CClassify& a_oSource)	{		Duplicate(a_oSource);		return *this;	}	BOOL CClassify::operator==(const CClassify& a_oSource)	{		return (m_strName == a_oSource.m_strName);	}	void CClassify::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)	{		/*xmls::xInt xid;		xmls::xString xstrname;		xmls::xInt xicolor;		xmls::xInt xiorder;		xmls::Slo slo;		slo.Register("classify", &xid);		slo.Register("name", &xstrname);		slo.Register("color", &xicolor);		slo.Register("order", &xiorder);		if (isStoring)		{			xid = m_iID;			xstrname = m_strName;			xicolor = m_iColor;			xiorder = m_iOrder;			slo.Serialize(true, classDoc, rootNode);		}		else		{			slo.Serialize(false, classDoc, rootNode);			m_iID = xid.value();			m_strName = xstrname.value().c_str();			m_iColor = xicolor.value();			m_iOrder = xiorder.value();		}*/	}	void CClassify::SetID(int iID)	{		m_iID = iID;	}	int CClassify::GetID()	{		return m_iID;	}	void CClassify::SetName(CString strName)	{		m_strName = strName;	}	CString CClassify::GetName()	{		return m_strName;	}	void CClassify::SetColor(COLORREF iColor)	{		m_iColor = iColor;	}	COLORREF CClassify::GetColor()	{		return m_iColor;	}	void CClassify::SetOrder(int iOrder)	{		m_iOrder = iOrder;	}	int CClassify::GetOrder()	{		return m_iOrder;	}	void CClassify::Init()	{		m_iID = -1;		m_strName = _T("");		m_iColor = RGB(255, 255, 255);		m_iOrder = -1;	}	void CClassify::Cleanup()	{	}	void CClassify::Duplicate(const CClassify& a_oSource)	{		m_iID = a_oSource.m_iID;		m_strName = a_oSource.m_strName;		m_iColor = a_oSource.m_iColor;		m_iOrder = a_oSource.m_iOrder;	}	CSTDLib::CSTDLib()	{		// initialization		Init();	}	CSTDLib::CSTDLib(const CSTDLib& a_oSource)	{		if (this == &a_oSource)		{			return;		}		Duplicate(a_oSource);	}	CSTDLib::CSTDLib(CSTDLib* a_poSource)	{		if (!a_poSource)		{			return;		}		if (this == a_poSource)		{			return;		}		Duplicate(*a_poSource);	}	CSTDLib::~CSTDLib()	{		Cleanup();	}	void CSTDLib::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)	{		/*int i = 0;		xmls::xString xstrname;		xmls::Collection<CStandardItem> xSTDItemList;		xmls::Collection<CClassify> xClassifyList;		xmls::Slo slo;		slo.Register("name", &xstrname);		slo.Register("stdminerals", &xSTDItemList);		slo.Register("classify", &xClassifyList);		if (isStoring)		{			xstrname = m_strName;			xSTDItemList.Clear();			xClassifyList.Clear();			for (i = 0; i < (int)m_listSTDItems.size(); i++)			{				xSTDItemList.addItem(m_listSTDItems[i].get());			}			for (i = 0; i < (int)m_listClassify.size(); i++)			{				xClassifyList.addItem(m_listClassify[i].get());			}			slo.Serialize(true, classDoc, rootNode);		}		else		{			slo.Serialize(false, classDoc, rootNode);			m_strName = xstrname.value().c_str();			m_listSTDItems.clear();			m_listClassify.clear();			for (i = 0; i < (int)xSTDItemList.size(); i++)			{				m_listSTDItems.push_back(CStandardItemPtr(xSTDItemList.getItem(i)));			}			for (i = 0; i < (int)xClassifyList.size(); i++)			{				m_listClassify.push_back(CClassifyPtr(xClassifyList.getItem(i)));			}		}*/	}	CSTDLib& CSTDLib::operator= (const CSTDLib& a_oSource)	{		Cleanup();		Duplicate(a_oSource);		return *this;	}	BOOL CSTDLib::operator== (const CSTDLib& a_oSource)	{		return (m_strName == a_oSource.m_strName && 			m_listSTDItems.size() == a_oSource.m_listSTDItems.size() &&			m_listClassify.size() == a_oSource.m_listClassify.size());	}	void CSTDLib::SetName(CString strName)	{		m_strName = strName;	}	CString CSTDLib::GetName()	{		return m_strName;	}	bool CSTDLib::AddItem(CStandardItem stdMineral)	{		int i = 0;		for (i = 0; i < (int)m_listSTDItems.size(); i++)		{			if (*(m_listSTDItems[i]) == stdMineral)			{				break;			}		}		// 不存在就添加		if (i >=(int) m_listSTDItems.size())		{			CStandardItemPtr pSTDMineral(new CStandardItem(stdMineral));			m_listSTDItems.push_back(pSTDMineral);			return true;		}		return false;	}	// 从0开始数, 在第iIndex位置之前插入一个记录	bool CSTDLib::InsertItem(CStandardItem stdMineral, int iIndex)	{		if (iIndex >(int) m_listSTDItems.size() || iIndex < 0)		{			return false;		}		int i = 0;		for (i = 0; i <(int) m_listSTDItems.size(); i++)		{			if (*(m_listSTDItems[i]) == stdMineral)			{				break;			}		}		// 不存在就插入		if (i >= (int)m_listSTDItems.size())		{			CStandardItemPtr pSTDMineral(new CStandardItem(stdMineral));			m_listSTDItems.insert(m_listSTDItems.begin() + iIndex, pSTDMineral);			return true;		}		return false;	}	void CSTDLib::RemoveItem(const CStandardItem& stdMineral)	{		std::vector<CStandardItemPtr>::iterator it;		for (it = m_listSTDItems.begin(); it < m_listSTDItems.end(); it++)		{			if (*((*it).get()) == stdMineral)			{				m_listSTDItems.erase(it);				break;			}		}	}	CStandardItemPtr CSTDLib::GetSTDItem(int iIndex)	{		if (iIndex < 0 || iIndex >= GetSTDItemCount())		{			return nullptr;		}		return m_listSTDItems[iIndex];	}	void CSTDLib::SwapItem(CStandardItem* pstdMineral1, CStandardItem* pstdMineral2)	{		if (NULL == pstdMineral1 || NULL == pstdMineral2)		{			return;		}		// 交换pstdMineral1和pstdMineral2的ID即可		int id1 = pstdMineral1->GetID();		int id2 = pstdMineral2->GetID();		pstdMineral1->SetID(id2);		pstdMineral2->SetID(id1);		// 此时m_listSTDMinerals里面的数据顺序已经发生了改变(原来设计按照ID从小到大的顺序排列)		// 此时要重新排序		std::sort(m_listSTDItems.begin(), m_listSTDItems.end(), [&](const CStandardItemPtr& ptr1, const CStandardItemPtr& ptr2)-> int		{			return ptr1->GetID() < ptr2->GetID();		});	}	void CSTDLib::SortByItemID(BOOL bAsc/* = TRUE*/)	{		if (bAsc)		{			std::sort(m_listSTDItems.begin(), m_listSTDItems.end(), [&](const CStandardItemPtr& ptr1, const CStandardItemPtr& ptr2)-> int			{				return ptr1->GetID() < ptr2->GetID();			});		}		else		{			std::sort(m_listSTDItems.begin(), m_listSTDItems.end(), [&](const CStandardItemPtr& ptr1, const CStandardItemPtr& ptr2)-> int			{				return ptr1->GetID() > ptr2->GetID();			});		}	}	int CSTDLib::GetSTDItemCount()	{		return m_listSTDItems.size();	}	void CSTDLib::Clear()	{		for (int i = 0; i < (int)m_listSTDItems.size(); i++)		{			m_listSTDItems[i]->Clear();		}		// m_strName = _T("");		m_listSTDItems.clear();		m_listClassify.clear();	}	CString CSTDLib::GetValidItemName(CString strFormat)	{		int i = 1;		CString strName = _T("");		strName.Format(_T("%s%d"), strFormat, i);		for (int j = 0; j < (int)m_listSTDItems.size(); j++)		{			if (0 == strName.CompareNoCase(m_listSTDItems[j]->GetName()))			{				strName.Format(_T("%s%d"), strFormat, ++i);				j = -1;	// 不可以为0因为会自动j++			}		}		return strName;	}	CString CSTDLib::GetDifferItemName(CString strMineralName)	{		int iCount = 1;		CString strNewName = strMineralName;		while (HasSameItemName(strNewName))		{			strNewName.Format(_T("%s_%d"), strMineralName, iCount++);		}		return strNewName;	}	bool CSTDLib::AddClassify(CClassify classify)	{		int i = 0;		for (i = 0; i < (int)m_listClassify.size(); i++)		{			if (*(m_listClassify[i]) == classify)			{				break;			}		}		// 不存在就添加		if (i >= (int)m_listClassify.size())		{			CClassifyPtr pClassify(new CClassify(classify));			m_listClassify.push_back(pClassify);			return true;		}		return false;	}	void CSTDLib::RemoveClassify(const CClassify& classify)	{		std::vector<CClassifyPtr>::iterator it;		for (it = m_listClassify.begin(); it < m_listClassify.end(); it++)		{			if (*((*it).get()) == classify)			{				m_listClassify.erase(it);				break;			}		}	}	int CSTDLib::GetClassifyCount()	{		return m_listClassify.size();	}	CString CSTDLib::GetClassifyName(int iClassify)	{		for (int i = 0; i < (int)m_listClassify.size(); i++)		{			if (iClassify == m_listClassify[i]->GetID())			{				return m_listClassify[i]->GetName();			}		}		return _T("");	}	void CSTDLib::GetClassifyNames(std::vector<CString>& vecstrnames)	{		vecstrnames.clear();		vecstrnames.push_back(_T(""));		for (int i = 0; i < (int)m_listClassify.size(); i++)		{			vecstrnames.push_back(m_listClassify[i]->GetName());		}	}	CString CSTDLib::GetDifferClassifyName(CString strClassifyName)	{		int iCount = 1;		CString strNewName = strClassifyName;		while (HasSameClassifyName(strNewName))		{			strNewName.Format(_T("%s_%d"), strClassifyName, iCount++);		}		return strNewName;	}	CClassifyPtr CSTDLib::GetClassifyPtr(int iIndex)	{		if (iIndex < 0 || iIndex >= GetClassifyCount())		{			return nullptr;		}		return m_listClassify[iIndex];	}	CClassifyPtr CSTDLib::GetClassifyPtr(CString strClassifyName)	{		for (int i = 0; i < GetClassifyCount(); i++)		{			if (strClassifyName == m_listClassify[i]->GetName())			{				return m_listClassify[i];			}		}		return nullptr;	}	void CSTDLib::SwapClassifyOrder(CClassify* pclassify1, CClassify* pclassify2)	{		if (NULL == pclassify1 || NULL == pclassify2)		{			return;		}		// 交换pstdMineral1和pstdMineral2的ID即可		int id1 = pclassify1->GetOrder();		int id2 = pclassify2->GetOrder();		pclassify1->SetOrder(id2);		pclassify2->SetOrder(id1);		// 此时m_listClassify里面的数据顺序已经发生了改变(原来设计按照ID从小到大的顺序排列)		// 此时要重新排序		std::sort(m_listClassify.begin(), m_listClassify.end(), [&](const CClassifyPtr& ptr1, const CClassifyPtr& ptr2)-> int		{			return ptr1->GetOrder() < ptr2->GetOrder();		});	}	void CSTDLib::LoadStrFromXml()	{		MultiLang::GetInstance().LoadStringFromXml();	}	CString CSTDLib::GetSTDLibPropName(int iPropid)	{//		AFX_MANAGE_STATE(AfxGetStaticModuleState());		CString str = _T("");//		str.LoadString(IDS_ORETYPE_PROP + iPropid);		str = MultiLang::GetInstance().GetCStringByKey(10,IDS_ORETYPE_PROP + iPropid);		return str;	}	bool CSTDLib::HasSameItemName(CString strMineralName)	{		for (int i = 0; i < (int)m_listSTDItems.size(); i++)		{			if (0 == strMineralName.CompareNoCase(m_listSTDItems[i]->GetName()))			{				return true;			}		}		return false;	}	bool CSTDLib::HasSameClassifyName(CString strClassifyName)	{		for (int i = 0; i < (int)m_listClassify.size(); i++)		{			if (0 == strClassifyName.CompareNoCase(m_listClassify[i]->GetName()))			{				return true;			}		}		return false;	}	// cleanup 	void CSTDLib::Cleanup()	{	}	// initialization	void CSTDLib::Init()	{		m_strName = _T("");		m_listSTDItems.clear();	}	// duplication	void CSTDLib::Duplicate(const CSTDLib& a_oSource)	{		Init();		m_strName = a_oSource.m_strName;		for (int i = 0; i < (int)a_oSource.m_listSTDItems.size(); i++)		{			m_listSTDItems.push_back(a_oSource.m_listSTDItems[i]); 		}	}}
 |