Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/AccountAreaDlg.cpp
T
2026-09-28 15:28:50 +08:00

1480 lines
31 KiB
C++

#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;i<ssArea.Length();i++)
{
Entity ent=ssArea[i];
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
if (pEnt != NULL)
{
if (pEnt->isKindOf(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<nLen;k++)
{
if (sArea[k]<'0' || sArea[k]>'9')
{
if (sArea[k]=='.')
{
if (k>0&&k<nLen-1)
{
if (sArea[k-1]>='0' && sArea[k-1]<='9' && sArea[k+1]>='0' && sArea[k+1]<='9')
continue;
}
}
else if (sArea[k]=='-')
{
if (k<nLen-1)
{
if (sArea[k+1]>='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<<sArea<<_T("m^U2^U");
TDbText *pText = new TDbText;
pText->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<len; i++ )
{
switch( a[i] )
{
case '(':
// 左括号直接入栈
stock[++top] = '(';
break;
case '*':
case '/':
while( top>=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<len; i++ )
{
// 要对正负号处理一下!
if (exp[i] == ' ')
continue;
TCHAR chRes = 0;
if ((i != len -1) && (exp[i+1] == ' '))
chRes = exp[i];
else
chRes = 0;
// switch( exp[i] )
switch (chRes)
{
case ' ':
break;
case '+':
TEST_TOPVALUE;
sum = digit[top] + digit[top-1];
digit[--top] = sum;
break;
case '-':
TEST_TOPVALUE;
sum = digit[top-1] - digit[top];
digit[--top] = sum;
break;
case '*':
TEST_TOPVALUE;
sum = digit[top] * digit[top-1];
digit[--top] = sum;
break;
case '/':
TEST_TOPVALUE;
// 防止除0错误
if (fabs(digit[top]) < 1e-7)
return eZeroDivisor;
sum = digit[top-1] / digit[top];
digit[--top] = sum;
break;
case 's':
sum = sin( DegTorad(digit[top]) );
digit[top] = sum;
break;
case 'c':
sum = cos( DegTorad(digit[top]) );
digit[top] = sum;
break;
case 't':
sum = tan( DegTorad(digit[top]) );
digit[top] = sum;
break;
case 'v':
sum = sqrt( digit[top] );
digit[top] = sum;
break;
case '^':
TEST_TOPVALUE;
sum = pow( digit[top-1], digit[top] );
digit[--top] = sum;
break;
case 'L':
sum = log10( digit[top] );
digit[top] = sum;
break;
default:
c = 0;
memset( str_num_temp, 0, sizeof(str_num_temp) );
unsigned uPointNum = 0;
BOOL bPostive = TRUE;
if ((exp[i] == '+') || (exp[i] == '-') )
{
bPostive = exp[i] == '+' ? TRUE : FALSE;
i++;
}
while( (exp[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;i<ssArea.Length();i++)
{
Entity ent=ssArea[i];
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
if (pEnt)
{
if (pEnt->isKindOf(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<nLen;k++)
{
if (sArea[k]<'0' || sArea[k]>'9')
{
if (sArea[k]=='.')
{
if (k>0&&k<nLen-1)
{
if (sArea[k-1]>='0' && sArea[k-1]<='9' && sArea[k+1]>='0' && sArea[k+1]<='9')
continue;
}
}
else if (sArea[k]=='-')
{
if (k<nLen-1)
{
if (sArea[k+1]>='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<<sArea<<_T("m^U2^U");
TDbText *pText = new TDbText;
pText->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; // 如果被设置了退出标志,则退出
}
}
}