简单模拟多段线绘制Pline命令过程的撤销功能

简单模拟多段线绘制Pline命令过程的撤销功能

这是关于多段线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()关闭对象了;

猜你喜欢

转载自www.cnblogs.com/edata/p/12463675.html
今日推荐