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

959 lines
21 KiB
C++

#include "StdAfx.h"
#include "resource.h"
#include "BimPaletteSet.h"
#include "coretools.h"
#include "KTCADUtilityEx.h"
#include "AecDbObjXDataMap.h"
namespace
{
typedef std::vector<std::pair<CString, CString> > BIMDATA;
class _com
{
public:
bool operator () (BIMDATA &a, BIMDATA &b) { return a.size() < b.size(); }
};
void getBimData(AcDbEntity *pEnt, BIMDATA &mm)
{
if (!pEnt) return;
mm.clear();
CoreTools::getBimDatas(pEnt, mm);
}
void mergeBimData(const std::vector<BIMDATA> &v, BIMDATA &rel)
{
rel.clear();
if (v.empty()) return;
std::vector<BIMDATA> vv(v);
// 按照BIMDATA的数量排序
// 理论上,共有的属性数量不会大于BIMDATA最小的一个
std::sort(vv.begin(), vv.end(), _com());
BIMDATA mini(vv[0]);
BIMDATA::const_iterator it(mini.begin());
std::set<CString> vals;
bool bAllHas(false);
for (; it != mini.end(); ++it)
{
vals.clear();
vals.insert(it->second);
bAllHas = true;
for (size_t i = 1; i < vv.size(); ++i)
{
BIMDATA &m(vv[i]);
bool bHas(false);
CString ss;
for (size_t f = 0; f < m.size(); ++f)
{
if (m[f].first == it->first)
{
bHas = true;
ss = m[f].second;
break;
}
}
if (!bHas)
{
bAllHas = false;
break;
}
vals.insert(ss);
}
if (bAllHas)
rel.push_back(BIMDATA::value_type(it->first, vals.size() == 1 ? (LPCTSTR)it->second : _T("*多种*")));
}
}
// 通过属性名称,找到在xdatamap保存的key,和对应的属性值sAttr
bool setBimDataByName(AcDbEntity *pEnt, LPCTSTR sName, LPCTSTR sAttr)
{
if (!pEnt) return false;
if (!sName) return false;
return CoreTools::setBimData(pEnt, sName, sAttr);
}
bool delBimDataByName(AcDbEntity *pEnt, LPCTSTR sName)
{
if (!pEnt) return false;
if (!sName) return false;
return CoreTools::delBimData(pEnt, sName);
}
}
#pragma region CBimPaletteSet
IMPLEMENT_DYNAMIC(CBimPaletteSet, CAdUiPaletteSet)
BEGIN_MESSAGE_MAP(CBimPaletteSet, CAdUiPaletteSet)
ON_WM_CREATE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
CBimPaletteSet * CBimPaletteSet::m_pMySelft = NULL;
CBimPaletteSet::CBimPaletteSet()
: m_pBimPalette(NULL)
, m_hDockBar(NULL)
, m_pfnOldProc(NULL)
, m_bTracking(FALSE)
{
m_pMySelft = this;
}
CBimPaletteSet::~CBimPaletteSet()
{
if (IsWindow(m_hDockBar))
UnsubclassDockBar();
m_pMySelft = NULL;
}
bool CBimPaletteSet::CreatePaletteSet(LPCTSTR pszTitle)
{
CMDIFrameWnd* pFrame = acedGetAcadFrame();
ASSERT(NULL != pFrame);
if (!Create(pszTitle, WS_CHILD | WS_VISIBLE | CBRS_SIZE_DYNAMIC | CBRS_RIGHT, CRect(0, 0, 160, 100), pFrame))
{
acutPrintf(_T("\n创建上华BIM属性表失败!"));
return FALSE;
}
EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT | CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM);
RestoreControlBar(AFX_IDW_DOCKBAR_RIGHT);
m_pBimPalette = new CBimPalette;
if (m_pBimPalette->Create(WS_CHILD | WS_VISIBLE, _T("上华BIM属性表"), this, NULL))
AddPalette(m_pBimPalette);
if (this->GetPaletteCount() > 0)
{
SetActivePalette(0);
}
SetTimer(1024, 600000, NULL);
return true;
}
void CBimPaletteSet::SetObjectIds(const AcDbObjectIdArray &ids)
{
if (m_pBimPalette)
m_pBimPalette->SetObjectIds(ids);
}
int CBimPaletteSet::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CAdUiPaletteSet::OnCreate(lpCreateStruct) == -1)
return -1;
CWnd* pWnd = GetDlgItem(idCloseBtn);
ASSERT(NULL != pWnd);
pWnd->EnableWindow(FALSE);
static GUID cMenuBar = { 0xbca92f11, 0x774, 0x4328, { 0x8f, 0x3d, 0xba, 0x91, 0x4a, 0xcf, 0xc3, 0x36 } };
SetToolID(&cMenuBar);
return 0;
}
void CBimPaletteSet::OnDestroy()
{
CAdUiPalette* pPage = NULL;
while (GetPaletteCount() > 0)
{
pPage = GetPalette(0);
RemovePalette(pPage);
delete pPage;
}
CAdUiPaletteSet::OnDestroy();
}
bool CBimPaletteSet::OnClosing()
{
return (IDYES != MessageBox(_T("上华BIM属性窗口即将关闭,执行“BP”命令即可重新打开。\n\n是否要关闭上华BIM属性窗口?"), _T("上华BIM属性窗口"), MB_YESNO | MB_ICONQUESTION));
}
void CBimPaletteSet::GetFloatingMinSize(long * plMinWidth, long * plMinHeight)
{
*plMinWidth = 40;
*plMinHeight = 100;
}
void CBimPaletteSet::SizeChanged(CRect * lpRect, BOOL bFloating, int flags)
{
CAdUiPaletteSet::SizeChanged(lpRect, bFloating, flags);
CRect rc(lpRect);
rc.DeflateRect(6, 6);
CString sKey;
CAdUiPalette* pPage = NULL;
for (int i = 0; i < GetPaletteCount(); i++)
{
pPage = GetPalette(i);
if (pPage != NULL)
{
((CBimPalette*)pPage)->MoveWindow(rc);
}
}
}
void CBimPaletteSet::GetMinimumSize(CSize & size)
{
CAdUiPaletteSet::GetMinimumSize (size) ;
}
void CBimPaletteSet::GetMaximumSize(CSize & size)
{
CAdUiPaletteSet::GetMaximumSize (size) ;
}
#define AS_DOCK_CONTROLBAR(pBar) ((CControlBar*)((DWORD_PTR(pBar) <= 0xffff) ? NULL : (pBar)))
CSize CBimPaletteSet::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
int iMajor = acdbHostApplicationServices()->releaseMajorVersion();
int iMinor = acdbHostApplicationServices()->releaseMinorVersion();
//if (iMajor >= 17 && iMinor >= 2) // 仅AutoCAD2009以后
if ((iMajor >= 17 && iMinor >= 2) || (iMajor > 17)) // 仅AutoCAD2009以后
{
BOOL bFloat = IsFloating();
if (bFloat)
{
UnsubclassDockBar();
}
else
{
int iPos;
CDockBar* pDockBar = DYNAMIC_DOWNCAST(CDockBar, GetParent());
if (NULL != pDockBar && ((iPos = pDockBar->FindBar(this)) > 0 && NULL != AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos - 1]) && AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos - 1])->IsVisible()
|| NULL != AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos + 1]) && AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos + 1])->IsVisible()))
{
UnsubclassDockBar();
}
else
{
SubclassDockBar(pDockBar->GetSafeHwnd());
}
}
}
return CAdUiPaletteSet::CalcFixedLayout(bStretch, bHorz);
}
BOOL CBimPaletteSet::SubclassDockBar(HWND hWnd)
{
if (NULL == hWnd)
return FALSE;
if (m_hDockBar == hWnd)
return TRUE;
UnsubclassDockBar();
m_hDockBar = hWnd;
#ifdef _WIN64
m_pfnOldProc = (WNDPROC)SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LPARAM)&CBimPaletteSet::DockBarProc);
#else
m_pfnOldProc = (WNDPROC)SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)&CBimPaletteSet::DockBarProc);
#endif
ASSERT(NULL != m_pfnOldProc);
return TRUE;
}
void CBimPaletteSet::UnsubclassDockBar()
{
if (NULL == m_hDockBar || NULL == m_pfnOldProc)
return;
#ifdef _WIN64
VERIFY(SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&CBimPaletteSet::DockBarProc);
#else
VERIFY(SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&CBimPaletteSet::DockBarProc);
#endif
m_hDockBar = NULL;
m_pfnOldProc = NULL;
}
UINT CBimPaletteSet::OnTrackHitTest(CPoint pt)
{
CRect rc;
UINT nHit = OnGetTrackRect(::GetDlgCtrlID(m_hDockBar), rc);
return (rc.PtInRect(pt) ? nHit : HTNOWHERE);
}
UINT CBimPaletteSet::OnGetTrackRect(UINT nDockOrHit, CRect & rc)
{
CRect rc1;
GetWindowRect(&rc1);
CWnd::FromHandle(m_hDockBar)->ScreenToClient(&rc1);
CRect rc2;
::GetClientRect(m_hDockBar, &rc2);
CSize szBorder;
szBorder.cx = GetSystemMetrics(SM_CXFRAME);
szBorder.cy = GetSystemMetrics(SM_CYFRAME);
switch (nDockOrHit)
{
case HTLEFT:
case AFX_IDW_DOCKBAR_RIGHT:
rc.SetRect(rc1.left - szBorder.cx, rc2.top, rc1.left, rc2.bottom);
return HTLEFT;
case HTRIGHT:
case AFX_IDW_DOCKBAR_LEFT:
rc.SetRect(rc1.right, rc2.top, rc1.right + szBorder.cx, rc2.bottom);
return HTRIGHT;
case HTTOP:
case AFX_IDW_DOCKBAR_BOTTOM:
rc.SetRect(rc2.left, rc1.top - szBorder.cy, rc2.right, rc1.top);
return HTTOP;
case HTBOTTOM:
case AFX_IDW_DOCKBAR_TOP:
rc.SetRect(rc2.left, rc1.bottom, rc2.right, rc1.bottom + szBorder.cy);
return HTBOTTOM;
default:
ASSERT(FALSE);
return HTNOWHERE;
}
}
void CBimPaletteSet::OnStartTracking(UINT nHit)
{
m_bTracking = TRUE;
::SetCapture(m_hDockBar);
::RedrawWindow(m_hDockBar, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
OnGetTrackRect(nHit, m_rcTracking);
OnTrackPaint();
}
void CBimPaletteSet::OnTrackUpdate(CPoint pt)
{
UINT nDock = ::GetDlgCtrlID(m_hDockBar);
BOOL bHorz = (AFX_IDW_DOCKBAR_TOP == nDock || AFX_IDW_DOCKBAR_BOTTOM == nDock);
CSize szOff = pt - m_rcTracking.CenterPoint();
((bHorz) ? szOff.cx : szOff.cy) = 0;
CSize szLimit;
GetFloatingMinSize(&szLimit.cx, &szLimit.cy);
CRect rc;
GetWindowRect(&rc);
CWnd::FromHandle(m_hDockBar)->ScreenToClient(&rc);
switch (nDock)
{
case AFX_IDW_DOCKBAR_LEFT:
if ((m_rcTracking.left + szOff.cx) - rc.left < szLimit.cx)
return;
break;
case AFX_IDW_DOCKBAR_RIGHT:
if (rc.right - (m_rcTracking.right + szOff.cx) < szLimit.cx)
return;
break;
case AFX_IDW_DOCKBAR_TOP:
if ((m_rcTracking.top + szOff.cy) - rc.top < szLimit.cy)
return;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
if (rc.bottom - (m_rcTracking.bottom + szOff.cy) < szLimit.cy)
return;
break;
}
OnTrackPaint();
m_rcTracking.OffsetRect(szOff);
OnTrackPaint();
}
void CBimPaletteSet::OnStopTracking()
{
m_bTracking = FALSE;
::ReleaseCapture();
OnTrackPaint();
CRect rc;
UINT nDock = ::GetDlgCtrlID(m_hDockBar);
UINT nHit = OnGetTrackRect(nDock, rc);
CSize szOff = m_rcTracking.CenterPoint() - rc.CenterPoint();
GetWindowRect(&rc);
switch (nHit)
{
case HTLEFT:
rc.left += szOff.cx;
break;
case HTRIGHT:
rc.right += szOff.cx;
break;
case HTTOP:
rc.top += szOff.cy;
break;
case HTBOTTOM:
rc.bottom += szOff.cy;
break;
}
DockControlBar(nDock, rc);
m_pDockSite->DelayRecalcLayout();
}
void CBimPaletteSet::OnTrackPaint()
{
CWnd* pWnd = CWnd::GetDesktopWindow();
CDC *pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
CBrush* pBrush = CDC::GetHalftoneBrush();
CBrush* pBrushOld = pDC->SelectObject(pBrush);
CRect rc(m_rcTracking);
CWnd::FromHandle(m_hDockBar)->ClientToScreen(&rc);
pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT);
pDC->SelectObject(pBrushOld);
pWnd->ReleaseDC(pDC);
}
LRESULT CBimPaletteSet::OnDockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
ASSERT(NULL != m_pfnOldProc && m_hDockBar == hWnd);
switch (nMessage)
{
case WM_LBUTTONDOWN:
if (!m_bTracking)
{
CPoint pt(lParam);
UINT nHit = OnTrackHitTest(pt);
if ((HTLEFT | HTRIGHT) & nHit)
{
OnStartTracking(nHit);
return 0l;
}
}
break;
case WM_MOUSEMOVE:
if (m_bTracking)
{
CPoint pt(lParam);
OnTrackUpdate(pt);
return 0l;
}
break;
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
if (m_bTracking)
{
OnStopTracking();
return 0l;
}
break;
case WM_CAPTURECHANGED:
if (m_bTracking && ((HWND)lParam != hWnd))
{
OnStopTracking();
}
break;
}
return CallWindowProc(m_pfnOldProc, hWnd, nMessage, wParam, lParam);
}
LRESULT CBimPaletteSet::DockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
ASSERT(NULL != m_pMySelft);
return m_pMySelft->OnDockBarProc(hWnd, nMessage, wParam, lParam);
}
#pragma endregion
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma region CBimPalette
IMPLEMENT_DYNAMIC(CBimPalette, CAdUiPalette)
BEGIN_MESSAGE_MAP(CBimPalette, CAdUiPalette)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_WINDOWPOSCHANGED()
ON_BN_CLICKED(IDC_BIMPAT_BTNADD, &CBimPalette::OnBtnClickAdd)
ON_BN_CLICKED(IDC_BIMPAT_BTNMOD, &CBimPalette::OnBtnClickMod)
ON_BN_CLICKED(IDC_BIMPAT_BTNDEL, &CBimPalette::OnBtnClickDel)
ON_BN_CLICKED(IDC_BIMPAT_BTNIMP, &CBimPalette::OnBtnClickImp)
ON_BN_CLICKED(IDC_BIMPAT_BTNEXP, &CBimPalette::OnBtnClickExp)
ON_CBN_SELCHANGE(IDC_BIMPAT_COMBO, &CBimPalette::OnComboBoxSelChange)
END_MESSAGE_MAP()
inline CBimPalette::CBimPalette()
: m_pComboBox(NULL)
, m_pBtnAdd(NULL)
, m_pBtnMod(NULL)
, m_pBtnDel(NULL)
, m_pBtnImp(NULL)
, m_pBtnExp(NULL) {}
inline CBimPalette::~CBimPalette()
{
DELETE_PTR(m_pComboBox);
DELETE_PTR(m_pBtnAdd);
DELETE_PTR(m_pBtnMod);
DELETE_PTR(m_pBtnDel);
DELETE_PTR(m_pBtnImp);
DELETE_PTR(m_pBtnExp);
DELETE_PTR(m_pListCtrl);
::DeleteObject(m_font);
}
void CBimPalette::SetObjectIds(const AcDbObjectIdArray& ids)
{
m_pComboBox->ResetContent();
m_pListCtrl->DeleteAllItems();
m_ids.removeAll();
m_mapIDs.clear();
CString dxf(_T(""));
#if ARX > 23
std::pair<IDMap::iterator, bool> pb;
#else
IDMap::_Pairib pb;
#endif
AecDbObjXDataMap xData;
SH_BIM_BLOCK bims;
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AcDbEntity, pEnt)
{
if (!pEnt) continue;
// 任何实体都可以
//if (!CoreTools::isSHObject(pEnt))
//{
// CoreTools::getBimDatas(pEnt, bims);
// if (bims.empty()) continue;
//}
AcDbBlockReference *pRef(AcDbBlockReference::cast(pEnt));
if (pRef) // 对块参照的名称特殊处理
{
AcDbObjectId idRcd = pRef->blockTableRecord();
if (!idRcd.isValid()) continue;
AcDbBlockTableRecordPointer pRcd(idRcd, AcDb::kForRead);
if (pRcd.openStatus() != Acad::eOk) continue;
const TCHAR *pszName = NULL;
pRcd->getName(pszName);
dxf = pszName;
}
else
dxf = CoreTools::dxf2Chs(pEnt->isA()->dxfName());
m_ids.append(pEnt->objectId());
pb = m_mapIDs.insert(std::make_pair(dxf, AcDbObjectIdArray()));
pb.first->second.append(pEnt->objectId());
}
OPENOBJ_END()
}
if (m_ids.isEmpty())
{
if (m_pComboBox->AddString(_T("未选择上华对象")) != CB_ERR)
m_pComboBox->SetCurSel(0);
return;
}
if (m_mapIDs.size() > 1)
m_pComboBox->AddString(_T("*全部*"));
IDMap::const_iterator it(m_mapIDs.begin());
for (; it != m_mapIDs.end(); ++it)
{
m_pComboBox->AddString(CString(it->first) + _T(" (") + TypeConvert::i2s(it->second.length()) + _T(")"));
}
if (m_pComboBox->GetCount())
m_pComboBox->SetCurSel(0);
RefreshList();
}
void CBimPalette::OnBtnClickAdd()
{
AcAxDocLock lock;
AcDbObjectIdArray ids(0);
GetSelIDs(ids);
if (ids.isEmpty()) return;
CString v1(_T("")), v2(_T(""));
CAcModuleResourceOverride myResources;
while (CoreTools::getBimDataByDlg(true, v1, v2))
{
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForWrite, AcDbEntity, pEnt)
{
if (pEnt)
setBimDataByName(pEnt, v1, v2);
}
OPENOBJ_END()
RefreshList();
}
}
}
void CBimPalette::OnBtnClickMod()
{
AcAxDocLock lock;
AcDbObjectIdArray ids(0);
GetSelIDs(ids);
if (ids.isEmpty()) return;
CString name(_T("")), value(_T(""));
if (!GetSelBimData(name, value)) return;
CAcModuleResourceOverride myResources;
if (!CoreTools::getBimDataByDlg(false, name, value)) return;
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForWrite, AcDbEntity, pEnt)
{
if (pEnt)
setBimDataByName(pEnt, name, value);
}
OPENOBJ_END()
}
RefreshList();
}
void CBimPalette::OnBtnClickDel()
{
AcAxDocLock lock;
AcDbObjectIdArray ids(0);
GetSelIDs(ids);
if (ids.isEmpty()) return;
CString name(_T("")), value(_T(""));
if (!GetSelBimData(name, value)) return;
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForWrite, AcDbEntity, pEnt)
{
if (pEnt)
delBimDataByName(pEnt, name);
}
OPENOBJ_END()
}
RefreshList();
}
void CBimPalette::OnBtnClickImp()
{
AcAxDocLock lock;
AcDbObjectIdArray ids(0);
GetSelIDs(ids);
if (ids.isEmpty()) return;
CFileDialog dlg(TRUE, _T("*.ini"), NULL, OFN_HIDEREADONLY, _T("bim导入数据 (*.ini)|*.ini||"), acedGetAcadFrame());
if (dlg.DoModal() != IDOK) return;
std::map<CString, CString> datas1, datas2;
CString name, value;
for (int i = 0; i < m_pListCtrl->GetItemCount(); ++i)
{
name = m_pListCtrl->GetItemText(i, 0);
value = m_pListCtrl->GetItemText(i, 1);
datas1.insert(std::make_pair(name, value));
}
CoreTools::iniFile2BimData(dlg.GetPathName(), datas2);
datas1.insert(datas2.begin(), datas2.end());
for (int i = 0; i < ids.length(); ++i)
{
OPENOBJ_BEGIN(ids[i], AcDb::kForWrite, AcDbEntity, pEnt)
{
if (!pEnt) continue;
std::map<CString, CString>::iterator it(datas1.begin());
for (; it != datas1.end(); ++it)
setBimDataByName(pEnt, it->first, it->second);
}
OPENOBJ_END()
}
RefreshList();
}
void CBimPalette::OnBtnClickExp()
{
CFileDialog dlg(FALSE, _T("*.ini"), NULL, OFN_HIDEREADONLY, _T("bim导出数据 (*.ini)|*.ini||"), acedGetAcadFrame());
if (dlg.DoModal() != IDOK) return;
std::map<CString, CString> datas;
CString name, value;
for (int i = 0; i < m_pListCtrl->GetItemCount(); ++i)
{
name = m_pListCtrl->GetItemText(i, 0);
value = m_pListCtrl->GetItemText(i, 1);
datas.insert(std::make_pair(name, value));
}
CoreTools::bimData2IniFile(dlg.GetPathName(), datas);
}
void CBimPalette::OnComboBoxSelChange()
{
RefreshList();
}
int CBimPalette::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CAdUiPalette::OnCreate(lpCreateStruct) == -1)
return -1;
CClientDC dc(this);
CoreTools::createFont(&m_font, _T("Arial Unicode Ms"), 12, &dc);
CoreTools::createFont(&m_fontCombo, _T("Arial Unicode Ms"), 9, &dc);
DWORD dwStyle(WS_CHILD | WS_VISIBLE);
CRect rctmp;
do
{
m_pBtnDel = new CAcUiBitmapButton();
if (!m_pBtnDel->Create(_T("✖")
, dwStyle | BS_PUSHBUTTON
, rctmp
, this
, IDC_BIMPAT_BTNDEL)) break;
m_pBtnDel->SetFont(&m_font);
m_pBtnMod = new CAcUiBitmapButton();
if (!m_pBtnMod->Create(_T("✎")
, dwStyle | BS_PUSHBUTTON
, rctmp
, this
, IDC_BIMPAT_BTNMOD)) break;
m_pBtnMod->SetFont(&m_font);
m_pBtnAdd = new CAcUiBitmapButton();
if (!m_pBtnAdd->Create(_T("✙")
, dwStyle | BS_PUSHBUTTON
, rctmp
, this
, IDC_BIMPAT_BTNADD)) break;
m_pBtnAdd->SetFont(&m_font);
m_pBtnImp = new CAcUiBitmapButton();
if (!m_pBtnImp->Create(_T("➘")
, dwStyle | BS_PUSHBUTTON
, rctmp
, this
, IDC_BIMPAT_BTNIMP)) break;
m_pBtnImp->SetFont(&m_font);
m_pBtnExp = new CAcUiBitmapButton();
if (!m_pBtnExp->Create(_T("➚")
, dwStyle | BS_PUSHBUTTON
, rctmp
, this
, IDC_BIMPAT_BTNEXP)) break;
m_pBtnExp->SetFont(&m_font);
m_pComboBox = new CAcUiComboBox();
if (!m_pComboBox->Create(dwStyle | CBS_DROPDOWNLIST
, rctmp
, this
, IDC_BIMPAT_COMBO)) break;
m_pComboBox->SetFont(&m_fontCombo);
m_pListCtrl = new CAcUiListCtrl();
if (!m_pListCtrl->Create(
dwStyle
| LVS_SINGLESEL
| LVS_REPORT
| LVS_ALIGNLEFT
//| LVS_EDITLABELS
| LVS_SHOWSELALWAYS
//| LVS_SORTASCENDING
, rctmp
, this
, IDC_BIMPAT_LISTCTRL)) break;
m_pListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_SINGLEROW);
m_pListCtrl->InsertColumn(0, _T("名称"), LVCFMT_CENTER, 100);
m_pListCtrl->InsertColumn(1, _T("属性"), LVCFMT_CENTER, 100);
return 0;
} while (false);
DELETE_PTR(m_pComboBox);
DELETE_PTR(m_pBtnAdd);
DELETE_PTR(m_pBtnMod);
DELETE_PTR(m_pBtnDel);
DELETE_PTR(m_pListCtrl);
return -1;
}
#define MOVE_WINDOW(wnd,rc) if (wnd && ::IsWindow(wnd->GetSafeHwnd())) wnd->MoveWindow(rc)
void CBimPalette::CalcCtrlPosition(CRect & rc)
{
double dScale = CoreTools::GetDPIScale();
const CSize szBtn(int(24 * dScale), int(24 * dScale));
int n1(int(1 * dScale)), n2(int(2 * dScale)), n3(int(3 * dScale)), n5(int(5 * dScale)), n7(int(7 * dScale));
CRect rctmp(CPoint(rc.right - n1 - szBtn.cx, rc.top + n1), szBtn);
MOVE_WINDOW(m_pBtnExp, rctmp);
rctmp.left -= (n1 + szBtn.cx);
rctmp.right -= (n1 + szBtn.cx);
MOVE_WINDOW(m_pBtnImp, rctmp);
rctmp.left -= (n1 + szBtn.cx);
rctmp.right -= (n1 + szBtn.cx);
MOVE_WINDOW(m_pBtnDel, rctmp);
rctmp.left -= (n1 + szBtn.cx);
rctmp.right -= (n1 + szBtn.cx);
MOVE_WINDOW(m_pBtnMod, rctmp);
rctmp.left -= (n1 + szBtn.cx);
rctmp.right -= (n1 + szBtn.cx);
MOVE_WINDOW(m_pBtnAdd, rctmp);
CRect rect;
m_pComboBox->GetWindowRect(rect);
int h((rctmp.Height() - rect.Height()) * .5);
rctmp = CRect(CPoint(rc.left + n1, rctmp.top + h), CSize(rc.Width() - (n7 + 5 * szBtn.cx), szBtn.cy));
MOVE_WINDOW(m_pComboBox, rctmp);
rctmp = CRect(CPoint(rc.left + n1, rc.top + n2 + szBtn.cx), CSize(rc.Width() - n2, rc.Height() - n3 - szBtn.cy));
MOVE_WINDOW(m_pListCtrl, rctmp);
}
void CBimPalette::GetSelIDs(AcDbObjectIdArray & ids)
{
int idx = m_pComboBox->GetCurSel();
if (idx == CB_ERR) return;
CString ss;
m_pComboBox->GetLBString(idx, ss);
if ((idx = ss.Find(_T(" ("))) != -1) // 选择的是一类实体
{
ss = ss.Left(idx);
IDMap::const_iterator it = m_mapIDs.find(ss);
if (it == m_mapIDs.end()) return;
ids = it->second;
}
else // 全部
ids = m_ids;
}
bool CBimPalette::GetSelBimData(CString & name, CString & value)
{
int idx = m_pListCtrl->GetSelectionMark();
if (idx < 0)
{
AfxMessageBox(_T("请选择一行BIM属性。"));
return false;
}
name = m_pListCtrl->GetItemText(idx, 0);
value = m_pListCtrl->GetItemText(idx, 1);
return true;
}
void CBimPalette::RefreshList()
{
m_pListCtrl->DeleteAllItems();
AcDbObjectIdArray ids(0);
GetSelIDs(ids);
std::vector<BIMDATA> v(0);
BIMDATA bim;
for (int i = 0; i < ids.length(); ++i)
{
bim.clear();
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AcDbEntity, pEnt)
{
if (pEnt)
{
getBimData(pEnt, bim);
v.push_back(bim);
}
}
OPENOBJ_END()
}
bim.clear();
mergeBimData(v, bim);
BIMDATA::const_iterator it(bim.begin());
int nitem;
for (int i = 0; it != bim.end(); ++it, ++i)
{
nitem = m_pListCtrl->InsertItem(i, it->first);
m_pListCtrl->SetItemText(nitem, 1, it->second);
}
}
void CBimPalette::OnWindowPosChanged(WINDOWPOS * lpwndpos)
{
CAdUiPalette::OnWindowPosChanged(lpwndpos);
CRect rc;
GetClientRect(rc);
rc.InflateRect(-3, -1, -3, -1);
CalcCtrlPosition(rc);
}
void CBimPalette::OnPaint()
{
CPaintDC dc(this);
CRect rc;
GetClientRect(rc);
rc.InflateRect(-2, 0, -2, 0);
dc.FillSolidRect(rc, RGB(158, 158, 158));
rc.InflateRect(-1, -1, -1, -1);
dc.FillSolidRect(rc, RGB(240, 240, 240));
}
void CBimPalette::GetFloatingMinSize(long * pnMinWidth, long * pnMinHeight)
{
*pnMinWidth = 74;
*pnMinHeight = 200;
}
#pragma endregion