1287 lines
33 KiB
C++
1287 lines
33 KiB
C++
#include "StdAfx.h"
|
|
#include <typeinfo>
|
|
#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<AecDbEntityBase>(id)
|
|
|| UIMenuItem::isKindOf<AecDbCurveBase>(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<AcDbPolyline> 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, <name1>, RTENAME, <name2>, ..., 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<UIMenuItem::Category> &cats
|
|
, std::map<CString, int> &mapWeight
|
|
, std::map<CString, bool> &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<UIMenuItem::Category>(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<AecMInterfaces *>(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<AecDbEntityBase>(ar, pt) || isOneAndKindOf<AecDbCurveBase>(ar, pt);
|
|
}
|
|
|
|
bool UIMenuItem::isClosedPLine(CONDI_PARAMS_IMP)
|
|
{
|
|
if (isOneAndKindOf<AcDbPolyline>(ar, pt))
|
|
{
|
|
AcDbObjectPointer<AcDbPolyline> 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<AecDbCurveBase>(ar[i]) || isKindOf<AecDbEntityBase>(ar[i]))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool UIMenuItem::isOneValve(CONDI_PARAMS_IMP)
|
|
{
|
|
if (!isOneAndKindOf<AecDbEwEquipment>(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<AecDbEwPipe> 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<AecDbEwFitting> 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<AecDbEwEquipment>(ar, pt)) return false;
|
|
return !isOneValve(ar, pt);
|
|
}
|
|
|
|
bool UIMenuItem::isSlab(CONDI_PARAMS_IMP)
|
|
{
|
|
if (isOneAndKindOf<AcDbCircle>(ar, pt)) return true;
|
|
return isXSlab(ar, pt);
|
|
}
|
|
|
|
bool UIMenuItem::isXSlab(CONDI_PARAMS_IMP)
|
|
{
|
|
if (isOneAndKindOf<AcDbPolyline>(ar, pt))
|
|
{
|
|
return !isPolylineSelfCollinear(ar.first());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool UIMenuItem::isAecMInterfaces(const AcDbObjectId &id)
|
|
{
|
|
if (isSameOf<AecDb3dRoad>(id)
|
|
|| isSameOf<AecDb3dRoadFitting>(id)
|
|
|| isSameOf<AecDbEcFitting>(id)
|
|
|| isSameOf<AecDbEwEquipment>(id)
|
|
|| isSameOf<AecDbEwFitting>(id)
|
|
|| isKindOf<AecDbEwPipeBase>(id) // AecDbEwPipeBase派生的都是
|
|
|| isSameOf<AecDbHvacDuct>(id)
|
|
|| isSameOf<AecDbX3dPartEntity>(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<std::vector<UIMenuItem *>>(m_menuItems);
|
|
}
|
|
|
|
void AecObjectUIContext::analyCfgFile()
|
|
{
|
|
std::map<CString, int> weights;
|
|
std::map<CString, bool> useds;
|
|
::analyCfgFile(m_sortCategories, weights, useds);
|
|
|
|
if (weights.empty() || useds.empty()) return;
|
|
|
|
CString className;
|
|
std::map<CString, int>::const_iterator itW;
|
|
std::map<CString, bool>::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<UIItemVector::const_iterator, UIItemVector::const_iterator> 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<UIMenuItem::Category, UIItemVector> ITEMMAP;
|
|
|
|
if (!pszPath) return;
|
|
|
|
if (_taccess(pszPath, 0x0) == 0x0)
|
|
::DeleteFile(pszPath);
|
|
|
|
ITEMMAP mapItems;
|
|
std::pair<ITEMMAP::iterator, bool> 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<std::vector<UIMenuItem *>>(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
|
|
}
|
|
|