#include "stdafx.h" #include "BDQGDlg.h" #include "AecDbEwEquipment.h" #include "uihistory.h" #include #include "dbobjptr.h" #include "coretools.h" #define _DQG_DATA_ _T("____DQG___DATA____") #define _DQG_ELEV_ _T("____DQG___ELEV____") #define _DQG_SPACE_ _T("____DQG___SPACE____") #define _DQG_V_ _T("____DQG___V____") #define _DQG_H_ _T("____DQG___H____") #define _DQG_MATERIAL_ _T("____DQG___MATERIAL____") #define _DQG_FACTORY_ _T("____DQG___FACTORY____") #define _DQG_COMMON_ _T("____DQG___COMMON____") #define _DQG_PT_INS_ _T("____DQG___PT___INS____") #define _DQG_PT_DIR_ _T("____DQG___PT___DIR____") namespace { AecDbEwEquipment* makeBaseEquiment(LPCTSTR name) { if (!name) return NULL; AecDbEwEquipment *pWEquip = new AecDbEwEquipment; AecDbObjXDataMap *pXDataMap = pWEquip->GetSpecialtyData(); pXDataMap->SetAt(KEY_NAME, name); pXDataMap->SetAt(KEY_RUNTIME, eEquipment); pXDataMap->SetAt(KEY_DRAW2D, _T("DBClick_DQG")); return pWEquip; } void moveSubPrimObj(AecDbEwEquipment *pEqu , const Adesk::Int32 &id , const double &dist , const int &axis) { AecEqui::XPrimData data; data.m_vtMove.set(0.0, 0.0, 0.0); data.m_vtMove[axis] = dist; pEqu->ModifyPrimData(id, data, 2); } void moveSubPrimObj(AecDbEwEquipment *pEqu , const Adesk::Int32 &id , const AcGePoint3d &pt1 , const AcGePoint3d &pt2) { AcGeVector3d vtMove = pt2 - pt1; moveSubPrimObj(pEqu, id, vtMove.x, 0); moveSubPrimObj(pEqu, id, vtMove.y, 1); moveSubPrimObj(pEqu, id, vtMove.z, 2); } template void setData(AecEqui::XPrimData *pXPData, void *pData) { ::Sleep(30); pXPData->m_nID = ::GetTickCount(); pXPData->m_pData = new T; ::memcpy(pXPData->m_pData, pData, sizeof(T)); pXPData->m_nSize = sizeof(T); } template Adesk::Int32 addSubPrimObj(AecDbEwEquipment *pEqu, T &t, const AecEqui::Primitive &type) { AecEqui::XPrimData data; data.m_eType = type; setData(&data, &t); pEqu->AddSubPrimObj(&data); data.releaseData(); return data.m_nID; } } #pragma region CBDQGDlg IMPLEMENT_DYNAMIC(CBDQGDlg, CDialog) CBDQGDlg::CBDQGDlg(CWnd *pParent /*=NULL*/) : CDialog(IDD_BDQG_DLG, pParent) , m_sFactory(_T("北京东胜亚电气有限公司")) , m_sName(_T("")) , m_sUse(_T("")) , m_sDesc(_T("")) , m_sMaterial(_T("")) , m_sCommon(_T("")) , m_dHeight(1000.0) , m_dWidth(1000.0) , m_dDeep(1000.0) , m_dSpace(1000.0) , m_dElev(1000.0) , m_iAlignV(0) , m_iAlignH(0) { GET_CACHE(CBDQGDlg, %s%s%s%s%s%s%f%f%f%f%f%d%d , &m_sFactory , &m_sName , &m_sUse , &m_sDesc , &m_sMaterial , &m_sCommon , &m_dHeight , &m_dWidth , &m_dDeep , &m_dSpace , &m_dElev , &m_iAlignV , &m_iAlignH ); } CBDQGDlg::~CBDQGDlg() { } void CBDQGDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST, m_list); DDX_Text(pDX, IDC_EDIT_NAME, m_sName); DDX_Text(pDX, IDC_EDIT_HEIGHT, m_dHeight); DDX_Text(pDX, IDC_EDIT_WIDTH, m_dWidth); DDX_Text(pDX, IDC_EDIT_DEEP, m_dDeep); DDX_Text(pDX, IDC_EDIT_USE, m_sUse); DDX_Text(pDX, IDC_EDIT_DESC, m_sDesc); DDX_Text(pDX, IDC_EDIT_SPACE, m_dSpace); DDX_Text(pDX, IDC_EDIT_ELEV, m_dElev); DDX_Text(pDX, IDC_EDIT_MATERIAL, m_sMaterial); DDX_Text(pDX, IDC_EDIT_FACTORY, m_sFactory); DDX_Text(pDX, IDC_EDIT_COMMON, m_sCommon); DDX_Radio(pDX, IDC_RADIO_TOP, m_iAlignV); DDX_Radio(pDX, IDC_RADIO_LEFT, m_iAlignH); } BEGIN_MESSAGE_MAP(CBDQGDlg, CDialog) ON_BN_CLICKED(IDOK, &CBDQGDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_BTN_ADD, &CBDQGDlg::OnBnClickedAdd) ON_BN_CLICKED(IDC_BTN_MODIFY, &CBDQGDlg::OnBnClickedModify) ON_BN_CLICKED(IDC_BTN_DEL, &CBDQGDlg::OnBnClickedDel) ON_BN_CLICKED(IDC_BTN_UP, &CBDQGDlg::OnBnClickedUp) ON_BN_CLICKED(IDC_BTN_DW, &CBDQGDlg::OnBnClickedDw) ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, &CBDQGDlg::OnClickListItem) END_MESSAGE_MAP() BOOL CBDQGDlg::OnInitDialog() { CDialog::OnInitDialog(); initCtrls(); refreshList(); UpdateData(FALSE); return TRUE; } void CBDQGDlg::initCtrls() { m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_SINGLEROW); m_list.EnableToolTips(TRUE); CRect rect; m_list.GetClientRect(&rect); int width(rect.Width() / 6); m_list.InsertColumn(0, _T("名称"), LVCFMT_LEFT, width); m_list.InsertColumn(1, _T("高度"), LVCFMT_LEFT, width); m_list.InsertColumn(2, _T("宽度"), LVCFMT_LEFT, width); m_list.InsertColumn(3, _T("深度"), LVCFMT_LEFT, width); m_list.InsertColumn(4, _T("用途"), LVCFMT_LEFT, width); m_list.InsertColumn(5, _T("说明"), LVCFMT_LEFT, width); } void CBDQGDlg::OnBnClickedOk() { if (!UpdateData(TRUE)) return; SET_CACHE(CBDQGDlg, %s%s%s%s%s%s%f%f%f%f%f%d%d , m_sFactory , m_sName , m_sUse , m_sDesc , m_sMaterial , m_sCommon , m_dHeight , m_dWidth , m_dDeep , m_dSpace , m_dElev , m_iAlignV , m_iAlignH ); CDialog::OnOK(); } void CBDQGDlg::OnBnClickedAdd() { UpdateData(TRUE); if (m_sName.IsEmpty()) { AfxMessageBox(_T("名称不能为空!")); return; } _Records::iterator it = findDataByName(m_sName); if (it != m_datas.end()) { AfxMessageBox(_T("此名称已经存在!")); return; } m_datas.push_back(_Record(m_sName, m_sUse, m_sDesc, m_dHeight, m_dWidth, m_dDeep)); refreshList(); } void CBDQGDlg::OnBnClickedModify() { UpdateData(TRUE); CString sName = getCurrentSelectName(); if (sName.IsEmpty()) { AfxMessageBox(_T("选择无效!")); } _Records::iterator it = findDataByName(sName); if (it == m_datas.end()) { AfxMessageBox(_T("未找到数据!")); return; } if (sName != m_sName) { _Records::iterator it1 = findDataByName(m_sName); if (it1 != m_datas.end()) { AfxMessageBox(_T("要修改的名称已经存在!")); return; } } it->operator=(_Record(m_sName, m_sUse, m_sDesc, m_dHeight, m_dWidth, m_dDeep)); refreshList(); } void CBDQGDlg::OnBnClickedDel() { UpdateData(TRUE); CString sName = getCurrentSelectName(); if (sName.IsEmpty()) { AfxMessageBox(_T("选择无效!")); } _Records::iterator it = findDataByName(sName); if (it == m_datas.end()) { AfxMessageBox(_T("未找到数据!")); return; } m_datas.erase(it); refreshList(); } void CBDQGDlg::OnBnClickedUp() { int idx = getCurrentSelectIdx(); if (idx <= 0) return; moveUpData(idx); setCurrentSelect(idx - 1); } void CBDQGDlg::OnBnClickedDw() { int idx = getCurrentSelectIdx(); if (idx >= m_datas.size() - 1) return; moveUpData(idx + 1); setCurrentSelect(idx + 1); } void CBDQGDlg::moveUpData(const int &idx) { _Records::iterator it_cur(m_datas.begin()); std::advance(it_cur, idx); _Record rc(*it_cur); _Records::iterator it_ins(it_cur - 1); m_datas.erase(it_cur); m_datas.insert(it_ins, rc); refreshList(); } CBDQGDlg::_Records::iterator CBDQGDlg::findDataByName(LPCTSTR psz) { return std::find(m_datas.begin(), m_datas.end(), _Record(psz)); } void CBDQGDlg::makeBinaryByDatas(void *&pData, int &nSize) { nSize = 0; for (size_t i(0); i < m_datas.size(); ++i) nSize += m_datas[i].getBinarySize(); nSize += sizeof(int); // record 的数量 pData = new byte[nSize]; ::memset(pData, 0, nSize); byte *p((byte*)pData); int count((int)m_datas.size()); ::memcpy(p, &count, sizeof(int)); p += sizeof(int); void *pItem(NULL); int len(0); for (size_t i(0); i < m_datas.size(); ++i) { m_datas[i].makeBinary(pItem, len); ::memcpy(p, pItem, len); p += len; DELETE_ARR_(pItem); } } void CBDQGDlg::makeDatasByBinary(const void *pData) { if (!pData) return; m_datas.clear(); byte *p((byte*)pData); int count(0); ::memcpy(&count, p, sizeof(int)); p += sizeof(int); _Record rc; for (int i(0); i < count; ++i) { rc.fromBinary(p); p += rc.getBinarySize(); m_datas.push_back(rc); } } CString CBDQGDlg::getCurrentSelectName() { int idx = getCurrentSelectIdx(); if (idx == -1) return _T(""); return m_list.GetItemText(idx, 0); } int CBDQGDlg::getCurrentSelectIdx() { return m_list.GetNextItem(-1, LVIS_SELECTED); } void CBDQGDlg::setCurrentSelect(const int &idx) { m_list.SetItemState(idx, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); m_list.SetSelectionMark(idx); } AecDbEwEquipment* CBDQGDlg::getEqu(const AcGePoint3d &ptIns, const AcGeVector3d &vtDir) { if (m_datas.empty()) return NULL; // 获得总宽度,最大高度 double dAllWidth(.0), dMaxHeight(.0); for (size_t i(0); i < m_datas.size(); ++i) { dAllWidth += m_datas[i]._dWidth; if (m_datas[i]._dHeight > dMaxHeight) dMaxHeight = m_datas[i]._dHeight; } AecDbEwEquipment *pEqu = makeBaseEquiment(_T("电气柜")); // 设备生成在原点,向两侧排列 Adesk::Int32 id(0); AecEqui::XBox box; double dW(.0), dH(.0); AcGePoint3d pt(AcGePoint3d::kOrigin); AcGePoint3d ptLeft = AcGePoint3d::kOrigin - (AcGeVector3d::kXAxis * dAllWidth * .5);// 最左侧点 for (size_t i(0); i < m_datas.size(); ++i) { dW = m_datas[i]._dWidth; dH = m_datas[i]._dHeight; pt = ptLeft + AcGeVector3d::kXAxis * dW * .5; pt.z = .0; if (m_iAlignV == 0) // 顶对齐 pt.z += (dMaxHeight - dH); else if (m_iAlignV == 1) // 中对齐 pt.z += (dMaxHeight - dH) * .5; // 生成设备的子元素 ::memset(&box, 0, sizeof(AecEqui::XBox)); box.dL = m_datas[i]._dDeep; box.dW = dW; box.dH = dH; id = addSubPrimObj(pEqu, box, AecEqui::kBox); moveSubPrimObj(pEqu, id, AcGePoint3d::kOrigin, pt); ptLeft += AcGeVector3d::kXAxis * (dW + m_dSpace); } ptLeft = AcGePoint3d::kOrigin - (AcGeVector3d::kXAxis * dAllWidth); // 最左侧点 AcGePoint3d ptRight = ptLeft + AcGeVector3d::kXAxis * dAllWidth; // 最右侧点 AcGeVector3d vt(vtDir); vt.normalize(); AcGePoint3d ptInsert(ptIns); ptInsert.z = m_dElev; if (m_iAlignH == 0) // 左->右 ptInsert += vt * dAllWidth * .5; else if (m_iAlignH == 2) // 右->左 ptInsert -= vt * dAllWidth * .5; pEqu->SetInsert(ptInsert, vt); void *pData(NULL); int dataLen(0); makeBinaryByDatas(pData, dataLen); pEqu->GetSpecialtyData()->SetAt(_DQG_DATA_, pData, dataLen); DELETE_ARR_(pData); pEqu->GetSpecialtyData()->SetAt(_DQG_ELEV_, m_dElev); pEqu->GetSpecialtyData()->SetAt(_DQG_SPACE_, m_dSpace); pEqu->GetSpecialtyData()->SetAt(_DQG_V_, m_iAlignV); pEqu->GetSpecialtyData()->SetAt(_DQG_H_, m_iAlignH); pEqu->GetSpecialtyData()->SetAt(_DQG_MATERIAL_, m_sMaterial); pEqu->GetSpecialtyData()->SetAt(_DQG_FACTORY_, m_sFactory); pEqu->GetSpecialtyData()->SetAt(_DQG_COMMON_, m_sCommon); pEqu->GetSpecialtyData()->SetAt(_DQG_PT_INS_, ptInsert); pEqu->GetSpecialtyData()->SetAt(_DQG_PT_DIR_, vt); return pEqu; } bool CBDQGDlg::initByEqu(AecDbEwEquipment *pEqu, AcGePoint3d &ptIns, AcGeVector3d &vtDir) { if (!pEqu) return false; void *pData(NULL); int lenData(0); if (!pEqu->GetSpecialtyData()->GetAt(_DQG_DATA_, pData, lenData)) return false; if (pData && lenData > 0) makeDatasByBinary(pData); DELETE_ARR_(pData); if (!pEqu->GetSpecialtyData()->GetAt(_DQG_ELEV_, m_dElev)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_SPACE_, m_dSpace)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_V_, m_iAlignV)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_H_, m_iAlignH)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_MATERIAL_, m_sMaterial)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_FACTORY_, m_sFactory)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_COMMON_, m_sCommon)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_PT_INS_, ptIns)) return false; if (!pEqu->GetSpecialtyData()->GetAt(_DQG_PT_DIR_, vtDir)) return false; return true; } void CBDQGDlg::OnClickListItem(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMItemACtivate = reinterpret_cast(pNMHDR); NMLISTVIEW* pNMListView = (NMLISTVIEW *)pNMHDR; if (-1 != pNMListView->iItem) { m_sName = m_list.GetItemText(pNMListView->iItem, 0); m_dHeight = TypeConvert::s2i(m_list.GetItemText(pNMListView->iItem, 1)); m_dWidth = TypeConvert::s2i(m_list.GetItemText(pNMListView->iItem, 2)); m_dDeep = TypeConvert::s2i(m_list.GetItemText(pNMListView->iItem, 3)); m_sUse = m_list.GetItemText(pNMListView->iItem, 4); m_sDesc = m_list.GetItemText(pNMListView->iItem, 5); UpdateData(FALSE); } *pResult = 0; } void CBDQGDlg::refreshList() { m_list.DeleteAllItems(); _Records::const_iterator it(m_datas.begin()); for (int i(0); it != m_datas.end(); ++it, ++i) { m_list.InsertItem(i, it->_sName); m_list.SetItemText(i, 1, TypeConvert::i2s(it->_dHeight)); m_list.SetItemText(i, 2, TypeConvert::i2s(it->_dWidth)); m_list.SetItemText(i, 3, TypeConvert::i2s(it->_dDeep)); m_list.SetItemText(i, 4, it->_sUse); m_list.SetItemText(i, 5, it->_sDesc); } } int CBDQGDlg::_Record::getBinarySize() { return 3 * sizeof(int) + _sName.GetLength() * sizeof(TCHAR) + _sUse.GetLength() * sizeof(TCHAR) + _sDesc.GetLength() * sizeof(TCHAR) + 3; // 最后+3为了截断字符串 } void CBDQGDlg::_Record::makeBinary(void *&pData, int &nSize) { nSize = getBinarySize(); pData = new byte[nSize]; ::memset(pData, 0, nSize); byte *p((byte*)pData); ::memcpy(p, &_dHeight, sizeof(int)); p += sizeof(int); ::memcpy(p, &_dWidth, sizeof(int)); p += sizeof(int); ::memcpy(p, &_dDeep, sizeof(int)); p += sizeof(int); ::memcpy(p, _sName.GetBuffer(), sizeof(TCHAR) * _sName.GetLength()); _sName.ReleaseBuffer(); p += sizeof(TCHAR) * _sName.GetLength() + 1; ::memcpy(p, _sUse.GetBuffer(), sizeof(TCHAR) * _sUse.GetLength()); _sUse.ReleaseBuffer(); p += sizeof(TCHAR) * _sUse.GetLength() + 1; ::memcpy(p, _sDesc.GetBuffer(), sizeof(TCHAR) * _sDesc.GetLength()); _sDesc.ReleaseBuffer(); } void CBDQGDlg::_Record::fromBinary(const void *pData) { if (!pData) return; byte *p((byte*)pData); ::memcpy(&_dHeight, p, sizeof(int)); p += sizeof(int); ::memcpy(&_dWidth, p, sizeof(int)); p += sizeof(int); ::memcpy(&_dDeep, p, sizeof(int)); p += sizeof(int); _sName = p; p += sizeof(TCHAR) * _sName.GetLength() + 1; _sUse = p; p += sizeof(TCHAR) * _sUse.GetLength() + 1; _sDesc = p; } #pragma endregion #pragma region DBClick_DQG ACRX_CONS_DEFINE_MEMBERS(DBClick_DQG, AecDbXDraw, 0); DBClick_DQG::DBClick_DQG(void) { } DBClick_DQG::~DBClick_DQG(void) { } Acad::ErrorStatus DBClick_DQG::Edit() { AcDbObjectId idDqg; GetAttach(idDqg); AcDbObjectPointer equ(idDqg, AcDb::kForWrite); if (equ.openStatus() != Acad::eOk) return equ.openStatus(); AcGePoint3d ptIns; AcGeVector3d vtDir; CAcModuleResourceOverride myResources; CBDQGDlg dlg; if (!dlg.initByEqu(equ.object(), ptIns, vtDir)) { acutPrintf(_T("\n无效的电气柜!")); return Acad::eInvalidInput; } if (dlg.DoModal() == IDOK) { equ->erase(); AecDbEwEquipment *pEqu = dlg.getEqu(ptIns, vtDir); if (pEqu) CoreTools::AddToModelSpace(pEqu); } return Acad::eOk; } #pragma endregion