梦想CAD控件自定义实体实现

一、增加自定义实体对象


调用DrawCustomEntity函数,绘制一个自定义实体对象。


下面代码绘制一个自定义实体,C#代码实现如下:


private void DrawMlineCommand() {     MxDrawUiPrPoint getPt = new MxDrawUiPrPoint();     getPt.message = "点取第一点";     if (getPt.go() != MCAD_McUiPrStatus.mcOk)     {         return;     }                   var frstPt = getPt.value();     if (frstPt == null)     {         return;     }        MxDrawUiPrPoint getSecondPt = new MxDrawUiPrPoint();        getSecondPt.message = "点取第二点";     getSecondPt.basePoint = frstPt;        getSecondPt.setUseBasePt(false);        MxDrawCustomEntity spDrawData = getSecondPt.InitUserDraw("DrawCustEntity");     spDrawData.SetDouble("Width", 30);        spDrawData.SetPoint("Point1", frstPt);        Int32 lCount = 1;     spDrawData.SetLong("Count", 1);                   while (true)     {         if (getSecondPt.go() != MCAD_McUiPrStatus.mcOk)             break;            var secondPt = getSecondPt.value();         if (secondPt == null)             break;            lCount++;            String sPointName = "Point" + lCount.ToString();            spDrawData.SetPoint(sPointName, secondPt);         spDrawData.SetLong("Count", lCount);     }     if (lCount > 1)         axMxDrawX1.DrawEntity(spDrawData); }


js代码实现如下:


//绘制自定义实体 function DyInsertCustomEntity() {     //清空当前显示内容     mxOcx.NewFile();     var getPt = mxOcx.NewComObject("IMxDrawUiPrPoint");     getPt.message = "点取第一点";     if (getPt.go() != 1)         return;     var frstPt = getPt.value();     if (frstPt == null)         return;     var getSecondPt = mxOcx.NewComObject("IMxDrawUiPrPoint");     getSecondPt.message = "点取第二点";     getSecondPt.basePoint = frstPt;     getSecondPt.setUseBasePt(true);     if (getSecondPt.go() != 1)         return;     var secondPt = getSecondPt.value();     if (secondPt == null)         return;     var ent = mxOcx.DrawCustomEntity("TestMxCustomEntity""");     ent.SetPoint("spt", frstPt);     ent.SetPoint("ept", secondPt); }


//绘制自定义实体1 function MyInsertCustomEntity() //清空当前显示内容     mxOcx.NewFile();     var spDrawData;     var getPt1 = mxOcx.NewComObject("IMxDrawUiPrPoint");     {         getPt1.message = "点取第一点";         spDrawData = getPt1.InitUserDraw("DynDrawEnt1");         if (getPt1.go() != 1) {             return;         }     }     var getPt2 = mxOcx.NewComObject("IMxDrawUiPrPoint");     {         getPt2.message = "点取第二点";         spDrawData = getPt2.InitUserDraw("DynDrawEnt2");         spDrawData.SetPoint("vFirst", getPt1.value());         if (getPt2.go() != 1) {             return;         }     }     var getPt3 = mxOcx.NewComObject("IMxDrawUiPrPoint");     {         getPt3.message = "点取第三点";         spDrawData = getPt3.InitUserDraw("DynDrawEnt3");         spDrawData.SetPoint("vFirst", getPt1.value());         spDrawData.SetPoint("vSecond", getPt2.value());         if (getPt3.go() != 1) {             return;         }     }     var getPt4 = mxOcx.NewComObject("IMxDrawUiPrPoint");     {         getPt4.message = "点取第四点";         spDrawData = getPt4.InitUserDraw("DynDrawEnt4");         spDrawData.SetPoint("vFirst", getPt1.value());         spDrawData.SetPoint("vSecond", getPt2.value());         spDrawData.SetPoint("vThird", getPt3.value());         if (getPt4.go() != 1) {             return;         }     }     {         spDrawData = mxOcx.DrawCustomEntity("DrawEnt""");         spDrawData.SetPoint("vFirst", getPt1.value());         spDrawData.SetPoint("vSecond", getPt2.value());         spDrawData.SetPoint("vThird", getPt3.value());         spDrawData.SetPoint("vFour", getPt4.value());     } }


二、响应自定义事件,绘制自定义实体


需要响应DMxDrawXEvents::CustomEntity_Explode事件。


下面例子,得到自实体的数据,C#代码实现如下:


