458 lines
12 KiB
C++
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();
|
|
}
|