#include "StdAfx.h" #include #include "AecUIContextMenu.h" #include "AecDbEntityBase.h" #include "AecDbCurveBase.h" #include "AecDbEwEquipment.h" #include "aecdbewpipe.h" #include "AecDbEwFitting.h" #include "CoreTools.h" #include "aecdb3droad.h" #include "AecDb3dRoadFitting.h" #include "AecDbECFitting.h" #include "AecDbEwPipeBase.h" #include "AecDbHvacDuct.h" #include "AecDbX3dPartEntity.h" #include "shJson.h" #include "TypeConvert.h" #include "FilePath.h" namespace { bool isSHEntity(const AcDbObjectId &id) { if (UIMenuItem::isKindOf(id) || UIMenuItem::isKindOf(id)) return true; return false; } bool isSHEntity(const AcDbObjectIdArray &ids) { for (int i(0); i < ids.length(); ++i) { if (!isSHEntity(ids[i])) return false; } return true; } bool getSingleSelect(ads_name adsEnt, bool bClearPickFirst = true) { ads_name ssSet; if (acedSSGet(NULL, NULL, NULL, NULL, ssSet) == RTNORM) { acedSSName(ssSet, 0, adsEnt); acedSSFree(ssSet); // 清空当前选择 if (bClearPickFirst) acedSSSetFirst(NULL, NULL); return true; } return false; } //一个 Polyline 自身是否所有点共线 bool isPolylineSelfCollinear(const AcDbObjectId &id) { AcDbObjectPointer ent(id, AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return true; // 打开失败算共线 AcDbPolyline *pPoly(ent.object()); return CoreTools::isPolylineSelfCollinear(pPoly); } void idsToSelection(const AcDbObjectIdArray &ids, ads_name &ss) { // 创建一个空的选择集 acedSSAdd(NULL, NULL, ss); ads_name entName; for (int i = 0; i < ids.length(); i++) { // 将 ID 转为 ads_name if (acdbGetAdsName(entName, ids[i]) == Acad::eOk) { // 加入选择集 acedSSAdd(entName, ss, ss); } } } void appendMenu(HMENU hMenu , const UINT_PTR id , LPCTSTR psz , int idx = -1 , UINT flags = MF_STRING | MF_ENABLED ) { static CString sIdx = _T("0123456789ABCDEFGHIJKUMNOPQRSTUVWXYZabcdefghijkumnopqrstuvwxyz"); if (idx == -1) { ::AppendMenu(hMenu, flags, id, psz); return; } CString str(_T("&")); if (idx >= sIdx.GetLength()) idx = 0; str += sIdx[idx]; str += _T(". "); ::AppendMenu(hMenu, flags, id, str + psz); } AcGePoint3d getPickPoint() { AcGePoint3d ptOut(AcGePoint3d::kOrigin); CPoint ptCursor; ::GetCursorPos(&ptCursor); HWND hDocWnd = adsw_acadDocWnd(); if (hDocWnd == NULL) return ptOut; ::ScreenToClient(hDocWnd, &ptCursor); struct resbuf rb; acedGetVar(_T("CVPORT"), &rb); int cvport = rb.resval.rint; ads_point ptResult; if (acedCoordFromPixelToWorld(cvport, ptCursor, ptResult)) { ptOut.set(ptResult[X], ptResult[Y], ptResult[Z]); } return ptOut; } // 将 AcDbObjectIdArray 转换为 resbuf 链表 // 格式: RTENAME, , RTENAME, , ..., RTNONE resbuf *makeResbuf(const AcDbObjectIdArray &ids) { // 1. 如果数组为空,直接返回 NULL (或者一个仅包含 RTNONE 的节点,视需求而定) // 通常返回 NULL 表示没有数据,acedCmd 会处理 NULL if (ids.isEmpty()) { return NULL; } resbuf *pHead = NULL; // 链表头指针 resbuf *pTail = NULL; // 链表尾指针,用于快速追加 for (int i = 0; i < ids.length(); ++i) { // 2. 获取实体 ID const AcDbObjectId &id = ids[i]; // 3. 将 ObjectId 转换为 ads_name ads_name entName; if (acdbGetAdsName(entName, id) != Acad::eOk) { // 如果转换失败(例如实体已被删除),跳过该实体 continue; } // 4. 创建新的 resbuf 节点 // acutNewRb 分配内存,记得最后要释放 resbuf *pNode = acutNewRb(RTENAME); if (pNode == NULL) { // 内存分配失败,清理已分配的链表并返回 NULL if (pHead) acutRelRb(pHead); return NULL; } // 5. 复制 ads_name 到 resbuf 中 // 注意:ads_name 是一个数组 (long[2]),必须复制内容,不能直接赋值指针 pNode->resval.rlname[0] = entName[0]; pNode->resval.rlname[1] = entName[1]; // 6. 链接到链表 if (pHead == NULL) { pHead = pNode; // 第一个节点 pTail = pNode; } else { pTail->rbnext = pNode; // 追加到尾部 pTail = pNode; // 更新尾指针 } } // 7. 在链表末尾追加 RTNONE 节点 (作为结束标志) // 许多 ADS 函数(如 acedCmd)需要 RTNONE 结尾,但有些(如 acedSSGet)可能不需要。 // 根据你的描述 "最后是 RTNONE",我们加上它。 if (pHead != NULL) { resbuf *pEndNode = acutNewRb(RTNONE); if (pEndNode) { pTail->rbnext = pEndNode; } else { // 极端情况下内存不足,清理并返回 acutRelRb(pHead); return NULL; } } return pHead; } void analyCfgFile(std::vector &cats , std::map &mapWeight , std::map &mapUsed ) { using namespace SHJson; // 1. 初始化:清空传入的容器,防止多次调用时数据叠加 cats.clear(); mapWeight.clear(); mapUsed.clear(); // 2. 获取配置文件路径 CString sPath = FilePath::GetSysDir() + AecObjectUIContext::outputFileName; // 3. 读取并解析 JSON 文件 WDocument doc; if (!file2Json(sPath, doc)) { // 如果文件不存在或解析失败,直接返回空容器 return; } CString sClass; int iWeight = 0; bool bUsed(false); // 4. 遍历 JSON 根节点(每个成员代表一个分类) for (MIt it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) { // 获取分类的 Key 并转换为 UIMenuItem::Category 枚举,存入 vector CString sCatKey = it->name.GetString(); int iCat = _ttoi(sCatKey); cats.push_back(static_cast(iCat)); // 5. 确保分类的值是一个数组,然后遍历数组中的菜单项 if (!it->value.IsArray()) continue; const WValue &arr = it->value; MCIt cit; for (SHJson::VCIt vit = arr.Begin(); vit != arr.End(); ++vit) { if (!vit->IsObject()) continue; cit = vit->FindMember(_T("class")); if (cit != vit->MemberEnd() && cit->value.IsString()) sClass = cit->value.GetString(); cit = vit->FindMember(_T("weight")); if (cit != vit->MemberEnd() && cit->value.IsInt()) iWeight = cit->value.GetInt(); cit = vit->FindMember(_T("used")); if (cit != vit->MemberEnd() && cit->value.IsBool()) bUsed = cit->value.GetBool(); // 存入 map 中 (只要 class 名称不为空) if (!sClass.IsEmpty()) { mapWeight[sClass] = iWeight; mapUsed[sClass] = bUsed; } } } } } #pragma region command #define SEND_EXEC_CMD(subcmd)\ acDocManager->sendStringToExecute(acDocManager->curDocument(), m_sCommand + subcmd, false, false, false) resbuf *Filter_Condition_N_ENT::executeCommand() const { // N 个实体按照顺序发送 // 清空选择集 acedSSSetFirst(0, NULL); // 实际上,不会出现N和m_arIds数量不一致的情况,在判断菜单是否有效时就会判断 resbuf *pEntBuf = makeResbuf(m_arIds); if (!pEntBuf) return NULL; resbuf *pRes = acutBuildList(RTSTR, m_sCommand, RTNONE); pRes->rbnext = pEntBuf; return pRes; } resbuf *Fitler_Condition_Interface_Ins::executeCommand() const { ads_point pt; pt[X] = m_ptPick.x; pt[Y] = m_ptPick.y; pt[Z] = m_ptPick.z; return acutBuildList(RTSTR, m_sCommand, RT3DPOINT, pt, RTNONE); } bool Fitler_Condition_Interface_Ins::eanbleCondition(const AcDbObjectIdArray &ar, const AcGePoint3d &pt) { if (ar.length() != 1) return false; if (!m_pFunc) return false; // 1.是否满足列表 if (!m_pFunc(ar, pt, m_sFilter, m_N)) return false; // 2.是否是能得到接口的类 if (!isAecMInterfaces(ar.first())) return false; // 3.得到所有接口 AcDbEntityPointer ent(ar.first(), AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; AecMInterfaces *pInterface = dynamic_cast(ent.object()); if (!pInterface) return false; int count = pInterface->GetInterfaceCount(); if (count == 0) return false; AcGePoint3d pt1(AcGePoint3d::kOrigin), pt2(pt); pt2.z = 0; AecInterface inf; for (int i(0); i < count; ++i) { pInterface->GetInterface(i, inf); pt1.x = inf.ptPos.x; pt1.y = inf.ptPos.y; if (pt1.distanceTo(pt2) > 50) continue; else { m_ptPick = inf.ptPos; return true; } } return false; } resbuf *Filter_Condition_Sender::executeCommand() const { SEND_EXEC_CMD(_T(" ")); return NULL; } #pragma endregion #pragma region UIMenuItem AcDbObjectIdArray UIMenuItem::m_arIds; bool UIMenuItem::isOneSHEntity(CONDI_PARAMS_IMP) { return isOneAndKindOf(ar, pt) || isOneAndKindOf(ar, pt); } bool UIMenuItem::isClosedPLine(CONDI_PARAMS_IMP) { if (isOneAndKindOf(ar, pt)) { AcDbObjectPointer ent(ar.first(), AcDb::kForRead); if (ent.openStatus() == Acad::eOk && ent->isClosed()) return true; } return false; } bool UIMenuItem::canQModify(CONDI_PARAMS_IMP) { // 只要有一个上华实体就可以 for (int i(0); i < ar.length(); ++i) { if (isKindOf(ar[i]) || isKindOf(ar[i])) return true; } return false; } bool UIMenuItem::isOneValve(CONDI_PARAMS_IMP) { if (!isOneAndKindOf(ar, pt)) return false; AcDbEntityPointer ent(ar.first(), AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; AecDbEwEquipment *pEqu(AecDbEwEquipment::cast(ent)); if (!pEqu) return false; int subRuntime(0), valveType(0); pEqu->GetAt(KEY_SUBRUNTIME, subRuntime); if (subRuntime != eValve) return false; if (!pEqu->GetAt(PIPE_VALVE, valveType)) return false; return true; } bool UIMenuItem::isAllSHEntity(CONDI_PARAMS_IMP) { for (int i(0); i < ar.length(); ++i) { if (!isSHEntity(ar[i])) return false; } return true; } CString UIMenuItem::getClassName(UIMenuItem * pItem) { const std::type_info &info = typeid(*pItem); return CString(info.name()).Mid(6); } bool UIMenuItem::compareItems(const UIMenuItem *a, const UIMenuItem *b) { if (!a || !b) return false; // 1. 先比分类 if (a->m_iCategory != b->m_iCategory) return a->m_iCategory < b->m_iCategory; // 2. 分类相同,再比权重 return a->m_iWeight < b->m_iWeight; } bool UIMenuItem::compareItemsByCategory(const UIMenuItem *a, const UIMenuItem *b) { if (!a || !b) return false; return a->m_iCategory < b->m_iCategory; } void UIMenuItem::BuildPickFist() { if (m_arIds.length() > 0) { ads_name ss; idsToSelection(m_arIds, ss); acedSSSetFirst(ss, ss); acedSSFree(ss); } } CString UIMenuItem::getCategoryName(const Category & cat) { switch (cat) { case eSys: return CString(_T("系统")); case eCr: return CString(_T("生成实体")); case eCrPipe: return _T("管线实体"); case eCrStut: return _T("土建实体"); case eCrHVAC: return _T("暖通实体"); case eCrElec: return _T("电气实体"); case eDsPipe: return _T("管线设计"); case eDsStut: return _T("土建设计"); case eDsEqui: return _T("设备设计"); case eDsHVAC: return _T("暖通设计"); case eDsElec: return _T("电气设计"); case eInsFitting: return _T("插入管件"); case eCrEqui: return _T("设备实体"); case eInsParamValve: return _T("参数阀门"); case eInsCustomValve: return _T("自定义阀门"); case eDimStut: return _T("土建标注"); case eDimSys: return _T("系统标注"); case eOpView: return _T("视图操作"); case eExport: return _T("数据中心"); default: break; } return CString(); } bool UIMenuItem::isVertPipe(CONDI_PARAMS_IMP) { if (ar.length() != 1) return false; AcDbObjectPointer ent(ar.first(), AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; AcGeVector3d vtDir = ent->GetTailDir(); if (!vtDir.isParallelTo(AcGeVector3d::kZAxis) && !vtDir.isParallelTo(-AcGeVector3d::kZAxis)) return false; return true; } bool UIMenuItem::isFlange(CONDI_PARAMS_IMP) { if (ar.length() != 1) return false; AcDbObjectPointer ent(ar.first(), AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; int nType(0); ent->GetAt(KEY_RUNTIME, nType); return nType == eFlange; } bool UIMenuItem::isEquButNoValve(CONDI_PARAMS_IMP) { if (!isOneAndKindOf(ar, pt)) return false; return !isOneValve(ar, pt); } bool UIMenuItem::isSlab(CONDI_PARAMS_IMP) { if (isOneAndKindOf(ar, pt)) return true; return isXSlab(ar, pt); } bool UIMenuItem::isXSlab(CONDI_PARAMS_IMP) { if (isOneAndKindOf(ar, pt)) { return !isPolylineSelfCollinear(ar.first()); } return false; } bool UIMenuItem::isAecMInterfaces(const AcDbObjectId &id) { if (isSameOf(id) || isSameOf(id) || isSameOf(id) || isSameOf(id) || isSameOf(id) || isKindOf(id) // AecDbEwPipeBase派生的都是 || isSameOf(id) || isSameOf(id) ) return true; return false; } bool UIMenuItem::idMatchFilter(const AcDbObjectId &id, LPCTSTR sFilter) { if (!sFilter) return false; AcRxClass *pRx = id.objectClass(); if (!pRx) return false; const TCHAR *dxfName = pRx->dxfName(); if (!dxfName) return false; return acutWcMatch(dxfName, sFilter) == RTERROR ? false : true; } // 实体的dxf是否满足 Filter bool UIMenuItem::isFilterMacth(CONDI_PARAMS_IMP, LPCTSTR sFilter, const int &N) { // 如果N==-1,说明命令需要用户选择多个实体, // 当命令需要多个实体的时候,都会自带过滤器, // 会自动过滤出需要的实体,所以,只要符合条件的实体大于1 // 就可以把选择集抛给命令取舍了 if (N <= 0) { int num(0); for (int i(0); i < ar.length(); ++i) { if (idMatchFilter(ar[i], sFilter)) num++; // N 的意义在于 这个命令虽然需要大于1个的实体, // 但是至少需要abs(N)个实体才能工作 if (num >= -N) return true; } return false; } // 当N是具体数值是,说明ar的数量不仅要等于N // 它们的类型也都要满足 filter if (ar.length() != N) return false; for (int i(0); i < ar.length(); ++i) { if (!idMatchFilter(ar[i], sFilter)) return false; } return true; } bool UIMenuItem::eanbleCondition(const AcDbObjectIdArray & ar, const AcGePoint3d & pt) { if (!ar.isEmpty()) { m_arIds = ar; m_ptPick = pt; return true; } return false; } void UIMenuItem::addToMenu(const HMENU & hMenu, const int &idx) const { if (!hMenu) return; appendMenu(hMenu, m_idCommand, m_sUIName, idx); } resbuf* UIMenuItem::executeCommand() const { if (m_bUseSingleEntity) { ads_name adsEnt; if (getSingleSelect(adsEnt)) return acutBuildList(RTSTR, m_sCommand, RTENAME, adsEnt, RTNONE); } else { // 不管选择了几个实体,都直接发送,PICKFIRST已经在外部构建 SEND_EXEC_CMD(_T(" ")); return NULL; } // 多个实体,用sendStringToExecute通过选择集来传递实体 if (m_arIds.length() > 1) SEND_EXEC_CMD(_T(" ")); else { // 单个实体用 acedCmd ads_name adsEnt; if (getSingleSelect(adsEnt)) return acutBuildList(RTSTR, m_sCommand, RTENAME, adsEnt, RTNONE); } return NULL; } #pragma endregion // 暂存选中的 ID 数组 static AcDbObjectIdArray g_cachedIdsForCmd; // 暂存要执行的操作 ID static int g_cachedCmdIndex = 0; AecObjectUIContext* AecObjectUIContext::g_pBaseUIContext = NULL; AecDefaultUIContext* AecDefaultUIContext::g_pDefaultContext = NULL; const CString AecObjectUIContext::outputFileName = _T("\\uicontext.cfg"); #pragma region AecObjectUIContext AecObjectUIContext::AecObjectUIContext(): m_hMenu(NULL) { remakeMenuItems(); initMenuItems(); } AecObjectUIContext::~AecObjectUIContext() { if (m_hMenu) { ::DestroyMenu(m_hMenu); m_hMenu = NULL; } deleteContainerOfStd>(m_menuItems); } void AecObjectUIContext::analyCfgFile() { std::map weights; std::map useds; ::analyCfgFile(m_sortCategories, weights, useds); if (weights.empty() || useds.empty()) return; CString className; std::map::const_iterator itW; std::map::const_iterator itU; for (size_t i(0); i < m_menuItems.size(); ++i) { UIMenuItem *pItem(m_menuItems[i]); if (!pItem) continue; className = UIMenuItem::getClassName(pItem); itW = weights.find(className); if (itW != weights.end()) pItem->m_iWeight = itW->second; itU = useds.find(className); if (itU != useds.end()) pItem->m_bUsed = itU->second; } } void AecObjectUIContext::buildMenu(const AcDbObjectIdArray &ids, const AcGePoint3d &ptPick) { if (m_hMenu) { ::DestroyMenu(m_hMenu); m_hMenu = NULL; } m_hMenu = ::CreatePopupMenu(); if (!m_hMenu) return; std::pair range; UIMenuItem item; int idx(0); HMENU hSubMenu(NULL); for (size_t i(0); i < m_sortCategories.size(); ++i) { item.m_iCategory = m_sortCategories[i]; range = std::equal_range( m_menuItems.begin(), m_menuItems.end(), &item, // 传入指针用于比较 UIMenuItem::compareItemsByCategory // 比较函数 ); if (range.first == range.second) continue; // 没有该类别的菜单项,跳过 // 系统级命令,直接插入 if (item.m_iCategory == UIMenuItem::eSys) { hSubMenu = m_hMenu; } else { hSubMenu = ::CreatePopupMenu(); appendMenu(m_hMenu , (UINT_PTR)hSubMenu , UIMenuItem::getCategoryName(item.m_iCategory) , ++idx , MF_POPUP); idx = 0; } UIItemVector::const_iterator it(range.first); for (; it != range.second; ++it) { UIMenuItem *pItem = *it; if (!pItem) continue; if (!pItem->m_bUsed) continue; if(!pItem->eanbleCondition(ids, ptPick)) continue; pItem->addToMenu(hSubMenu, ++idx); } if (::GetMenuItemCount(hSubMenu) == 0 && hSubMenu != m_hMenu) { ::RemoveMenu(m_hMenu, (UINT_PTR)hSubMenu, MF_BYCOMMAND); ::DestroyMenu(hSubMenu); } idx = ::GetMenuItemCount(m_hMenu); } } void *AecObjectUIContext::getMenuContext(const AcRxClass *pClass, const AcDbObjectIdArray &ids) { if (ids.isEmpty()) return NULL; AcGePoint3d ptPick(getPickPoint()); UIMenuItem::m_arIds = ids; buildMenu(ids, ptPick); return &m_hMenu; } void AecObjectUIContext::onCommand(Adesk::UInt32 cmdIndex) { g_cachedCmdIndex = cmdIndex; acDocManager->sendStringToExecute(acDocManager->curDocument(), _T("_ui_context_command_helper_ ")); } UIMenuItem* AecObjectUIContext::findItemById(const UINT_PTR & id) { UIMenuItem ut(id); UIItemSet::const_iterator it = m_UIItemSet.find(&ut); if (it == m_UIItemSet.end()) return NULL; return *it; } void AecObjectUIContext::items2Json(LPCTSTR pszPath) const { using namespace SHJson; typedef std::map ITEMMAP; if (!pszPath) return; if (_taccess(pszPath, 0x0) == 0x0) ::DeleteFile(pszPath); ITEMMAP mapItems; std::pair pr; for (size_t i(0); i < m_menuItems.size(); ++i) { UIMenuItem *pItem(m_menuItems[i]); pr = mapItems.insert(std::make_pair(pItem->m_iCategory, UIItemVector())); pr.first->second.push_back(pItem); } WDocument doc; doc.SetArray(); ITEMMAP::const_iterator it(mapItems.begin()); WValue v; v.SetObject(); WValue ar; for (; it != mapItems.end(); ++it) { ar.SetArray(); const UIItemVector &vec(it->second); for (size_t i(0); i < vec.size(); ++i) { UIMenuItem *pItem(vec[i]); addMember(v, _T("class"), UIMenuItem::getClassName(pItem)); addMember(v, _T("name"), pItem->m_sUIName); addMember(v, _T("weight"), pItem->m_iWeight); // 此函数只为初始化使用,used字段永远为真 addMember(v, _T("used"), true); pushBack(ar, v); } addMember(doc, TypeConvert::i2s(it->first), ar); } json2File(pszPath, doc ,true); } void AecObjectUIContext::remakeMenuItems() { deleteContainerOfStd>(m_menuItems); m_menuItems.clear(); m_menuItems.push_back(new CO_COPY); m_menuItems.push_back(new CO_MOVE); m_menuItems.push_back(new PL_DTYC); m_menuItems.push_back(new PL_YCQT); m_menuItems.push_back(new PL_TMXS); m_menuItems.push_back(new CO_KSXZ); m_menuItems.push_back(new CO_ALIGN); m_menuItems.push_back(new CO_KSXG); m_menuItems.push_back(new PL_DTYG); m_menuItems.push_back(new PL_QMPS); m_menuItems.push_back(new PL_GYST); m_menuItems.push_back(new PL_JGST); m_menuItems.push_back(new PL_RYPD); m_menuItems.push_back(new PL_RZPD); m_menuItems.push_back(new PL_HZDB); m_menuItems.push_back(new PL_FZPB); m_menuItems.push_back(new PL_HZGB); m_menuItems.push_back(new PL_HZXB); m_menuItems.push_back(new PL_FZFM); m_menuItems.push_back(new PL_DXBQ); m_menuItems.push_back(new PL_QXHN); m_menuItems.push_back(new PL_GZZZ); m_menuItems.push_back(new PL_ZZDZ); m_menuItems.push_back(new PL_TYQG); m_menuItems.push_back(new PL_DLJC); m_menuItems.push_back(new PL_QTDD); m_menuItems.push_back(new PL_PLGL); m_menuItems.push_back(new PL_JXDQ); m_menuItems.push_back(new PL_BXDQ); m_menuItems.push_back(new PL_YHLT); m_menuItems.push_back(new PL_QTCC); m_menuItems.push_back(new PL_QTCM); m_menuItems.push_back(new PL_ZHMC); m_menuItems.push_back(new PL_CBKD); m_menuItems.push_back(new PL_CDKD); m_menuItems.push_back(new PL_BZZJ); m_menuItems.push_back(new PL_YXKD); m_menuItems.push_back(new PL_ZLKD); m_menuItems.push_back(new PL_DGKD); m_menuItems.push_back(new PL_JFZJ); m_menuItems.push_back(new PL_JFYJ); m_menuItems.push_back(new PL_JYZJ); m_menuItems.push_back(new PL_JYXJ); m_menuItems.push_back(new PL_JJSK); m_menuItems.push_back(new PL_CDST); m_menuItems.push_back(new PL_YXCG); m_menuItems.push_back(new PL_CJSY); m_menuItems.push_back(new PL_PMFY); m_menuItems.push_back(new PL_LJGD); m_menuItems.push_back(new PL_FYGX); m_menuItems.push_back(new PL_WTLG1); m_menuItems.push_back(new PL_DJWT); m_menuItems.push_back(new PL_45WT); m_menuItems.push_back(new PL_BJWT); m_menuItems.push_back(new PL_wmerge); m_menuItems.push_back(new PL_GXLJ); m_menuItems.push_back(new PL_GXBJ); m_menuItems.push_back(new PL_TJST1); m_menuItems.push_back(new PL_DJST); m_menuItems.push_back(new PL_PXST); m_menuItems.push_back(new PL_DZST); m_menuItems.push_back(new PL_EFST); m_menuItems.push_back(new PL_TJST2); m_menuItems.push_back(new PL_GXGM); m_menuItems.push_back(new PL_TJDT); m_menuItems.push_back(new PL_CRFL); m_menuItems.push_back(new PL_CDFL); m_menuItems.push_back(new PL_TJKG); m_menuItems.push_back(new PL_CRMB); m_menuItems.push_back(new PL_BZMB); m_menuItems.push_back(new PL_FZCB); m_menuItems.push_back(new PL_ZGBQ); m_menuItems.push_back(new PL_TJZT); m_menuItems.push_back(new PL_TJHJ); m_menuItems.push_back(new PL_JSJT); m_menuItems.push_back(new PL_WLJT); m_menuItems.push_back(new PL_NLJT); m_menuItems.push_back(new PL_GJBG); m_menuItems.push_back(new PL_SBLG); m_menuItems.push_back(new PL_UXBR); m_menuItems.push_back(new PL_XGXG); m_menuItems.push_back(new PL_LGGJ); m_menuItems.push_back(new PL_CXBG); m_menuItems.push_back(new PL_CRBQ); m_menuItems.push_back(new PL_SBDJ); m_menuItems.push_back(new PL_SBXZ1); m_menuItems.push_back(new PL_SBXZ2); m_menuItems.push_back(new PL_SBJC1); m_menuItems.push_back(new PL_SBJC2); m_menuItems.push_back(new PL_XGBG1); m_menuItems.push_back(new PL_XGBG2); m_menuItems.push_back(new PL_SBGZ); m_menuItems.push_back(new CO_SFXT1); m_menuItems.push_back(new CO_SFXT2); m_menuItems.push_back(new P3_CRZF); m_menuItems.push_back(new P3_CRDXZF); m_menuItems.push_back(new P3_CRJZF); m_menuItems.push_back(new P3_CRQF); m_menuItems.push_back(new P3_CRZHF); m_menuItems.push_back(new P3_CRDF); m_menuItems.push_back(new P3_CRPQF); m_menuItems.push_back(new P3_CRZSF); m_menuItems.push_back(new P3_CRFQF); m_menuItems.push_back(new P3_CRTJF); m_menuItems.push_back(new P3_CRSLKZF); m_menuItems.push_back(new P3_CRJYF); m_menuItems.push_back(new P3_CRPNF); m_menuItems.push_back(new P3_CRDCF); m_menuItems.push_back(new P3_GDBC); m_menuItems.push_back(new P3_CRSSJT); m_menuItems.push_back(new P3_CRCLJT); m_menuItems.push_back(new PL_CLBK); m_menuItems.push_back(new P3_CRXJJT); m_menuItems.push_back(new PL_CRZF); m_menuItems.push_back(new PL_CJZF); m_menuItems.push_back(new PL_AQFM); m_menuItems.push_back(new PL_CZHF); m_menuItems.push_back(new PL_CRDF); m_menuItems.push_back(new PL_CRJF); m_menuItems.push_back(new PL_CAQF); m_menuItems.push_back(new PL_STFM); m_menuItems.push_back(new PL_XTFM); m_menuItems.push_back(new PL_TJFM); m_menuItems.push_back(new PL_SSFM); m_menuItems.push_back(new PL_XSFM); m_menuItems.push_back(new PL_GMFM); m_menuItems.push_back(new PL_JYFM); m_menuItems.push_back(new PL_CBYF); m_menuItems.push_back(new PL_CZXF); m_menuItems.push_back(new PL_CCBF); m_menuItems.push_back(new PL_CPQF); m_menuItems.push_back(new PL_CJYF); m_menuItems.push_back(new PL_CPNF); m_menuItems.push_back(new PL_CDCF); m_menuItems.push_back(new PL_SSJT); m_menuItems.push_back(new PL_CLJT); m_menuItems.push_back(new PL_XJJT); m_menuItems.push_back(new PL_CRJZ); m_menuItems.push_back(new PL_QTDJ); m_menuItems.push_back(new PL_QTDY); m_menuItems.push_back(new PL_JBWC); m_menuItems.push_back(new PL_FFTM); m_menuItems.push_back(new PL_WQTP); m_menuItems.push_back(new PL_DXCH); m_menuItems.push_back(new PL_ZJCH); m_menuItems.push_back(new PL_JLHC); m_menuItems.push_back(new PL_FZYT); m_menuItems.push_back(new PL_FZTJ); m_menuItems.push_back(new PL_PFBZ); m_menuItems.push_back(new PL_DKBH); m_menuItems.push_back(new PL_DHFW); m_menuItems.push_back(new PL_BHYX); m_menuItems.push_back(new PL_DKBZ); m_menuItems.push_back(new PL_TGBZ); m_menuItems.push_back(new PL_YHBZ); m_menuItems.push_back(new PL_MCMM); m_menuItems.push_back(new PL_ZXBZ); m_menuItems.push_back(new PL_XSBZ); m_menuItems.push_back(new PL_XXBZ); m_menuItems.push_back(new PL_YCBZ); m_menuItems.push_back(new PL_YCSB); m_menuItems.push_back(new PL_ZZBZ); m_menuItems.push_back(new PL_ZZCB); m_menuItems.push_back(new PL_GJBZ); m_menuItems.push_back(new PL_FMBZ1); m_menuItems.push_back(new PL_FMBZ2); m_menuItems.push_back(new PL_SBBZ); m_menuItems.push_back(new HA_FBBZ); m_menuItems.push_back(new EL_QJBZ1); m_menuItems.push_back(new EL_QJBZ2); m_menuItems.push_back(new EL_DLBZ); m_menuItems.push_back(new CO_EXPORT); } void AecObjectUIContext::initMenuItems() { analyCfgFile(); // 得到以先种类后再权重排序的集合 std::sort(m_menuItems.begin(), m_menuItems.end(), UIMenuItem::compareItems); // 得到以id排序的集合 m_UIItemSet.clear(); m_UIItemSet.insert(m_menuItems.begin(), m_menuItems.end()); } void AecObjectUIContext::AddContext(void * pAppID) { if (g_pBaseUIContext == NULL) { AcRxClass *pEntityClass = AcDbEntity::desc(); if (pEntityClass && pAppID) { g_pBaseUIContext = new AecObjectUIContext(); acedAddObjectContextMenu(pEntityClass, g_pBaseUIContext, pAppID); } } } void AecObjectUIContext::DelContext() { if (g_pBaseUIContext != NULL) { AcRxClass *pEntityClass = AcDbEntity::desc(); if (pEntityClass) acedRemoveObjectContextMenu(pEntityClass, g_pBaseUIContext); DELETE_PTR(g_pBaseUIContext); } } void AecObjectUIContext::output2Json() { CString sPath = FilePath::GetSysDir() + AecObjectUIContext::outputFileName; AecObjectUIContext::g_pBaseUIContext->items2Json(sPath); } #pragma endregion #pragma region AecDefaultUIContext AecDefaultUIContext::AecDefaultUIContext(): m_hMenu(NULL) { } AecDefaultUIContext::~AecDefaultUIContext() { if (m_hMenu) { ::DestroyMenu(m_hMenu); m_hMenu = NULL; } } void *AecDefaultUIContext::getMenuContext(const AcRxClass *pClass, const AcDbObjectIdArray &ids) { if (m_hMenu) { ::DestroyMenu(m_hMenu); m_hMenu = NULL; } m_hMenu = ::CreatePopupMenu(); if (!m_hMenu) return NULL; UINT flags(MF_STRING | MF_ENABLED); int idx(1); appendMenu(m_hMenu, ID_CONTEXT_MENU_HIDE_SHOWALL, _T("显示全部"), idx++); appendMenu(m_hMenu, ID_CONTEXT_MENU_PL_DKBH, _T("编号排序"), idx++); appendMenu(m_hMenu, ID_CONTEXT_MENU_EXPORT_SWTT, _T("三维提图"), idx++); appendMenu(m_hMenu, NULL, NULL, -1, MF_SEPARATOR); HMENU hViewPort = ::CreatePopupMenu(); if (hViewPort) { appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_TOP, _T("俯 视"), 1); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_BOTTOM, _T("仰 视"), 2); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_LEFT, _T("左 视"), 3); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_RIGHT, _T("右 视"), 4); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_FRONT, _T("前 视"), 5); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_BACK, _T("后 视"), 6); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_SWISO, _T("西南等轴测"), 7); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_SEISO, _T("东南等轴测"), 8); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_NEISO, _T("东北等轴测"), 9); appendMenu(hViewPort, ID_CONTEXT_MENU_VIEW_NWISO, _T("西北等轴测"), 10); appendMenu(m_hMenu, (UINT_PTR)hViewPort, _T("视图"), idx++, MF_POPUP); } HMENU hOrbit = ::CreatePopupMenu(); if (hOrbit) { appendMenu(hOrbit, ID_CONTEXT_MENU_ORBIT_3D, _T("受约束的动态观察"), 1); appendMenu(hOrbit, ID_CONTEXT_MENU_ORBIT_3DF, _T("自由动态观察"), 2); appendMenu(hOrbit, ID_CONTEXT_MENU_ORBIT_3DC, _T("连续动态观察"), 3); appendMenu(m_hMenu, (UINT_PTR)hOrbit, _T("动态观察"), idx++, MF_POPUP); } HMENU hViewStyle = ::CreatePopupMenu(); if (hViewStyle) { appendMenu(hViewStyle, ID_CONTEXT_MENU_VSCURRENT_2, _T("二维线框"), 1); appendMenu(hViewStyle, ID_CONTEXT_MENU_VSCURRENT_W, _T("三维线框视觉样式"), 2); appendMenu(hViewStyle, ID_CONTEXT_MENU_VSCURRENT_H, _T("三维隐藏视觉样式"), 3); appendMenu(hViewStyle, ID_CONTEXT_MENU_VSCURRENT_R, _T("真实视觉样式"), 4); appendMenu(hViewStyle, ID_CONTEXT_MENU_VSCURRENT_C, _T("概念视觉样式"), 5); appendMenu(m_hMenu, (UINT_PTR)hViewStyle, _T("视觉样式"), idx++, MF_POPUP); } return &m_hMenu; } void AecDefaultUIContext::onCommand(Adesk::UInt32 cmdIndex) { g_cachedCmdIndex = cmdIndex; acDocManager->sendStringToExecute(acDocManager->curDocument(), _T("_ui_context_command_helper_ ")); } void AecDefaultUIContext::AddContext(void *pAppID) { if (g_pDefaultContext == NULL) { if (pAppID) { g_pDefaultContext = new AecDefaultUIContext(); acedAddDefaultContextMenu(g_pDefaultContext, pAppID, _T("✦ 上华软件 ✦")); } } } void AecDefaultUIContext::DelContext() { if (g_pDefaultContext != NULL) { acedRemoveDefaultContextMenu(g_pDefaultContext); DELETE_PTR(g_pDefaultContext); } } #pragma endregion #pragma region AecUIContext void AecUIContext::AddContext(void *pAppID) { AecObjectUIContext::AddContext(pAppID); AecDefaultUIContext::AddContext(pAppID); } void AecUIContext::DelContext() { AecObjectUIContext::DelContext(); AecDefaultUIContext::DelContext(); } #pragma endregion void _ui_context_command_helper_() { if (AecObjectUIContext::g_pBaseUIContext) { // 如果是AecObjectUIContext传过来的命令,则在这里处理 UIMenuItem *pItem = AecObjectUIContext::g_pBaseUIContext->findItemById(g_cachedCmdIndex); if (pItem) { // 构建选择集 UIMenuItem::BuildPickFist(); resbuf *pRes = pItem->executeCommand(); if (pRes) { SHacedCmd(pRes); acutRelRb(pRes); } return; } } // 下面的逻辑来处理 AecDefaultUIContext #pragma region default context menu commands resbuf *pRes(NULL); switch (g_cachedCmdIndex) { case ID_CONTEXT_MENU_PL_DKBH: pRes = acutBuildList(RTSTR, _T("PL_DKBH"), RTNONE); break; case ID_CONTEXT_MENU_HIDE_SHOWALL: pRes = acutBuildList(RTSTR, _T("PL_XSQB"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_TOP: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_top"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_BOTTOM: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_bottom"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_LEFT: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_left"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_RIGHT: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_right"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_FRONT: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_front"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_BACK: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_back"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_SWISO: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_swiso"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_SEISO: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_seiso"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_NEISO: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_neiso"), RTNONE); break; case ID_CONTEXT_MENU_VIEW_NWISO: pRes = acutBuildList(RTSTR, _T("_view"), RTSTR, _T("_nwiso"), RTNONE); break; case ID_CONTEXT_MENU_ORBIT_3D: pRes = acutBuildList(RTSTR, _T("_3dorbit"), RTNONE); break; case ID_CONTEXT_MENU_ORBIT_3DF: pRes = acutBuildList(RTSTR, _T("_3DFOrbit"), RTNONE); break; case ID_CONTEXT_MENU_ORBIT_3DC: pRes = acutBuildList(RTSTR, _T("_3DCOrbit"), RTNONE); break; case ID_CONTEXT_MENU_VSCURRENT_2: pRes = acutBuildList(RTSTR, _T("vscurrent"), RTSTR, _T("_2"), RTNONE); break; case ID_CONTEXT_MENU_VSCURRENT_W: pRes = acutBuildList(RTSTR, _T("vscurrent"), RTSTR, _T("_W"), RTNONE); break; case ID_CONTEXT_MENU_VSCURRENT_H: pRes = acutBuildList(RTSTR, _T("vscurrent"), RTSTR, _T("_H"), RTNONE); break; case ID_CONTEXT_MENU_VSCURRENT_R: pRes = acutBuildList(RTSTR, _T("vscurrent"), RTSTR, _T("_R"), RTNONE); break; case ID_CONTEXT_MENU_VSCURRENT_C: pRes = acutBuildList(RTSTR, _T("vscurrent"), RTSTR, _T("_C"), RTNONE); break; case ID_CONTEXT_MENU_EXPORT_SWTT: pRes = acutBuildList(RTSTR, _T("ew_swtt"), RTNONE); break; default: break; } if (pRes) { SHacedCmd(pRes); acutRelRb(pRes); } #pragma endregion }