#include "StdAfx.h" #include "resource.h" #include "BimPaletteSet.h" #include "coretools.h" #include "KTCADUtilityEx.h" #include "AecDbObjXDataMap.h" namespace { typedef std::vector > 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 &v, BIMDATA &rel) { rel.clear(); if (v.empty()) return; std::vector vv(v); // 按照BIMDATA的数量排序 // 理论上,共有的属性数量不会大于BIMDATA最小的一个 std::sort(vv.begin(), vv.end(), _com()); BIMDATA mini(vv[0]); BIMDATA::const_iterator it(mini.begin()); std::set 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 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 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::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 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 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