#include "stdafx.h" #include "AccountAreaDlg.h" // 根据“基本设定”获得“房间面积”保留的小数位数 CString GetAreaText(double dUseArea) { CString csArea; int nPrecisionNum = DocGetSpaceAreaPrecision(); // 小数部分的精确度 switch(nPrecisionNum) { case 0: csArea.Format(_T("%.0f"), dUseArea); break; case 1: csArea.Format(_T("%.1f"), dUseArea); break; case 2: csArea.Format(_T("%.2f"), dUseArea); break; case 3: csArea.Format(_T("%.3f"), dUseArea); break; case 4: csArea.Format(_T("%.4f"), dUseArea); break; case 5: csArea.Format(_T("%.5f"), dUseArea); break; case 6: csArea.Format(_T("%.6f"), dUseArea); break; case 7: csArea.Format(_T("%.7f"), dUseArea); break; case 8: csArea.Format(_T("%.8f"), dUseArea); break; default: csArea.Format(_T("%.2f"), dUseArea); break; } return csArea; } CAccountAreaDlg::CAccountAreaDlg(CWnd* pParent) : CModelessDialog(CAccountAreaDlg::IDD, pParent) { m_sExpression=_T(""); m_dResult=0; m_bUseEsc=TRUE; // m_nPath=0; m_ePath=eSelectFirst; m_nCursStart=0; m_nCursEnd=0; } void CAccountAreaDlg::DoDataExchange(CDataExchange* pDX) { CModelessDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_EXPRESSION, m_editExpression); } BEGIN_MESSAGE_MAP(CAccountAreaDlg, CModelessDialog) ON_EN_KILLFOCUS(IDC_EDIT_EXPRESSION, OnKillFocus) ON_BN_CLICKED(IDC_BUTTON_C, OnC) ON_BN_CLICKED(IDC_BUTTON_POINT, OnPoint) ON_BN_CLICKED(IDC_BUTTON_ADD, OnAdd) ON_BN_CLICKED(IDC_BUTTON_DE, OnDe) ON_BN_CLICKED(IDC_BUTTON_AMOUNT,OnAmount) ON_BN_CLICKED(IDC_BUTTON_ZERO, OnZero) ON_BN_CLICKED(IDC_BUTTON_ONE, OnOne) ON_BN_CLICKED(IDC_BUTTON_TWO, OnTwo) ON_BN_CLICKED(IDC_BUTTON_THREE, OnThree) ON_BN_CLICKED(IDC_BUTTON_FOUR, OnFour) ON_BN_CLICKED(IDC_BUTTON_FIVE, OnFive) ON_BN_CLICKED(IDC_BUTTON_SIX, OnSix) ON_BN_CLICKED(IDC_BUTTON_SEVEN, OnSeven) ON_BN_CLICKED(IDC_BUTTON_EIGHT,OnEight) ON_BN_CLICKED(IDC_BUTTON_NINE, OnNine) ON_BN_CLICKED(IDC_BUTTON_LABEL,OnLabel) ON_BN_CLICKED(IDC_BUTTON_SELAREA,OnSelArea) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BTN_LEFT_BRACKET, OnLeftBracket) ON_BN_CLICKED(IDC_BTN_RIGHT_BRACKET, OnRightBracket) ON_BN_CLICKED(IDC_BTN_MULTIPLY, OnMultiply) ON_BN_CLICKED(IDC_BTN_DIV, OnDivision) ON_BN_CLICKED(IDC_BTN_BACK, OnBackspace) END_MESSAGE_MAP() BOOL CAccountAreaDlg::OnInitDialog() { CModelessDialog::OnInitDialog(); AddTip(IDC_BTN_BACK, _T("退格")); AddTip(IDC_BUTTON_C, _T("清空")); return TRUE; } BOOL CAccountAreaDlg::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN) { if (pMsg->wParam == VK_RETURN) { return TRUE; } } return CModelessDialog::PreTranslateMessage(pMsg); } // void CAccountAreaDlg::SetCurs(int nStart,int nEnd) void CAccountAreaDlg::SetCurs() { m_editExpression.GetSel(m_nCursStart, m_nCursEnd); // modified by lgh on 100729 // 当前的位置只由编辑框觉得,外边不应该设置 // if (nStart>nEnd) // m_editExpression.SetSel(nEnd,nStart); // else // m_editExpression.SetSel(nStart,nEnd); } BOOL CAccountAreaDlg::CalcResult() { m_editExpression.GetWindowText(m_sExpression); CExpressionParser::EErrorStat eStat = CExpressionParser::Expression_Parser(m_sExpression, m_dResult); if (eStat != CExpressionParser::eOk) { // 还要处理操作数的识别问题(第一个数是操作数(正数和负数) CAcModuleResourceOverride vTemp; ::MessageBox(0, _T("输入有错误,请检查后重新计算!"), _T("输入错误"), MB_OK); return FALSE; } return TRUE; } BOOL CAccountAreaDlg::Amount() { if (!CalcResult()) { return FALSE; } m_sExpression.Empty(); m_sExpression.Format(_T("%lf"),m_dResult); m_nCursStart = m_sExpression.GetLength(); m_nCursEnd = m_nCursStart; m_editExpression.SetWindowText(m_sExpression); m_editExpression.SetSel(m_nCursStart, m_nCursEnd); UpdateData(FALSE); return TRUE; } BOOL CAccountAreaDlg::IsNoneSelect() { m_editExpression.GetWindowText(m_sExpression); return m_sExpression == _T(""); } void CAccountAreaDlg::SetAreaState(EAreaStat eState) { if (m_ePath == eState) return; if (eState == eSelect) { OnSelArea(); } else { OnLabel(); } } void CAccountAreaDlg::OnKillFocus() { UpdateData(TRUE); m_editExpression.GetSel(m_nCursStart,m_nCursEnd); } void CAccountAreaDlg::OnLabel() { UpdateData(TRUE); // if (m_nPath==1) // return; // m_nPath=1; // if (m_ePath==eDrawText) // return; if (!Amount()) return; m_ePath=eDrawText; m_bUseEsc=FALSE; acedPostCommand(_T("\33")); } void CAccountAreaDlg::OnSelArea() { UpdateData(TRUE); // if (m_nPath==0) // return; // m_nPath=0; if (m_ePath==eSelect) return; m_ePath=eSelect; m_bUseEsc=FALSE; acedPostCommand(_T("\33")); } void CAccountAreaDlg::OnC() { // modified by lgh, 该键的功能改为:清空编辑框中的内容 // m_editExpression.GetWindowText(m_sExpression); // long nLen=m_sExpression.GetLength(); // if (nLen<1) // return; // // if (m_nCursStart<1) // return; // if (m_nCursStart==m_nCursEnd) // { // m_sExpression.Delete(m_nCursStart-1); // m_nCursStart-=1; // } // else // { // m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); // } // m_nCursEnd=m_nCursStart; // m_editExpression.SetWindowText(m_sExpression); // UpdateData(FALSE); m_editExpression.SetWindowText(_T("")); m_sExpression = _T(""); m_nCursStart = m_nCursEnd = 0; } //void CAccountAreaDlg::InsertData(int nBegin,CString str) void CAccountAreaDlg::InsertData(CString sInsert) { // modified by lgh,原函数的实现繁琐,插入数据不能由外部指定位置(edit中维护有当前位置) // if (nBegin<0) // return; // m_editExpression.GetWindowText(m_sExpression); // m_sExpression.Insert(nBegin,str); // m_nCursStart=m_nCursStart+str.GetLength(); // m_nCursEnd=m_nCursStart; // m_editExpression.SetWindowText(m_sExpression); // UpdateData(FALSE); // 判断当前位置 前边的那个字符是否为运算符,如果没有则添加一个运算法,在添加字符串,否则不用添加 // m_editExpression.GetSel(m_nCursStart, m_nCursEnd); if ((m_nCursStart > 0) && (m_nCursStart <= m_nCursEnd)) { // 当前没有selection,并且光标不在编辑框起始处 m_editExpression.GetWindowText(m_sExpression); if (!IsOperationSymbol(m_sExpression[m_nCursStart-1]) && (m_sExpression[m_nCursStart-1]) != '(') sInsert = _T("+") + sInsert;// 该字符前添加加号 } // 处理完毕直接替换 m_editExpression.SetSel(m_nCursStart, m_nCursEnd); m_editExpression.ReplaceSel(sInsert); m_editExpression.GetSel(m_nCursStart, m_nCursEnd); } void CAccountAreaDlg::OnPoint() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T(".")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnAdd() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("+")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnDe() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("-")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnAmount() { // 由于添加了乘除法,以及括号,原先的算法不能继续使用 // 特引进算术表达式的解析函数,专门处理算术表达式字符串 // m_editExpression.GetWindowText(m_sExpression); // m_sExpression.Replace(_T("-"),_T("+-")); // sg modify 091104,解决字符串较长或者框选的面积对象较多时,累加结果不正确的问题 /* // 字符转换:CString->char* #if ADS>16 char szBuffer[256] = {0}; WideCharToMultiByte( CP_ACP, 0, m_sExpression, -1,szBuffer, 256, NULL, NULL ); #else LPSTR szBuffer=(LPSTR)(LPCTSTR)m_sExpression; #endif //字符串分割 char *p; const char* split="+"; p=strtok(szBuffer,split); while(p!=NULL) { CString strTemp=p; m_dResult+=_tstof(strTemp); p=strtok(NULL,split); } */ /* // 不转化为char,直接用cstring查找“+” CString csTmp = m_sExpression; int nRet = csTmp.Find(_T("+"), 0); while (nRet > -1) // 首位是“+”号的情况,相当于加了0 { CString csNum; csNum = csTmp.Left(nRet); m_dResult += _tstof(csNum); int nLength = csTmp.GetLength(); csTmp = csTmp.Right(nLength-nRet-1); nRet = csTmp.Find(_T("+"), 0); } m_dResult += _tstof(csTmp); m_sExpression.Empty(); m_sExpression.Format(_T("%lf"),m_dResult); m_dResult = 0; m_nCursStart = m_sExpression.GetLength(); m_nCursEnd = m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); */ Amount(); } void CAccountAreaDlg::OnClose() { m_bUseEsc=TRUE; acedPostCommand(_T("\33")); } void CAccountAreaDlg::OnZero() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("0")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnOne() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("1")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnTwo() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("2")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnThree() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("3")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnFour() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("4")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnFive() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("5")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnSix() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("6")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnSeven() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("7")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnEight() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("8")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnNine() { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,_T("9")); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::AddText(LPCTSTR sText) { m_editExpression.GetWindowText(m_sExpression); m_sExpression.Delete(m_nCursStart,m_nCursEnd-m_nCursStart); m_sExpression.Insert(m_nCursStart,sText); m_nCursStart++; m_nCursEnd=m_nCursStart; m_editExpression.SetWindowText(m_sExpression); UpdateData(FALSE); } void CAccountAreaDlg::OnLeftBracket() { AddText(_T("(")); } void CAccountAreaDlg::OnRightBracket() { AddText(_T(")")); } void CAccountAreaDlg::OnMultiply() { AddText(_T("*")); } void CAccountAreaDlg::OnDivision() { AddText(_T("/")); } void CAccountAreaDlg::OnBackspace() { m_editExpression.SetSel(m_nCursStart, m_nCursEnd); if (m_nCursStart != m_nCursEnd) { // 当前存在selection,删除Selection m_editExpression.Clear(); } else { if (m_nCursStart != 0) { // 如果不在第一个字符,则删除一个元素 m_editExpression.SetSel(m_nCursStart-1, m_nCursStart); m_editExpression.Clear(); } } m_editExpression.GetSel(m_nCursStart, m_nCursEnd); } BOOL CAccountAreaDlg::IsOperationSymbol(TCHAR ch) const { const int nNum = 4; TCHAR symbols[nNum] = {_T('+'), _T('-'), _T('*'), _T('/')}; for (int i = 0; i < nNum; i++) { if (ch == symbols[i]) return TRUE; } return FALSE; } bool CAccountAreaContext::m_bCMD = true; // 初始是命令行模式。 CAccountAreaContext::CAccountAreaContext() : m_pDlg(NULL), m_bCancel(FALSE), m_bSwitch(true) { Init(); if (m_bCMD) { m_eCmdState = eCMDSelectFirst; } else { CreateDlg(this); // == 进入对话框模式。 } } CAccountAreaContext::~CAccountAreaContext() { Reset(); m_bCMD = IsCMDModel() ? true : false; // 退出时,记录模式。 if (m_pDlg != NULL) { if (IsWindow(m_pDlg->m_hWnd)) { m_pDlg->DestroyWindow(); } delete m_pDlg; m_pDlg = NULL; } m_ssAreaAll.Redraw(4); } void CAccountAreaContext::Init() { xg_getvar(_T("SHORTCUTMENU"), &m_nSysVar); xg_setvar(_T("SHORTCUTMENU"), 1); // 0x0001,关闭右键快捷菜单 } void CAccountAreaContext::Reset() { xg_setvar(_T("SHORTCUTMENU"), m_nSysVar); } void CAccountAreaContext::SetCancel(BOOL b ) { m_bCancel = b; } BOOL CAccountAreaContext::GetCancel() { return m_bCancel; } void CAccountAreaContext::SetCmdState(CAccountAreaContext::EAreaCMDState eState) { m_eCmdState = eState; } CAccountAreaContext::EAreaCMDState CAccountAreaContext::GetCmdState() const { return m_eCmdState; } BOOL CAccountAreaContext::IsCMDModel() const { return m_pDlg == NULL; } int CAccountAreaContext::DealSelectResult(PickSet &ssArea, CStringArray &arSArea) { CString sArea; for(long i=0;iisKindOf(AcDbText::desc())) { sArea = ((AcDbText *)pEnt)->textString(); } else if (pEnt->isKindOf(TDbText::desc())) { sArea = ((TDbText *)pEnt)->GetText(); } else if (pEnt->isKindOf(TDbSpace::desc())) { TDbSpace *pSpace = (TDbSpace *)pEnt; if (pSpace != NULL) { if (pSpace->IsHalfArea()) sArea.Format(_T("%lf"), pSpace->m_nUseArea/2.0); else sArea.Format(_T("%lf"), pSpace->m_nUseArea); } } } OPENOBJ_END(); DealSelectSArea(sArea); if (sArea != _T("")) arSArea.Add(sArea); } return (int)arSArea.GetSize(); } void CAccountAreaContext::DealSelectSArea(CString &sArea) { int nIndex=sArea.Find(__T("m^U2^U")); if (nIndex>-1) sArea.Delete(nIndex,6); int nLen=sArea.GetLength(); for(int k=0;k'9') { if (sArea[k]=='.') { if (k>0&&k='0' && sArea[k-1]<='9' && sArea[k+1]>='0' && sArea[k+1]<='9') continue; } } else if (sArea[k]=='-') { if (k='0'&&sArea[k+1]<='9') continue; } } sArea.Delete(k); nLen--; k--; } } } void CAccountAreaContext::CreateDlg(CAccountAreaContext *pContex, BOOL bShow /* = TRUE */) { CAcModuleResourceOverride vTemp; pContex->m_pDlg = new CAccountAreaDlg(acedGetAcadFrame()); pContex->m_pDlg->Create(pContex->m_pDlg->IDD); pContex->m_pDlg->ShowWindow(bShow); } CString CAccountAreaContext::GetResultAreaString(CAccountAreaContext *pCtx) { ASSERT( pCtx != NULL ); if (!pCtx->IsCMDModel()) { // 当前是对话框模式,应该从对话框中提取面积值 if (pCtx->m_pDlg->CalcResult()) { return GetAreaText(pCtx->m_pDlg->m_dResult); } else { return _T(""); } } else { // 命令行模式,因此应该从m_arSArea中计算面积和 return GetAreaText(CalcSumOfArea(pCtx->m_arSArea)); } } double CAccountAreaContext::CalcSumOfArea(CStringArray &arSArea) { double dResult = 0.0; for (int i = 0; i < arSArea.GetSize(); i++) { dResult += _tstof(arSArea[i]); } return dResult; } ////////////////////////////////////////////////////////////////////////// // 状态类,根据当前上下文实现具体的操作 void CAccountAreaContext::DoCMDSelectState() { CAccountAreaContext *pAacx = this; CString sArea; RBList mask(RTDXF0, _T("TEXT,TCH_TEXT,TCH_SPACE"), NULL); PickSet ssArea(SS_FREE); LPCTSTR szKeyWord = _T("Q"); // TCHAR chRet; int nRet0; if (pAacx->GetCmdState() == CAccountAreaContext::eCMDSelectFirst) { // 初次进入,提示用户选择命令 LPCTSTR szKeyWord, szPrompt; if (m_bSwitch) { szKeyWord = _T("Q"); szPrompt = _T("\n请选择求和的房间面积对象或面积数值文字或[对话框模式(Q)]<退出>: "); } else { szKeyWord = _T(""); szPrompt = _T("\n请选择求和的房间面积对象或面积数值文字或<退出>: "); } nRet0 = SelectEnts(szPrompt, ssArea, mask, szKeyWord); if (nRet0 == RTKWORD) { CreateDlg(pAacx); // 对话框被显示了出来,并且下一个状态进入了对话框选择状态! return; } else if (nRet0 == RTERROR) { // 空选 return; // 继续选择 } } else { ASSERT(pAacx->GetCmdState() == CAccountAreaContext::eCMDSelect); nRet0 = SelectEnts(_T("\n请选择求和的房间面积对象或面积数值文字: "), ssArea, mask, _T("")); } if (nRet0==RTNORM) { m_ssAreaAll += ssArea; ssArea.Redraw(3); long iLen = m_ssAreaAll.Length(); if (iLen > 0) { pAacx->SetCmdState(CAccountAreaContext::eCMDSelect); } } else if (nRet0==RTCAN) { pAacx->SetCancel(); return; } else // 右键、回车,确认选择 { // 获取了刚刚选择的字符串 CStringArray arSArea; if (DealSelectResult(m_ssAreaAll, arSArea) > 0) pAacx->m_arSArea.Append(arSArea); if (pAacx->m_arSArea.GetSize() == 0) { pAacx->SetCancel(); return; } // 右键,或者回车,进入文字绘制模式 pAacx->SetCmdState(CAccountAreaContext::eCMDDrawText); double dSum = CalcSumOfArea(pAacx->m_arSArea); CString szPrompt; szPrompt.Format(_T("\n共选中了%d个对象, 求和结果=%s"), pAacx->m_arSArea.GetSize(), GetAreaText(dSum)); ads_prompt(szPrompt); return; } } // 选择命令 void CAccountAreaContext::DoSelectState() { CAccountAreaContext *pAacx = this; ASSERT(pAacx->m_pDlg != NULL); CString sArea; RBList mask(RTDXF0, _T("TEXT,TCH_TEXT,TCH_SPACE"), NULL); PickSet ssArea(SS_FREE); int nRet0; // if (pAacx->m_pDlg->IsNoneSelect()) if (m_pDlg->m_ePath == CAccountAreaDlg::eSelectFirst) { LPCTSTR szKeyWord, szPrompt; if (m_bSwitch) { szKeyWord = _T("Q"); szPrompt = _T("\n请选择房间面积对象或面积数值文字[命令行模式(Q)]<退出>: "); } else { szKeyWord = _T(""); szPrompt = _T("\n请选择房间面积对象或面积数值文字<退出>: "); } nRet0 = SelectEnts(szPrompt, ssArea, mask, szKeyWord); if (nRet0 == RTKWORD) { // 切换到了命令行的模式 if (IsWindow(m_pDlg->m_hWnd)) { m_pDlg->DestroyWindow(); delete m_pDlg; m_pDlg = NULL; } SetCmdState(eCMDSelectFirst); return; } if (nRet0 == RTNONE) { // 右键回车返回: SetCancel(TRUE); return; } } else { // nRet0 = SelectEntities(_T("\n请选择房间面积对象或面积数值文字: "), ssArea, mask); nRet0 = SelectEnts(_T("\n请选择房间面积对象或面积数值文字: "), ssArea, mask, _T("")); if (nRet0 == RTNONE) { // 右键回车,调入当前数据,并且继续选择状态 CStringArray arSArea; DealSelectResult(m_ssAreaAll, arSArea); m_ssAreaAll.Redraw(4); m_ssAreaAll.Free(); for (int i = 0; i < arSArea.GetSize(); i++) { pAacx->m_pDlg->InsertData(arSArea[i]); } pAacx->m_pDlg->SetCurs(); } } if (nRet0==RTNORM) { m_ssAreaAll += ssArea; ssArea.Redraw(3); if (m_ssAreaAll.Length() > 0) pAacx->m_pDlg->SetAreaState(CAccountAreaDlg::eSelect); } else if (nRet0==RTCAN) { if (!pAacx->m_pDlg->m_bUseEsc) { pAacx->m_pDlg->m_bUseEsc=TRUE; return; } else { pAacx->SetCancel(); return; } } return; } void CAccountAreaContext::DoDrawState() { m_ssAreaAll.Redraw(4); CAccountAreaContext *pAacx = this; PickSet ss(SS_FREE); ss.IncludeBegin(); XString sTemp; CString sArea = GetResultAreaString(pAacx); if (sArea == _T("")) { if (pAacx->IsCMDModel()) return; else { // pAacx->m_pDlg->m_ePath = CAccountAreaDlg::eSelect; // 因为计算错误,没有东西用来标志,重新回到原来的状态 pAacx->m_pDlg->SetAreaState(CAccountAreaDlg::eSelect); return; } } sTemp<SetText(sTemp); pText->SetHeight(3.5); pText->SetStyleId(InitTextStyle(TS_SPACE)); pText->SetLocation(Ucs2Wcs(XPoint())); pText->SetRotation(Ucs2Wcs(0)); pText->AddToCSpace(Adesk::kTrue); ss.IncludeEnd(); extern TARCH_IMPEXP int DragMovePickSet(PickSet &ss, const TCHAR *pszPrompt, const XPoint &ptBase, XPoint &ptFinal); int nRet=DragMovePickSet(ss,_T("\n点取面积标注位置<退出>:"),XPoint(),XPoint()); if (nRet!=RTNORM) { ss.Erase(); if (nRet==RTCAN) { if ((pAacx->m_pDlg != NULL) && (!pAacx->m_pDlg->m_bUseEsc)) { pAacx->m_pDlg->m_bUseEsc=TRUE; return; } else { pAacx->SetCancel(); return; } } else { pAacx->SetCancel(); return; } } else { if (pAacx->IsCMDModel()) { pAacx->SetCancel(); return; } } } void CAccountAreaContext::CloseSwitch() { m_bSwitch = false; } const unsigned CExpressionParser::m_uMaxValue = 1000; const unsigned CExpressionParser::m_uRealMaxValue = 1500; //将角度转换成弧度 double CExpressionParser::DegTorad( double deg ) { return (2*PI*deg)/360.0; } //将中缀表达式转换为后缀表达式(逆波兰式) CExpressionParser::EErrorStat CExpressionParser::Trans( CString &a, TCHAR b[] ) { TCHAR stock[m_uRealMaxValue]={0}; int top=0; // 当前栈顶 int len=0; // 总长度 int i=0; // 当前字符位置 int j=0; top = -1; j = -1; len = a.GetLength(); for ( i=0; i=0 && stock[top]!='(' && stock[top]!='+' && stock[top]!='-' ) { // 退栈,直到空、括号,低优先级的加或者减 b[++j] = stock[top--]; } // 运算符前实际上给添加了空格 stock[++top] = ' '; stock[++top] = a[i]; break; case 's': case 'c': case 't': // 关键字符,程序目前没有用到 while( top>=0 && stock[top]!='(' && stock[top]!='+' && stock[top]!='-' && stock[top]!='*' && stock[top]!='/' ) { b[++j] = stock[top--]; } stock[++top] = ' '; stock[++top] = a[i]; break; case 'v': case '^': // 关键字符,程序目前没有用到 while( top>=0 && stock[top]!='(' && stock[top]!='+' && stock[top]!='-' && stock[top]!='*' && stock[top]!='/' && stock[top]!='s' && stock[top]!='c' && stock[top]!='t' ) { b[++j] = stock[top--]; } stock[++top] = ' '; stock[++top] = a[i]; break; case 'L': // 关键字符,程序目前没有用到 while( top>=0 && stock[top]!='(' && stock[top]!='+' && stock[top]!='-' && stock[top]!='*' && stock[top]!='/' && stock[top]!='s' && stock[top]!='c' && stock[top]!='t' && stock[top]!='v' && stock[top]!='^' ) { b[++j] = stock[top--]; } stock[++top] = ' '; stock[++top] = a[i]; break; case ')': // 左括号,需要查找匹配,这里可能会不匹配(退栈错误) while( stock[top]!='(' ) { if (top == 0) return eBracketNotMatch; b[++j] = stock[top--]; } top--;// 清理剩下的那个括号 break; case '+': case '-': // 这里:要预先判断+-是不是正负号,如果是正负号,则进入default分支!! if ((i != 0) && (a[i-1] != '(')) { // 实际上的算术运算符优先级分类,低优先级的进入,要弹出高优先级的运算符,包括相同优先级的也要弹出 // 而 加减法是优先级最低的了。 while( top>=0 && stock[top]!='(' ) { // 退栈,直到空,或者括号 b[++j] = stock[top--]; } // 运算符前实际上给添加了空格 stock[++top] = ' '; stock[++top] = a[i]; // 加运算符之前先加一个空格 break; } default: b[++j] = a[i]; if((i < len - 1) && (a[i+1]<'0' || a[i+1]>'9') ) { if ( a[i+1] != '.' ) { b[++j] = ' '; } } else if (i == len - 1) { b[++j] = ' '; } break; } } // 栈中剩余的算号全部退栈 while ( top>=0 ) { // 括号不匹配 if (stock[top] == '(') return eBracketNotMatch; b[++j] = stock[top--]; } b[++j] = '\0'; // 设置终止字符串 return eOk; } //求解后缀表达式(逆波兰式)的值 CExpressionParser::EErrorStat CExpressionParser::Compvalue( TCHAR exp[], double &dResult) { int top=0; int len=0; int i=0; int c=0; double sum=0; double digit[m_uRealMaxValue]={0}; TCHAR str_num_temp[m_uRealMaxValue]={0}; #define TEST_TOPVALUE if (top == 0) return eOperationRedundant top = -1; len = (int)_tcsclen(exp); for ( i=0; i='0' && exp[i]<='9') || exp[i] == '.' ) { if (exp[i] == '.') { if (++uPointNum > 1) return eErrorCharacter;// 错误的字符 } str_num_temp[c++] = exp[i]; i++; } if (exp[i] != ' ') { // 下面的字符竟然不是空格,有错误 return eErrorCharacter;// 错误的字符 } str_num_temp[c] = '\0'; digit[++top] = _tstof(str_num_temp); digit[top] = bPostive ? digit[top] : -digit[top]; break; } } if (top != 0) return eOperationMissed; dResult = digit[0]; return eOk; } //解析数学表达式(供外界调用的接口) CExpressionParser::EErrorStat CExpressionParser::Expression_Parser( CString &sExpression, double &dResult ) { TCHAR temp[m_uRealMaxValue]={0}; EErrorStat eStat = eOk; eStat = Trans( sExpression, temp ); if (eStat != eOk) return eStat; return Compvalue( temp, dResult ); } // modify by lgh on 20100804,根据8.5的需求,将这个面积计算命令,进行了重写 /* // 面积计算,命令函数 void AccountArea() { // sg add 091110,防止启动命令时,选择集不为空,死循环 g_ssPickFirst.Free(); CAcModuleResourceOverride vTemp; CAccountAreaDlg dlg(acedGetAcadFrame()); dlg.Create(dlg.IDD); dlg.ShowWindow(SW_SHOW); while(1) { if (dlg.m_nPath==0) { CString sArea; RBList mask(RTDXF0, _T("TEXT,TCH_TEXT,TCH_SPACE"), NULL); PickSet ssArea(SS_FREE); int nRet0; nRet0=SelectEntities(_T("\n请选择房间面积对象或面积数值文字:"), ssArea, mask); if (nRet0==RTNORM) { for(long i=0;iisKindOf(AcDbText::desc())) { sArea = ((AcDbText *)pEnt)->textString(); } else if (pEnt->isKindOf(TDbText::desc())) { sArea = ((TDbText *)pEnt)->GetText(); } else if (pEnt->isKindOf(TDbSpace::desc())) { TDbSpace *pSpace=(TDbSpace *)pEnt; if (pSpace!=NULL) { if (pSpace->IsHalfArea()) sArea.Format(_T("%lf"),pSpace->m_nUseArea/2.0); else sArea.Format(_T("%lf"),pSpace->m_nUseArea); } } } OPENOBJ_END(); int nIndex=sArea.Find(__T("m^U2^U")); if (nIndex>-1) sArea.Delete(nIndex,6); int nLen=sArea.GetLength(); for(int k=0;k'9') { if (sArea[k]=='.') { if (k>0&&k='0' && sArea[k-1]<='9' && sArea[k+1]>='0' && sArea[k+1]<='9') continue; } } else if (sArea[k]=='-') { if (k='0'&&sArea[k+1]<='9') continue; } } sArea.Delete(k); nLen--; k--; } } if (dlg.m_nCursStart>0) { CString sCur=dlg.m_sExpression.GetAt(dlg.m_nCursStart-1); if (sCur!=_T("+")&&sCur!=_T("-")) sArea.Insert(0,_T("+")); } dlg.InsertData(dlg.m_nCursStart,sArea); } dlg.SetCurs(dlg.m_nCursStart,dlg.m_nCursEnd); } else if (nRet0==RTCAN) { if (!dlg.m_bUseEsc) { dlg.m_bUseEsc=TRUE; continue; } else break; } else break; } else { PickSet ss(SS_FREE); ss.IncludeBegin(); XString sTemp; double fExtpr=_tstof(dlg.m_sExpression); CString sArea=GetAreaText(fExtpr); sTemp<SetText(sTemp); pText->SetHeight(3.5); pText->SetStyleId(InitTextStyle(TS_SPACE)); pText->SetLocation(Ucs2Wcs(XPoint())); pText->SetRotation(Ucs2Wcs(0)); pText->AddToCSpace(Adesk::kTrue); ss.IncludeEnd(); extern TARCH_IMPEXP int DragMovePickSet(PickSet &ss, const TCHAR *pszPrompt, const XPoint &ptBase, XPoint &ptFinal); int nRet=DragMovePickSet(ss,_T("\n点取面积标注位置<退出>:"),XPoint(),XPoint()); if (nRet!=RTNORM) { ss.Erase(); if (nRet==RTCAN) { if (!dlg.m_bUseEsc) { dlg.m_bUseEsc=TRUE; continue; } else break; } else break; } } } if (::IsWindow(dlg.m_hWnd)) dlg.DestroyWindow(); } */ void AccountArea() { // 防止启动命令时,选择集不为空,死循环 g_ssPickFirst.Free(); CAccountAreaContext aacx; while (TRUE) { if (!aacx.IsCMDModel()) // 对话框模式还是命令行模式 { if (aacx.m_pDlg == NULL) { return; } switch (aacx.m_pDlg->m_ePath) { case CAccountAreaDlg::eSelectFirst: case CAccountAreaDlg::eSelect: aacx.DoSelectState(); aacx.CloseSwitch(); break; case CAccountAreaDlg::eDrawText: aacx.DoDrawState(); break; default: return; } } else { switch (aacx.GetCmdState()) { case CAccountAreaContext::eCMDSelectFirst: case CAccountAreaContext::eCMDSelect: aacx.DoCMDSelectState(); aacx.CloseSwitch(); break; case CAccountAreaContext::eCMDDrawText: aacx.DoDrawState(); break; default: return; } } if (aacx.GetCancel()) // 检测是否退出 { return; // 如果被设置了退出标志,则退出 } } }