private void axMxDrawX1_CustomEntity_Explode(object sender, AxMxDrawXLib._DMxDrawXEvents_CustomEntity_ExplodeEvent e)         {             MxDrawCustomEntity pCustomEntity = (MxDrawCustomEntity)e.pCustomEntity;             var sGuid = pCustomEntity.Guid;                MxDrawWorldDraw pWorldDraw = (MxDrawWorldDraw)e.pDraw;                if (sGuid == "DrawCustEntity")             {                 MyDrawMline(pWorldDraw, pCustomEntity, null);                 e.pRet = 1;             }         }    private void MyDrawMline(MxDrawWorldDraw pWorldDraw, MxDrawCustomEntity pCustomEntity, MxDrawPoint curPt) {     // 取自定义实体的端点数目,属性。     if (!pCustomEntity.IsHave("Count"))         return;     long lCount = pCustomEntity.GetLong("Count");     MxDrawPolyline tmpPl = new MxDrawPolyline();     for (long i = 0; i < lCount; i++)     {         String sName;         sName = "Point" + (i + 1).ToString();         if (!pCustomEntity.IsHave(sName))             break;            // 取自定义实体的端点坐标。         MxDrawPoint pt = pCustomEntity.GetPoint(sName);            // 把端点坐标,传给pl线,用于生成双线。         tmpPl.AddVertexAt(pt);     }     if (curPt != null)         tmpPl.AddVertexAt(curPt);        if (tmpPl.NumVerts < 2)     {         // 端点数少于2就,不构成直线,就不需要显示。         return;     }     // 求pl线,开始点的导数.     MxDrawVector3d vecFx;     if (!tmpPl.GetFirstDeriv(tmpPl.GetStartParam(), out vecFx))         return;     if (vecFx.IsZeroLength())         return;     // 把向量旋转90度.     vecFx.RotateByXyPlan(3.14159265 / 2.0);     vecFx.Normalize();     //  得到双线的宽度属性。     double dWidth = pCustomEntity.GetDouble("Width");     vecFx.Mult(dWidth);     MxDrawPoint startPt = tmpPl.GetStartPoint();        // 向pl线,两个方向偏移,     MxDrawPoint offsetPt1 = new MxDrawPoint();     offsetPt1.x = startPt.x;     offsetPt1.y = startPt.y;     offsetPt1.Add(vecFx);     MxDrawPoint offsetPt2 = new MxDrawPoint();     offsetPt2.x = startPt.x;     offsetPt2.y = startPt.y;     offsetPt2.Sum(vecFx);     MxDrawText text = new MxDrawText();     text.TextString = "Test";     text.Height = 100;     text.Position = startPt;     text.AlignmentPoint = startPt;     MxDrawPoint pt1, pt2;     text.GetBoundingBox(out pt1, out pt2);     MxDrawPoint pt3 = new MxDrawPoint();     pt3.x = pt1.x;     pt3.y = pt2.y;     MxDrawPoint pt4 = new MxDrawPoint();     pt4.x = pt2.x;     pt4.y = pt1.y;     MxDrawPoints pts = new MxDrawPoints();     pts.Add(pt1.x, pt1.y, 0);     pts.Add(pt3.x, pt3.y, 0);     pts.Add(pt2.x, pt2.y, 0);     pts.Add(pt4.x, pt4.y, 0);        Int32 lDraworder = pWorldDraw.Draworder;     pWorldDraw.Draworder = lDraworder + 1;     pWorldDraw.DrawWipeout(pts);     pWorldDraw.Draworder = lDraworder + 2;     pWorldDraw.DrawEntity((MxDrawEntity)text);     pWorldDraw.Draworder = lDraworder;     //    pWorldDraw->     {         MxDrawResbuf newobj;         if (tmpPl.OffsetCurves(dWidth, offsetPt1, out newobj))         {             for (Int32 j = 0; j < newobj.Count; j++)             {                 MxDrawEntity tmpObj = (MxDrawEntity)newobj.AtObject(j);                 if (tmpObj == null)                     continue;                    pWorldDraw.DrawEntity(tmpObj);             }             newobj.RemoveAll();         }     }     {         MxDrawResbuf newobj;         if (tmpPl.OffsetCurves(dWidth, offsetPt2, out newobj))         {             for (Int32 j = 0; j < newobj.Count; j++)             {                 MxDrawEntity tmpObj = (MxDrawEntity)newobj.AtObject(j);                 if (tmpObj == null)                     continue;                    pWorldDraw.DrawEntity(tmpObj);             }             // 这不使用newobj,需要显示调用RemoveAll函数清楚内存。             // 不然这个可能就会程序退出时才释放,这时它会去释放控件对象指针,有可能会出错。             newobj.RemoveAll();         }     } }


js代码实现如下:


// 自定义实体绘制函数 function ExplodeFun(pCustomEntity, pWorldDraw, txt) {     var sGuid = pCustomEntity.Guid;     if (sGuid == "TestMxCustomEntity") {         if (!pCustomEntity.IsHave("ept"))             return;         var stp = pCustomEntity.GetPoint("spt");         if (stp == null)             return;         var ept = pCustomEntity.GetPoint("ept");         if (ept == null)             return;         var mxUtility = mxOcx.NewUtility();         var vec = ept.SumVector(stp);         vec.Mult(0.5);         var midPt = mxOcx.NewPoint();         midPt.x = stp.x;         midPt.y = stp.y;         midPt.Add(vec);         var dAng = vec.Angle();         //计算一个标注角度,使用文字对象始终头朝上         dAng = mxUtility.GetDimAngle(dAng);         var dDis = 0.0;         dDis = stp.DistanceTo(ept);         var sTxt = "L=" + formatNumber(dDis, '#.##');         dAng = dAng * 180.0 / 3.14159265;         vec.RotateByXyPlan(3.14159265 / 2.0);         vec.Normalize();         vec.Mult(10);         stp.Add(vec);         ept.Add(vec);         pWorldDraw.DrawLine(stp.x, stp.y, ept.x, ept.y);         vec.Mult(2);         stp.Sum(vec);         ept.Sum(vec);         pWorldDraw.DrawLine(stp.x, stp.y, ept.x, ept.y);         pWorldDraw.SetColorIndex(1);         pWorldDraw.DrawText(midPt.x, midPt.y, sTxt, 5, dAng,             1, 2);         mxOcx.SetEventRet(1);       }            var dHeigth = mxOcx.ViewLongToDocCoord(5);           // 绘制绘制自定义实体1     if(sGuid == "DrawEnt"){         {             if (!pCustomEntity.IsHave("vFour"))                 return;               if (!pCustomEntity.IsHave("vThird"))                 return;               if (!pCustomEntity.IsHave("vSecond"))                 return;               if (!pCustomEntity.IsHave("vFirst"))                 return;         }         {             var vFourPt = pCustomEntity.GetPoint("vFour");             var dX = vFourPt.x;             var dY = vFourPt.y;               var vThirdPt = pCustomEntity.GetPoint("vThird");             pWorldDraw.DrawLine(vThirdPt.x, vThirdPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             var dX = vThirdPt.x;             var dY = vThirdPt.y;               var vSecondPt = pCustomEntity.GetPoint("vSecond");             pWorldDraw.DrawLine(vSecondPt.x, vSecondPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             dX = vSecondPt.x;             dY = vSecondPt.y;               var vFirstPt = pCustomEntity.GetPoint("vFirst");             pWorldDraw.DrawLine(vFirstPt.x, vFirstPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             dX = vFirstPt.x;             dY = vFirstPt.y;               pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);         }         mxOcx.SetEventRet(1);     }   }


三、响应自定义事件,动态绘制


C#代码实现如下:


private void axMxDrawX1_DynWorldDraw(object sender, AxMxDrawXLib._DMxDrawXEvents_DynWorldDrawEvent e) {     MxDrawCustomEntity pCustomEntity = (MxDrawCustomEntity)e.pData;     String sGuid = pCustomEntity.Guid;     e.pRet = 0;        MxDrawWorldDraw pWorldDraw = (MxDrawWorldDraw)e.pWorldDraw;     MxDrawPoint curPt = new MxDrawPoint();     curPt.x = e.dX;     curPt.y = e.dY;        if (sGuid == "DrawCustEntity")     {         MyDrawMline(pWorldDraw, pCustomEntity, curPt);     } }


js代码实现如下:


//动态施放绘制事件回调函数指针 //动态拖放时的绘制事件 //参数一为当前鼠标位置X坐标;参数为二当前鼠标位置Y坐标; // 参数三为IMxDrawWorldDraw对象,用于动态绘制;参数四为IMxDrawCustomEntity对象,动态绘制数据 function DoDynWorldDrawFun(dX,dY,pWorldDraw,pData) {     //自定义实体的GUID标识符     var sGuid = pData.Guid;     //设置自定义事件的返回值     mxOcx.SetEventRet(0);       var curPt = mxOcx.NewPoint();     curPt.x = dX;     curPt.y = dY;           var dHeigth = mxOcx.ViewLongToDocCoord(5);     //自定义实体的GUID标识符     switch (pData.Guid) {         case "DynDrawEnt4":         {             var vThirdPt = pData.GetPoint("vThird");             pWorldDraw.DrawLine(vThirdPt.x, vThirdPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             dX = vThirdPt.x;             dY = vThirdPt.y;         }         case "DynDrawEnt3":         {             var vSecondPt = pData.GetPoint("vSecond");             pWorldDraw.DrawLine(vSecondPt.x, vSecondPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             dX = vSecondPt.x;             dY = vSecondPt.y;         }         case "DynDrawEnt2":         {             var vFirstPt = pData.GetPoint("vFirst");             pWorldDraw.DrawLine(vFirstPt.x, vFirstPt.y, dX, dY);             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);             dX = vFirstPt.x;             dY = vFirstPt.y;         }         case "DynDrawEnt1":         {             pWorldDraw.DrawText(dX, dY, "(" + dX.toFixed(1) + "," + dY.toFixed(1) + ")", dHeigth, 0, 1, 1);         }     }     //设置自定义事件的返回值     mxOcx.SetEventRet(0);     }


四、响应自定义事件,返回自定义实体夹点


需要响应_DMxDrawXEvents::CustomEntity_getGripPoints事件,C#代码实现如下:


private void axMxDrawX1_CustomEntity_getGripPoints(object sender, AxMxDrawXLib._DMxDrawXEvents_CustomEntity_getGripPointsEvent e) {     MxDrawCustomEntity pCustomEntity = (MxDrawCustomEntity)e.pCustomEntity;     var sGuid = pCustomEntity.Guid;     e.pOk = 0;     if (sGuid == "DrawCustEntity")     {         if (!pCustomEntity.IsHave("Count"))             return;            long lCount = pCustomEntity.GetLong("Count");            MxDrawResbuf ret = (MxDrawResbuf)axMxDrawX1.NewResbuf();            for (long i = 0; i < lCount; i++)         {             String sName;             sName = "Point" + (i + 1).ToString();             if (!pCustomEntity.IsHave(sName))                 break;                // 取自定义实体的端点坐标。             MxDrawPoint pt = pCustomEntity.GetPoint(sName);                   ret.AddPoint(pt);         }         e.pOk = 1;         axMxDrawX1.SetEventRetEx(ret);     }    }


js代码实现如下:


// 返回自定义实体夹点 function GetGripPointsFun(pCustomEntity) {     var sGuid = pCustomEntity.Guid;           //自定义实体绘制两条直线     if (sGuid == "TestMxCustomEntity") {         if (!pCustomEntity.IsHave("ept"))             return;           var stp = pCustomEntity.GetPoint("spt");         if (stp == null)             return;           var ept = pCustomEntity.GetPoint("ept");         if (ept == null)             return;           var ret = mxOcx.NewResbuf();           ret.AddPoint(stp);         ret.AddPoint(ept);           mxOcx.SetEventRetEx(ret);     }           //自定义实体1     if (sGuid == "DrawEnt") {         if (!pCustomEntity.IsHave("vFour"))             return;         var stp = pCustomEntity.GetPoint("vFirst");         if (stp == null)             return;         var ept = pCustomEntity.GetPoint("vSecond");         if (ept == null)             return;         var tpt = pCustomEntity.GetPoint("vThird");         if (tpt == null)             return;         var fpt = pCustomEntity.GetPoint("vFour");         if (fpt == null)             return;         var ret = mxOcx.NewResbuf();         ret.AddPoint(stp);         ret.AddPoint(ept);         ret.AddPoint(tpt);         ret.AddPoint(fpt);         mxOcx.SetEventRetEx(ret);     } }


五、响应自定义事件,夹点移动后的处理


需要响应CustomEntity_moveGripPointsAt事件。


下面例子,夹点移动后,修改自定义实体的属性,C#代码实现如下:


private void axMxDrawX1_CustomEntity_moveGripPointsAt(object sender, AxMxDrawXLib._DMxDrawXEvents_CustomEntity_moveGripPointsAtEvent e) {     e.pRet = 1;     MxDrawCustomEntity pCustomEntity = (MxDrawCustomEntity)e.pCustomEntity;     var sGuid = pCustomEntity.Guid;        if (sGuid == "DrawCustEntity")     {         if (!pCustomEntity.IsHave("Count"))             return;            long lCount = pCustomEntity.GetLong("Count");                           for (long i = 0; i < lCount; i++)         {             String sName;             sName = "Point" + (i + 1).ToString();             if (!pCustomEntity.IsHave(sName))                 break;                // 取自定义实体的端点坐标。             MxDrawPoint pt = pCustomEntity.GetPoint(sName);                if (i == e.lGridIndex)             {                 pt.x = pt.x + e.dOffsetX;                 pt.y = pt.y + e.dOffsetY;                    pCustomEntity.SetPoint(sName, pt);             }         }     } }


js代码实现如下:


// 移动自定义实体夹点 function MoveGripPointsFun(pCustomEntity, lGridIndex, dOffsetX, dOffsetY) {       var sGuid = pCustomEntity.Guid;          if (sGuid == "TestMxCustomEntity") {         if (!pCustomEntity.IsHave("ept"))             return;           var stp = pCustomEntity.GetPoint("spt");         if (stp == null)             return;           var ept = pCustomEntity.GetPoint("ept");         if (ept == null)             return;             if (lGridIndex == 0) {             stp.x = stp.x + dOffsetX;             stp.y = stp.y + dOffsetY;             pCustomEntity.SetPoint("spt", stp);         }         else {             ept.x = ept.x + dOffsetX;             ept.y = ept.y + dOffsetY;             pCustomEntity.SetPoint("ept", ept);         }           mxOcx.SetEventRet(1);     }     if (sGuid == "DrawEnt") {         if (!pCustomEntity.IsHave("vFour"))             return;         var stp = pCustomEntity.GetPoint("vFirst");         if (stp == null)             return;         var ept = pCustomEntity.GetPoint("vSecond");         if (ept == null)             return;         var tpt = pCustomEntity.GetPoint("vThird");         if (tpt == null)             return;         var fpt = pCustomEntity.GetPoint("vFour");         if (fpt == null)             return;         {             stp.x = stp.x + dOffsetX;             stp.y = stp.y + dOffsetY;             pCustomEntity.SetPoint("vFirst", stp);             ept.x = ept.x + dOffsetX;             ept.y = ept.y + dOffsetY;             pCustomEntity.SetPoint("vSecond", ept);             tpt.x = tpt.x + dOffsetX;             tpt.y = tpt.y + dOffsetY;             pCustomEntity.SetPoint("vThird", tpt);             fpt.x = fpt.x + dOffsetX;             fpt.y = fpt.y + dOffsetY;             pCustomEntity.SetPoint("vFour", fpt);         }         mxOcx.SetEventRet(1);     } }


六、自定义实体之打碎


c#代码实现如下


            // 打开图纸文件。                         axMxDrawX1.OpenDwgFile("C:\西桥头村.dwg");                 // 打碎图纸上的自定义实体。             MxDrawResbuf filter = new MxDrawResbuf();                         // 设置选择过滤条件,只选择自定义实体。                         filter.AddStringEx("ACAD_PROXY_ENTITY", 5020);             MxDrawSelectionSet ss = new MxDrawSelectionSet();                         // 得到所有自定义实体。                         ss.AllSelect(filter);                         // 遍历自定义实体             for (Int32 i = 0; i < ss.Count; i++)             {                 MxDrawEntity ent = ss.Item(i);                 MxDrawResbuf param = new MxDrawResbuf();                 param.AddObjectId(ent.ObjectID);                                 // 打碎自定义实体。                                 MxDrawResbuf ret = (MxDrawResbuf)axMxDrawX1.CallEx("Mx_Explode", param);                                 // 删除自定义实体。                 if(ret.AtString(0) == "Ok")                     ent.Erase();             }                         // 把图纸所有内容都放到当前视区。             axMxDrawX1.ZoomAll();


七、在块表记录中添加一个自定义实体


c#代码实现如下


        MxDrawDatabase database = (MxDrawDatabase)axMxDrawX1.GetDatabase();         MxDrawBlockTableRecord blkRec = database.CurrentSpace();                 // 调用AddCustomEntity函数绘制自定义实体。 逗号后的字符串"DrawCustEntity"是自定义实体的GUID         MxDrawResbuf ret =  blkRec.GetProp("AddCustomEntity,DrawCustEntity");                 // 得到自定义实体。                 MxDrawCustomEntity ent = (MxDrawCustomEntity)database.ObjectIdToObject(ret.AtObjectId(0));                 // 设置自定义实体的属性。                 ent.BeginSetValue();         ent.SetDouble("Width", 30);           MxDrawPoint pt1 = new MxDrawPoint();         pt1.x = 10;         pt1.y = 10;         MxDrawPoint pt2 = new MxDrawPoint();           pt2.x = 20;         pt2.y = 20;         ent.SetPoint("Point1", pt1);         ent.SetPoint("Point2", pt2);           ent.SetLong("Count", 2);         ent.EntSetValue();
上一篇:CAD交互绘制矩形批注(网页版)


下一篇:Grafana+Telegraf+Influxdb监控Tomcat集群方案