Files
envi-code/SourceCode/Code2026/ElecCmd/BDQGDlg.cpp
T
2026-09-28 15:28:50 +08:00

598 lines
14 KiB
C++

#include "stdafx.h"
#include "BDQGDlg.h"
#include "AecDbEwEquipment.h"
#include "uihistory.h"
#include <functional>
#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 <typename T>
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 <typename T>
Adesk::Int32 addSubPrimObj(AecDbEwEquipment *pEqu, T &t, const AecEqui::Primitive &type)
{
AecEqui::XPrimData data;
data.m_eType = type;
setData<T>(&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<LPNMITEMACTIVATE>(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<AecDbEwEquipment> 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