// 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; iSetDoorLineOffsetDist(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(); }