Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/DoorLineDlg.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

458 lines
12 KiB
C++

// DoorLineDlg.cpp :implementation file
#include "stdafx.h"
#include "DoorLineDlg.h"
#include "Resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int CDoorLineDlg::m_nLocation = 1; // 记录门口线位置,单侧
int CDoorLineDlg::m_nFunction = 0; // 记录添加或者消除门口线的功能,默认加门口线
int CDoorLineDlg::m_nOffsetDist = 0; // 记录偏移距离
CDoorLineDlg::CDoorLineDlg(CWnd* pParent /*=NULL*/)
: CModelessDialog(CDoorLineDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDoorLineDlg)
//}}AFX_DATA_INIT
}
CDoorLineDlg::~CDoorLineDlg()
{
}
void CDoorLineDlg::DoDataExchange(CDataExchange* pDX)
{
CModelessDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDoorLineDlg)
DDX_Radio(pDX, IDC_RADIO_ADD_LINE, m_nFunction);
DDX_Radio(pDX, IDC_RADIO_MIDDLE, m_nLocation);
DDX_Control(pDX, IDC_COMBO_OFFSET_DIST, m_cmbOffsetDist);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDoorLineDlg, CModelessDialog)
//{{AFX_MSG_MAP(CDoorLineDlg)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_RADIO_ADD_LINE, OnRadioFunction)
ON_BN_CLICKED(IDC_RADIO_DEL_LINE, OnRadioFunction)
ON_BN_CLICKED(IDC_RADIO_MIDDLE, OnRadioLocation)
ON_BN_CLICKED(IDC_RADIO_ONESIDE, OnRadioLocation)
ON_BN_CLICKED(IDC_RADIO_BOTH, OnRadioLocation)
ON_BN_CLICKED(IDC_RADIO_ALLLINE, OnRadioLocation)
ON_CBN_KILLFOCUS(IDC_COMBO_OFFSET_DIST, OnKillfocusComboOffsetDist)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CDoorLineDlg::OnInitDialog()
{
CModelessDialog::OnInitDialog();
InitCombox();
AddTip(IDC_STATIC_OFFSET_DIST, _T("表示门口线偏移墙边线的距离"));
SetDlgFunctionShow();
// 如果门口线居中,则偏移距离不可编辑
bool bEnable = (m_nLocation!=0);
GetDlgItem(IDC_STATIC_OFFSET_DIST)->EnableWindow(bEnable);
GetDlgItem(IDC_COMBO_OFFSET_DIST)->EnableWindow(bEnable);
UpdateData(FALSE);
return TRUE;
}
// 根据功能,控制对话框上的控件显示
void CDoorLineDlg::SetDlgFunctionShow()
{
UpdateData();
if (m_nFunction == 0) // 加门口线
{
GetDlgItem(IDC_STATIC_OFFSET_DIST)->ShowWindow(SW_SHOW);
GetDlgItem(IDC_COMBO_OFFSET_DIST)->ShowWindow(SW_SHOW);
GetDlgItem(IDC_RADIO_ALLLINE)->ShowWindow(SW_HIDE);
}
else // 消门口线
{
GetDlgItem(IDC_STATIC_OFFSET_DIST)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_COMBO_OFFSET_DIST)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_RADIO_ALLLINE)->ShowWindow(SW_SHOW);
}
UpdateData(FALSE);
}
// 初始化下拉列表控件
void CDoorLineDlg::InitCombox()
{
int aryOffset[] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
CString csItem;
m_cmbOffsetDist.ResetContent();
for (int i = 0 ; i < ELEMENTS(aryOffset); i++)
{
csItem.Format(_T("%d"), aryOffset[i]);
m_cmbOffsetDist.AddString(csItem); // 初始化“偏移距离”控件
}
// 读取静态记忆值
csItem.Format(_T("%d"), m_nOffsetDist);
int nIndex = m_cmbOffsetDist.FindStringExact(-1, csItem);
if (nIndex < 0) // 没有找到,就添加到最后
{
nIndex = m_cmbOffsetDist.AddString(csItem);
}
m_cmbOffsetDist.SetCurSel(nIndex);
}
void CDoorLineDlg::OnRadioFunction()
{
UpdateData();
SetDlgFunctionShow();
// 由“消除门口线”变成“加门口线”,门口线自动从“所有侧”变成“单侧”
if (m_nFunction==0 && m_nLocation==3)
{
m_nLocation = 1;
}
UpdateData(FALSE);
m_bUseEsc = false;
acedPostCommand(_T("\33"));
}
void CDoorLineDlg::OnRadioLocation()
{
UpdateData();
// 如果门口线居中,则偏移距离不可编辑
bool bEnable = (m_nLocation!=0);
GetDlgItem(IDC_STATIC_OFFSET_DIST)->EnableWindow(bEnable);
GetDlgItem(IDC_COMBO_OFFSET_DIST)->EnableWindow(bEnable);
UpdateData(FALSE);
}
void CDoorLineDlg::OnKillfocusComboOffsetDist()
{
UpdateData();
CString csOffsetDist;
m_cmbOffsetDist.GetWindowText(csOffsetDist);
if (csOffsetDist.IsEmpty())
{
csOffsetDist.Format(_T("%d"), m_nOffsetDist);
m_cmbOffsetDist.SetWindowText(csOffsetDist);
}
else
{
if (!IsDigital(csOffsetDist))
{
MessageBox(_T("请输入大于等于0的数!"));
}
else
{
m_nOffsetDist = _ttoi(csOffsetDist);
}
}
UpdateData(FALSE);
}
void CDoorLineDlg::OnClose()
{
m_bUseEsc = true;
if (m_bModeless)
{
acedPostCommand(_T("\33\33"));
}
else
{
CModelessDialog::OnClose();
}
}
// 设置是否允许修改门口线的侧
void CDoorLineDlg::SetLockLocation(bool bEnable)
{
GetDlgItem(IDC_RADIO_MIDDLE)->EnableWindow(bEnable);
GetDlgItem(IDC_RADIO_ONESIDE)->EnableWindow(bEnable);
GetDlgItem(IDC_RADIO_BOTH)->EnableWindow(bEnable);
GetDlgItem(IDC_RADIO_ALLLINE)->EnableWindow(bEnable);
UpdateData(FALSE);
}
// 设置居中门口线
// nFlag1为单、双侧以及无的标记,nFlag2为居中标记
void CDoorLineDlg::SetMidLoc(bool bTrue, TDbOpening *pOpening)
{
pOpening->assertWriteEnabled();
if (bTrue) // 设置居中门口线
{
pOpening->m_nOpStyleEx |= OPS_DOORLINE_MID;
pOpening->m_nOpStyle &= ~OPS_DOORLINE1; // 覆盖原有的单侧门口线
pOpening->m_nOpStyle &= ~OPS_DOORLINE2;
}
else // 取消居中门口线
{
pOpening->m_nOpStyleEx &= ~OPS_DOORLINE_MID;
}
}
// 设置双侧门口线
// nFlag1为单、双侧以及无的标记,nFlag2为居中标记
void CDoorLineDlg::SetBothSide(bool bTrue, TDbOpening *pOpening)
{
pOpening->assertWriteEnabled();
if (bTrue) // 设置双侧门口线
{
pOpening->m_nOpStyle |= OPS_DOORLINE1;
pOpening->m_nOpStyle |= OPS_DOORLINE2;
pOpening->m_nOpStyleEx &= ~OPS_DOORLINE_MID; // 覆盖原有的居中门口线
}
else // 取消双侧门口线
{
pOpening->m_nOpStyle &= ~OPS_DOORLINE1;
pOpening->m_nOpStyle &= ~OPS_DOORLINE2;
}
}
// 将对话框中的偏移距离,与墙体宽度进行比较,确定是否偏移距离过大,返回实际的偏移距离,并自动统计超过的个数
double CDoorLineDlg::GetOffsetWidth(AcDbObjectId idWall, int &nCountNum)
{
double dWallWidth = 0;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
dWallWidth = pWall->GetWidth(4);
}
OPENOBJ_END();
if (dWallWidth < m_nOffsetDist - _DIST_SNAP) // 小于偏移距离
{
nCountNum++;
return dWallWidth;
}
return m_nOffsetDist;
}
// 命令函数: 加门口线
// sg add 101230,从windoor.cpp文件中迁移过来,并重新进行了改写
void DoorLine()
{
CAcModuleResourceOverride vTemp;
CDoorLineDlg dlg;
if (!dlg.Create(dlg.IDD, acedGetAcadFrame()))
return;
acedGetAcadDwgView()->SetFocus();
dlg.ShowWindow(SW_SHOW);
CString csPrompt;
PickSet ss(SS_FREE), ssTmp(SS_FREE);
RBList Mask = ads_buildlist(RTDXF0, _T("TCH_OPENING"), NULL);
// add by xly on 110412 右键菜单中的门口线崩溃的错误
ss = g_ssPickFirst;
ss.BaseFilter(Mask);
int nCountOpening = 0; // 统计有多少个对象,自动按齐墙边计算
while (1)
{
dlg.UpdateData();
dlg.m_bUseEsc = true;
if (dlg.m_nFunction == 0) // 加门口线
{
csPrompt = _T("\n请选取需要加门口线的门:");
}
else // 消除门口线
{
csPrompt = _T("\n请选取需要消门口线的门:");
}
ss.Free();
if (SelectEntities(csPrompt, ss, Mask) != RTNORM) // 选择门
{
if (dlg.m_bUseEsc) // 确实要退出
{
break;
}
continue; // 切换了功能或门口线位置
}
nCountOpening = 0; // 计数器清零
dlg.UpdateData();
XPoint ptSide; // 需要增加门口线的侧
if (dlg.m_nLocation == 1) // 单侧时,提示点取侧
{
if (dlg.m_nFunction == 0) // 加门口线
{
csPrompt = _T("\n请点取门口线所在的一侧<退出>:");
}
else // 消除门口线
{
csPrompt = _T("\n请点取门口线消除的一侧<退出>:");
}
dlg.SetLockLocation(false); // 设置不允许修改侧
if (ads_getpoint(NULL, csPrompt, ptSide) != RTNORM)
{
if (dlg.m_bUseEsc) // 确实要退出
{
break;
}
dlg.SetLockLocation(true); // 解锁
continue; // 切换了功能或门口线位置
}
ptSide = Ucs2Wcs(ptSide);
dlg.SetLockLocation(true); // 解锁
}
long lCount = ss.Length();
for (long i=0L; i<lCount; i++)
{
Entity ent = ss[i];
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbOpening, pDoor);
if (pDoor != NULL)
{
switch (dlg.m_nLocation)
{
case 0: // 居中加、减门口线
{
dlg.SetMidLoc(dlg.m_nFunction==0, pDoor);
}
break;
case 1: // 单侧加、减门口线
{
if (dlg.m_nFunction == 0) // 加门口线
{
dlg.SetMidLoc(false, pDoor); // 先消除原来有的居中和双侧门口线
pDoor->SetDoorLineOffsetDist(dlg.GetOffsetWidth(pDoor->GetWallId(), nCountOpening)); // 偏移距离
}
XPoint pt = pDoor->GetLocation();
pt.z = 0;
XLine ln(pt, pDoor->GetRotation());
int nSide = ln.OnWhichSide(ptSide);
AcGePoint3dArray gripPoints;
if (pDoor->getGripPoints(gripPoints, AcDbIntArray(), AcDbIntArray())==Acad::eOk &&
gripPoints.length()>=4)
{
XPoint ptGrip = gripPoints[3];
ptGrip.z = 0;
int nSide1 = ln.OnWhichSide(ptGrip);
pDoor->assertWriteEnabled();
if (nSide == nSide1)
{
// sg modify 110214,根据功能判断是否需要加门口线
// if ((pDoor->m_nOpStyle&OPS_DOORLINE1) != 0) // modified by whl
if (dlg.m_nFunction != 0) // 消除门口线
pDoor->m_nOpStyle &= ~OPS_DOORLINE1;
else // 添加门口线
{
// 判断当前是否是已经加了双侧门口线
if ((pDoor->m_nOpStyle&OPS_DOORLINE1)!=0 && (pDoor->m_nOpStyle&OPS_DOORLINE2)!=0)
{
pDoor->m_nOpStyle &= ~OPS_DOORLINE2;
}
pDoor->m_nOpStyle |= OPS_DOORLINE1;
}
}
else
{
// sg modify 110214,根据功能判断是否需要加门口线
// if ((pDoor->m_nOpStyle&OPS_DOORLINE2)!=0)
if (dlg.m_nFunction != 0) // 消除门口线
pDoor->m_nOpStyle &= ~OPS_DOORLINE2;
else // 添加门口线
{
// 判断当前是否是已经加了双侧门口线
if ((pDoor->m_nOpStyle&OPS_DOORLINE1)!=0 && (pDoor->m_nOpStyle&OPS_DOORLINE2)!=0)
{
pDoor->m_nOpStyle &= ~OPS_DOORLINE1;
}
pDoor->m_nOpStyle|= OPS_DOORLINE2;
}
}
}
}
break;
case 2: // 双侧加、减门口线
{
dlg.SetBothSide(dlg.m_nFunction==0, pDoor);
if (dlg.m_nFunction == 0) // 加门口线
{
pDoor->SetDoorLineOffsetDist(dlg.GetOffsetWidth(pDoor->GetWallId(), nCountOpening)); // 偏移距离
}
}
break;
case 3: // 所有侧,消除门口线
{
dlg.SetMidLoc(false, pDoor);
dlg.SetBothSide(false, pDoor);
}
}
/*
AcDbObjectId idWall=pDoor->GetWallId();
XPoint pt1, pt2;
pDoor->GetSidePoints(pt1, pt2);
XCurveSegment segSide;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (pWall) {
XCurveSegment segCen=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
int nSide=segCen.OnWhichSide(ptSide);
segSide=segCen.Offset(nSide, pWall->GetWidth(4)/2, LS_INFINITE);
double nRot=pDoor->GetRotation();
XLine ln1(pt1, nRot+PI/2.0), ln2(pt2, nRot+PI/2.0);
XPoint ptInt1, ptInt2, ptInt[2];
int nIntNum=segSide.Intersection(ln1, ptInt[0], ptInt[1]);
if (!nIntNum)
continue;
else if (nIntNum==1)
ptInt1=ptInt[0];
else
ptInt1=XLine(ptInt[0], ptInt[1]).NearPoint(pt1);
nIntNum=segSide.Intersection(ln2, ptInt[0], ptInt[1]);
if (!nIntNum)
continue;
else if (nIntNum==1)
ptInt2=ptInt[0];
else
ptInt2=XLine(ptInt[0], ptInt[1]).NearPoint(pt1);
segSide.SetPoints(ptInt1, ptInt2);
segSide.SetElevation(0.0); // ZJQ add this on 2003/3/18
AcDbCurve *pCurve=segSide.AsAcDbCurve();
pCurve->setPropertiesFrom(pDoor);
AddToModelSpace(pCurve, Adesk::kTrue);
}
OPENOBJ_END();
*/
}
OPENOBJ_END();
}
if (nCountOpening != 0)
{
CString csPrompt;
csPrompt.Format(_T("\n注意: 有%d个门窗的门口线偏移距离过大, 程序自动按墙边对齐绘制! "), nCountOpening);
acutPrintf(csPrompt);
}
}
dlg.DestroyWindow();
}