在本教程的准备文件中已备好所需头文件及源文件,如下所示:
教程 MyCFilter.h
教程 MyCFilter.cpp
在本教程中,我们使用控件\MxDraw52\Src\MxDraw5.2\samples\Edit项目进行添加自定义实体演示。
运行VS,打开“Edit”项目,添加MyCFilter类(本教程使用已准备好的文件)。在 TestCommands.cpp 头文件中包含“MyCFilter.h”,并在 CTestCommands 类的RegisterCommand函数下调用 MyFilterByMrxDbgSelSet 类的RegisterCommand函数。
在上述操作中,我们将类及其命令注册进了控件系统,而后我们将调用命令来实现过滤。
在本实例中,我们将使用构造选择集(MrxDbgSelSet类)进行过滤,该类封装了选择集及其处理函数,支持如下过滤条件,且当对象被析构的时候,将自动释放选择集。
| 参数类型 | 类型 | |
|---|---|---|
| RTDXF0 | TEXT | 文字 |
| MTEXT | 多行文字 | |
| CIRCLE | 圆 | |
| ARC | 圆弧 | |
| LINE | 线 | |
| LWPOLYLINE | 多段线 | |
| INSERT | 图块 | |
| ELLIPSE | 椭圆 | |
| SPLINE | 样条线 | |
| LinkLine | 超链接 | |
| 8 | 图层 | |
| 2 | 图块 | |
| -4 | 通配符 | |
| 62 | 颜色 | |
| -3 | 扩展数据 | |
接下来将解释MyCFilter类下的命令及其过滤的含义。
userSelect function
作用:与用户交互,选择实体。
接口:SelSetStatus userSelect(const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByIN()
{
MrxDbgSelSet ss;
auto eResult = ss.userSelect();
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}allSelect function
作用:选择全部实体。
接口:SelSetStatus allSelect(const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByX()
{
MrxDbgSelSet ss;
auto eResult = ss.allSelect();
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}userSelect function
作用:与用户交互,选择实体。
接口:SelSetStatus userSelect(LPCTSTR selectPrompt, LPCTSTR removePrompt, const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
selectPrompt | 选择对象时的提示 |
removePrompt | 从选择集中删除对象时的提示(没用) |
filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByIN1()
{
MrxDbgSelSet ss;
auto eResult = ss.userSelect(L"提示1", L"删除1");
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}impliedSelect function
作用:返回当前图上已经选择的实体。
接口:SelSetStatus impliedSelect(const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByI()
{
MrxDbgSelSet ss;
auto eResult = ss.impliedSelect();
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}crossingSelect function
作用:由p1,p2交叉框选实体,实体在pt和p2组成的矩形框内或与矩形框边线相交都放入选择集。
接口:SelSetStatus crossingSelect(
const McGePoint3d & pt1,
const McGePoint3d & pt2,
const resbuf * filter = NULL
);
参数:
| 名称 | 说明 |
|---|---|
pt1 | 矩形窗口的第一个角点,UCS坐标 |
pt2 | 矩形窗口的第二个角点,UCS坐标 |
filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByW()
{
MrxDbgSelSet ss;
auto eResult = ss.crossingSelect(
McGePoint3d(0, 0, 0),
McGePoint3d(100, 100, 0));
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}crossingPolygonSelect function
作用:指向一个点链表,点集合组成一个多边形区域,在这个区域内的和多边形的边相交的实体都放入到选择集中。
接口:SelSetStatus crossingPolygonSelect(const McGePoint3dArray & ptArray, const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
| ptArray | 构成多边形的点表,UCS坐标 |
| filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByCP()
{
MrxDbgSelSet ss;
McGePoint3dArray vecPos;
vecPos.append(McGePoint3d(-195, 270, 0));
vecPos.append(McGePoint3d(490, 395, 0));
vecPos.append(McGePoint3d(436, -124, 0));
vecPos.append(McGePoint3d(-76, -60, 0));
vecPos.append(McGePoint3d(-238, 54, 0));
vecPos.append(McGePoint3d(-195, 270, 0));
auto eResult = ss.crossingPolygonSelect(vecPos);
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}lastSelect function
作用:选择最后一次选择的实体。
接口:SelSetStatus lastSelect(const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
| filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByLast()
{
MrxDbgSelSet ss;
auto eResult = ss.lastSelect();
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}pointSelect function
作用:根据光标所在位置,选择靶框内的实体。
接口:SelSetStatus pointSelect(const McGePoint3d & pt1, const resbuf * filter = NULL);
参数:
| 名称 | 说明 |
|---|---|
| pt1 | 要构造选择集的目标点,UCS坐标 |
| filter | 过滤表 |
参考例程:
void MyFilterByMrxDbgSelSet::SelSetByPt()
{
MrxDbgSelSet ss;
auto eResult = ss.pointSelect(McGePoint3d(-48, 135, 0));
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
}SelSetBySetHight function
作用:设置mcedSSGet函数执行用户选择时,被选择的对象的高亮显示回调函数。
接口:void setHighlightCallback(
bool (*pSSGetHighlightFunPtr)(
IN McDbEntity * pEnt,
IN bool isHighlight,
IN void * pUserData),
void * pUserData = NULL
);
参数:
| 名称 | 说明 |
|---|---|
| pSSGetHighlightFunPtr | 回调函数的指针 |
| pEnt | 选择的实体 |
| isHighlight | 是否高亮 |
| pUserData | 用户自定义数据,将从回调函数中传入 |
参考例程:
bool SS9Test(IN McDbEntity * pEnt, IN bool isHighlight, IN void * pUserData)
{
int * sEnt = static_cast<int*>(pUserData);
McDbExtents cRect;
pEnt->getGeomExtents(cRect);
McDbLine * pLine1 = new McDbLine(cRect.minPoint(), cRect.maxPoint());
McDbLine * pLine2 = new McDbLine(
McGePoint3d(cRect.minPoint().x, cRect.maxPoint().y, 0),
McGePoint3d(cRect.maxPoint().x, cRect.minPoint().y, 0));
MrxDbgUtils::addToCurrentSpaceAndClose(pLine1);
MrxDbgUtils::addToCurrentSpaceAndClose(pLine2);
vId.push_back(pLine1->objectId());
vId.push_back(pLine2->objectId());
return false;
}
void MyFilterByMrxDbgSelSet::SelSetBySetHight()
{
MrxDbgSelSet ss;
int iLen(10);
ss.setHighlightCallback(SS9Test, &iLen);
ss.userSelect();
McDbObjectIdArray arrayId;
ss.asArray(arrayId);
std::for_each(vId.begin(), vId.end(), [](McDbObjectId id) {
McDbObjectPointer<McDbEntity> spEnt(id, McDb::kForWrite);
if (spEnt.openStatus() != Mcad::eOk)
return;
spEnt->erase();
});
PrintVecEntName(arrayId);
}SelSetBySetHight function
作用:创建一个链表数据,该函数是变参数的,可以一下传入多个链表数据,返回的链表数据在不使用时调用mcutRelRb释放内存。
接口:ARXDLL struct resbuf * mcutBuildList (int rtype, ...);
参数:
| 名称 | 说明 |
|---|---|
rtype | 参数类型 |
... | 变参数 |
参考例程:
void MyFilterByMrxDbgSelSet::MrxDbgfilter()
{
auto FuncSelect = [](resbuf * pFilter)
{
MrxDbgSelSet ss;
ss.allSelect(pFilter);
Mx::mcutRelRb(pFilter);
McDbObjectIdArray vId;
ss.asArray(vId);
PrintVecEntName(vId);
};
auto FuncEnt = [&FuncSelect](int rType, CString pStr)
{
FuncSelect(Mx::mcutBuildList(rType, pStr, 0));
};
auto FuncEnt1 = [&FuncSelect](
int rType0, CString pStr0,
int rType1, CString pStr1,
bool isOr
)
{
if (isOr)
{
FuncSelect(Mx::mcutBuildList(
-4, _T("<OR"), rType0, pStr0,
rType1, pStr1, -4, _T("OR>"),
0));
}
else
{
FuncSelect(Mx::mcutBuildList(
-4, _T("<AND"), rType0, pStr0,
rType1, pStr1, -4, _T("AND>"),
0));
}
};
//基本类型
FuncEnt(RTDXF0, _T("TEXT"));
FuncEnt(RTDXF0, _T("MTEXT"));
FuncEnt(RTDXF0, _T("CIRCLE"));
FuncEnt(RTDXF0, _T("ARC"));
FuncEnt(RTDXF0, _T("LINE"));
FuncEnt(RTDXF0, _T("LWPOLYLINE"));
FuncEnt(RTDXF0, _T("INSERT"));
FuncEnt(RTDXF0, _T("ELLIPSE"));
FuncEnt(RTDXF0, _T("SPLINE"));
FuncEnt(RTDXF0, _T("TEXT,CIRCLE,SPLINE"));
//图层
FuncEnt(8, _T("TEST1"));
FuncEnt(8, _T("TEST3"));
//图块
FuncEnt(2, _T("123"));
// //“或”连接
FuncEnt1(RTDXF0, _T("TEXT"), 8, _T("TestColor1"), true);
FuncEnt1(RTDXF0, _T("CIRCLE"), 8, _T("TestColor1"), true);
FuncEnt1(RTDXF0, _T("CIRCLE"), RTDXF0, _T("TEXT"), true);
// //“与”连接
FuncEnt1(RTDXF0, _T("TEXT"), 8, _T("TestColor1"), false);
FuncEnt1(RTDXF0, _T("CIRCLE"), 8, _T("TestColor1"), false);
}注意:在上述的滤过演示中,我们根据“基本类型”、“图层”、“图块”及“按位OR”和“按位AND”,在过滤时,我们需要在参数中填入类型,而在后跟类型名,如只选择文字时,我们需要在第一个参数填入“RTDXF0”,而在下一个参数填入类型,这里的类型如都是输入“RTDXF0”类型下的基本类型,则可以使用逗号隔开进行填入, 而在连接符号中,我们需要使用成对的符号进行填写,如选择“基本类型”中的“TEXT”且在“TestColor1”层时,我们需要写成:
Mx::mcutBuildList(
-4, _T("<AND"), RTDXF0, _T("TEXT"),
8, _T("TestColor1"), -4, _T("AND>"),
0));在“按位与”的条件中,我们要将同时存在的类型放在"<AND"与"AND>"之中,筛选条件必须以“0”结束,且参数链表需要通过
ARXDLL int mcutRelRb (struct resbuf *rb)
进行释放。