https://www.cnblogs.com/edata/p/12463675.html
这是关于多段线pline命令中的撤销功能的简单代码
代码使用了事务管理器来执行增加对象和撤销处理.
代码
/// <summary> /// 简单模拟多段线绘制过程的撤销功能. /// code by edata 2020-3-11 /// </summary> /// <remarks>简单模拟多段线绘制过程的_u撤销功能.仅考虑了UCS问题</remarks> //设置坐标系转换缓冲区链表 resbuf ucs,wcs; ucs.restype=RTSHORT; ucs.resval.rint=1; wcs.restype=RTSHORT; wcs.resval.rint=0; ads_point pt; ads_point ptWcs; if (RTNORM != acedGetPoint(NULL,_T("\n 选择起点: "),pt)) { return; } acedTrans(pt,&ucs,&wcs,0,ptWcs); AcGePoint3d p1=asPnt3d(ptWcs); AcGePoint3d ptStart=p1; AcDbPolyline *pPoly=NULL; //开启事务管理器 AcTransaction *pTrans =actrTransactionManager->startTransaction(); while (true) { CString strPrompt=_T("\n 选择下一个点[(U)撤销]: "); CString strKword=_T("Undo _ u"); if (pPoly!=NULL) { int nCount =pPoly->numVerts(); if (nCount>1) { strPrompt=_T("\n 选择下一个点[(U)撤销/(C)闭合]: "); strKword=_T("Undo Close _ u c"); } } //设置使用Undo关键字,该值允许使用ctrl+z撤销 acedInitGet(NULL,strKword); int nRet=acedGetPoint(pt,strPrompt,pt); if (RTKWORD == nRet) { ACHAR szKword[132]; if (RTNORM != acedGetInput(szKword)) { continue; } if (_tcscmp(szKword,_T("u")) == 0) { if (pPoly != NULL) { int nCount = pPoly->numVerts(); if (nCount>0) { //此处使用removeVertexAt不能移除仅剩的一个点,后面对1个点的线取消事务 Acad::ErrorStatus es= pPoly->removeVertexAt(nCount-1); //重新生成 pPoly->draw(); if (nCount>1) { pPoly->getEndPoint(p1); pt[X] = p1.x; pt[Y] = p1.y; pt[Z] = p1.z; acedTrans(pt,&wcs,&ucs,0,pt); } else { p1=ptStart; pt[X] = p1.x; pt[Y] = p1.y; pt[Z] = p1.z; acedTrans(pt,&wcs,&ucs,0,pt); } } } } else if (_tcscmp(szKword,_T("c")) == 0) { if (pPoly!=NULL) { int nCount =pPoly->numVerts(); if (nCount>1) { pPoly->setClosed(true); break; } } } continue; } else if (RTNORM != nRet) { break; } acedTrans(pt,&ucs,&wcs,0,ptWcs); AcGePoint3d p2=asPnt3d(ptWcs); //处理多段线图形 if (pPoly == NULL) { pPoly = new AcDbPolyline(); pPoly->addVertexAt(0,AcGePoint2d(p1.x,p1.y)); pPoly->addVertexAt(1,AcGePoint2d(p2.x,p2.y)); //添加到当前数据库当前空间 AddEntToCurSpace(pPoly); //添加对象到事务处理 actrTransactionManager->addNewlyCreatedDBRObject(pPoly); //显示图形 pPoly->draw(); } else { int nCount = pPoly->numVerts(); pPoly->addVertexAt(nCount,AcGePoint2d(p2.x,p2.y)); //显示图形 pPoly->draw(); } p1=p2; } if (pPoly == NULL) { //未创建多段线,终止事务 actrTransactionManager->abortTransaction(); return; } else { int nCount = pPoly->numVerts(); if (nCount == 1) { //仅有一个点,终止事务 actrTransactionManager->abortTransaction(); return; } } //事务结束 actrTransactionManager->endTransaction();
AddEntToCurSpace 添加实体对象到当前数据库当前空间
代码
static Acad::ErrorStatus AddEntToCurSpace(AcDbEntity *pEnt) { AcDbObjectId objId=AcDbObjectId::kNull; return AddEntToCurSpace(pEnt,objId); } static Acad::ErrorStatus AddEntToCurSpace(AcDbEntity *pEnt,AcDbObjectId &objId) { if (pEnt == NULL) { return Acad::eNullEntityPointer; } AcDbBlockTableRecordPointer pBlkRcd(acdbHostApplicationServices()->workingDatabase()->currentSpaceId(),AcDb::kForWrite); if (Acad::eOk != pBlkRcd.openStatus()) { return pBlkRcd.openStatus(); } return pBlkRcd->appendAcDbEntity(objId,pEnt); }
结束语:使用事务管理器的时候,事务中的对象不能使用close()关闭对象了;
文章评论