返回介绍

实体

发布于 2023-08-09 23:10:34 字数 18451 浏览 0 评论 0 收藏 0

图纸所有对象都是从类MxDrawMcDbObject 继承,该 类的详细参考:http://www.mxdraw.com/help/IMxDrawMcDbObject.htm,该类提供得到对象句柄,ID,对象类型信息等函数。

图上可见的对象是从类MxDrawEntity 继承,该 类的详细参考:http://www.mxdraw.com/help/IMxDrawEntity.htm,该类提供可见实体的通用属性操作,如线型,图层,文字样式,颜色等函数。

它们在类继承图中位置如下:

class.png

类继承关系详细 PDF格式图:https://mxtmpweb.mxdraw.f3322.net:3562/class.pdf

A. 实体ID和句柄

ID和句柄都用来标识一个对象,ID是一个64位长整型变量,是一个内存地址,访问速度最快,但它每次打开都不一样,如果需要把一个对象的标识存起来,下次又能找到对象,就需要使用句柄,句柄是一个字符串变量,它保证不管什么时候总是不会变化,句柄在DWG图纸中是唯一存在,ID是内存中唯一存在。

如下代码,得到id,句柄,如下:

    MxDrawModifyTheColor changeColor = new MxDrawModifyTheColor();
    MxDrawApplication app = new MxDrawApplication();
    changeColor.Do(app.WorkingDatabase(), 0x010101);

在修改颜色后调用Restore 恢复对象颜色。

修改显示顺序

在用户绘图时,在默认情况下,重叠对象(例如文字、宽多段线和实体填充多边形)通常按其创建次序显示:新创建的对象显示在现有对象前面。本实例演示了如何控制显示顺序,具体实现c#代码如下:

private void MxOrder()
{
    MxDrawDatabase database = (MxDrawDatabase)axMxDrawX1.GetDatabase();
    
    // 得到当前图上,最小的显示顺序
    MxDrawResbuf ret = database.GetProp("getMinDrawOrder");
    int lMin = ret.AtLong(0);
 
       // 得到当前图上,最大的显示顺序
    MxDrawResbuf ret2 = database.GetProp("getMaxDrawOrder");
    int lMax = ret2.AtLong(0);
 
       // 绘一个图片对象,得到它的id.
    long sTemp = axMxDrawX1.DrawImage(0, 0, 0, 0, "D:\\mxcad.jpg");
    
    // 根据id得到图片对象.
    MxDrawMcDbObject ent = database.ObjectIdToObject(sTemp);
 
       // 准备调用参数。
    MxDrawResbuf param = new MxDrawResbuf();
    param.AddLong(lMin + 2);
 
       // 设置显示顺序
    ent.SetProp("drawOrder", param);
    
    // 把图上所有图形,放到当前显示范围内。
    axMxDrawX1.ZoomAll();
}

由上述设置的c#代码可以将我们插入的图片显示到最开始绘制的两个实体之上,之后绘制的实体之下。效果如下图所示:

upordown.png

E. 扩展数据

用户可给图纸上的对象设置扩展数据,这些扩展数据可以是用户实际需求的专业数据,扩展数据支持字符串,double,int,等类型。每个扩展数据都一个扩展数据名称,每个名称下也可能有多个扩展数据,一个实体可以有多个扩展数据名称,这些扩展数据在内存中是一个链表来存放的,每个链结代表一个数据,每个链结中字符串数据长度不超过200(DWG图纸格式确定了),链表类MxDrawResbuf详细说明参考:

http://www.mxdraw.com/help/IMxDrawResbuf.htm

关于扩展数据的详细教程:

http://www.mxdraw.com/help_4_95.html

F. 编辑实体

我们提供了,复制,移动,缩放,变换,镜向等编辑实体函数,详细如下图:

edit.png

下面C#代码,把实体从一个点,移到另一个点.

          // 创建一个工具对象。
            MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 移动实体
            // 移动基点 
            MxDrawPoint ptBase = new MxDrawPoint();
            ptBase.x = 0;
            ptBase.y = 0;
            // 移动到点.
            MxDrawPoint ptMoveTo = new MxDrawPoint();
            ptMoveTo.x = 100;
            ptMoveTo.y = 100;
            ent.Move(ptBase, ptMoveTo);

调用TransformBy函数,可以构建一个坐标变换矩阵,然后对实体进行变换。

下面C#代码,选对实体进行缩放,然后再移动:

                  // 创建一个工具对象。
            MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 创建一个移动矩阵
            MxDrawMatrix3d movdMat = new MxDrawMatrix3d();
            
            // 移动向量。,100,100相当于向右,向上移动100.
            MxDrawVector3d offset = new MxDrawVector3d();
            offset.x = 100;
            offset.y = 100;
            // 设置移动矩阵.
            movdMat.Translation(offset);
            // 创建一个缩放矩阵.
            MxDrawMatrix3d scale = new MxDrawMatrix3d();
            // 设置缩放基点是0,0.
            MxDrawPoint scaleBasePoint = new MxDrawPoint();
            scaleBasePoint.x = 0;
            scaleBasePoint.y = 0;
            // 设置缩放比例为 2.
            scale.Scaling(2, scaleBasePoint);
            // 把两矩阵相乘.PostMultBy是右乘。 
            // movdMat = movdMat * scale;
            // 控件的矩阵坐标变换是从表达式的右往左变换
            // 所以下面这句的意思,先进行缩放,然后再进行移动变换。
            movdMat.PostMultBy(scale);
            // 变换实体.
            ent.TransformBy(movdMat);

G. 删除实体

删除实体,直接调用控件Erase函数删除,该函数传一个实体id.

比如 :

axMxDrawX1.Erase(lId);

或都调用对象的删除函数也行,比如:

     // 创建一个工具对象。
            MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 删除对象。
            ent.Erase();

H. 扩展记录

在CAD中,对象上面不但可以存放扩展数据,还可以存放扩展记录,在对象上可创建一个字典(这个字典和前面说到的全局字典类似),字典中存放扩展记录,这样可以存放更多的数据,调用GetExtensionDictionary函数得到字典。

下面C#代码演示如何读取对象扩展记录:

                  MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 得到实体扩展字典
            MxDrawDictionary dict = ent.GetExtensionDictionary();
            if (dict == null)
                return;
            // 得到字典下自己写数据的字典
            MxDrawDictionary myDict = (MxDrawDictionary)dict.GetAt("MyDict");
            if (myDict == null)
            {
                return;
            }
            // 得到字典内扩展记录.
            MxDrawXRecord rec = (MxDrawXRecord)myDict.GetAt("MyGlobalData");
            if (rec == null)
            {
                return;
            }
            // 输出扩展记录中的数据.
            MxDrawResbuf data = rec.GetXRecordData();
            data.PrintData();

下面C#代码演示如何写入扩展记录:

                  MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 写扩展字典
            MxDrawResbuf param = new MxDrawResbuf();
            //创建扩展字典,如果对象已经有扩展字典,该函数什么都不做。
            ent.SetProp("createExtensionDictionary", param);
            // 得到扩展字典
            MxDrawDictionary dict = ent.GetExtensionDictionary();
            if (dict == null)
                return;
            // 向扩展字典中增加一个自己的字典,用于写自己的数据.
            MxDrawDictionary myDict = (MxDrawDictionary)dict.AddObject("MyDict", "McDbDictionary");
            // 向字典中增加一个扩展记录。
            MxDrawXRecord xRecord = (MxDrawXRecord)myDict.AddXRecord("MyGlobalData");
            if (xRecord == null)
                return;
            // 做准备写入的扩展记录数据.
            MxDrawResbuf xData2 = new MxDrawResbuf();
            xData2.AddLong(99999);
            xData2.AddDouble(666);
            MxDrawPoint ptTest = new MxDrawPoint();
            ptTest.x = 77;
            ptTest.y = -100;
            xData2.AddPoint(ptTest);
            xData2.AddString("TestApp2");
            // 写入数据.
            xRecord.SetXRecordData(xData2);

I. 得到实体的坐标

不同的实体它的坐标属性不一样,比如直线就是开始点,和结束点属性,圆的就是中心点坐标和半径属性。所以要得实体的坐标,需要判断对象类型,然后再转换成具体的对象,再读取它的坐标。

控件提供的计算对象最小外包的函数:GetBoundingBox,详见: http://www.mxdraw.com/help/IMxDrawEntity__GetBoundingBox@[out]_IMxDrawPoint__@[out]_IMxDrawPoint__.htm

下面C#代码,得到对象最小外包矩形框坐标:

            MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体:");
            if (ent == null)
                return;
            MxDrawPoint pt1Ob, pt2Ob;
            // 得到最小外包。
            ent.GetBoundingBox(out pt1Ob,out pt2Ob);
            ent.Close();
            MxDrawPoint pt1 = (MxDrawPoint)pt1Ob;
            MxDrawPoint pt2 = (MxDrawPoint)pt2Ob;
            if(pt1 != null && pt2 != null)
            {
                // 成功得到。
                MxDrawApplication app = new MxDrawApplication();
                app.ZoomWindow(pt1.x,pt1.y, pt2.x,pt2.y);
            }

J. 实体的选择

调用控件的AddCurrentSelect函数,把实体设置成选中状,函数详见:

http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__AddCurrentSelect@LONGLONG@VARIANT_BOOL@VARIANT_BOOL.htm

调用控件的ClearCurrentSelect函数清除当前选择

调用IMxDrawSelectionSet::CurrentSelect 得到当前选择的实体,详见:

http://www.mxdraw.com/help/IMxDrawSelectionSet__CurrentSelect@[in,defaultvalueNULL]_IMxDrawResbuf_.htm

下面代码,得到当前选择的实体:

                  MxDrawSelectionSet ss = new MxDrawSelectionSet();
            MxDrawResbuf  filter = new MxDrawResbuf();
            ss.CurrentSelect(filter);
            int i = 0;
            for (; i < ss.Count; i++)
            {
                MxDrawEntity ent = ss.Item(i);
                if (ent.ObjectName == "McDbLine")
                {
                    // 是个直线。
                    MxDrawLine line = (MxDrawLine)ent;
                    MxDrawPoint spt = line.StartPoint;
                    MxDrawPoint ept = line.EndPoint;
                   
                }
                else if (ent.ObjectName == "McDbPolyline")
                {
                    // 是个多义线.
                    MxDrawPolyline pl = (MxDrawPolyline)ent;
                    int j = 0;
                    // 循环,得到端点坐标
                    for (j = 0; j < pl.NumVerts; j++)
                    {
                        MxDrawPoint pt = pl.GetPointAt(j);
                        
                    }
                }
            }

响应控件的SelectModified事件,实时得到被选择的实体,详细接口见:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawXEvents__SelectModified@IDispatch_@IDispatch_@VARIANT_BOOL.htm

K. 闪烁实体

我们控件可以对实体进行一个动画的闪烁,这样可以更方便提示用户。

调用控件函数:TwinkeEnt,StopTwinkeEnt,StopAllTwinkeEnt,SetTwinkeTime,SetTwinkeColor ,实现实体的闪烁控制。

如下代码,让用户在图上选择一个对象,然后闪烁

           MxDrawUtility mxUtility = new MxDrawUtility();
            MxDrawPoint getPt;
            // 让用户在图上选择一个对象。
            MxDrawEntity ent = mxUtility.GetEntity(out getPt, "选择实体");
            if (ent == null)
                return;
            // 准备闪烁颜色.
            MxDrawResbuf colors = new MxDrawResbuf();
            colors.AddLong(255);
            colors.AddLong(65280);
            axMxDrawX1.SetTwinkeColor(colors);
            // 设置闪烁间隔的时间
            axMxDrawX1.SetTwinkeTime(2000);
            // 开始闪烁
            axMxDrawX1.TwinkeEnt(ent.ObjectID);

控件DrawImageMark函数,在图上绘制一个图片标记,该标记可以是一组的图片组成,如果闪烁这样的图片标记对象,就可以做出一个图片动画效果。

例如下:

         // 创建一个取点对象.
            MxDrawUiPrPoint getPt =new MxDrawUiPrPoint();
            getPt.message = "点取图片的插入中点";
            if (getPt.go() != MCAD_McUiPrStatus.mcOk)
            {
                return;
            }
            // 得到在图上点取的点.
            MxDrawPoint frstPt = getPt.value();
            if (frstPt == null)
            {
                return;
            }
            // 准备一组闪烁的图片.
            String sImageFile1 = axMxDrawX1.GetOcxAppPath() + "\\1.png";
            String sImageFile2 = axMxDrawX1.GetOcxAppPath() + "\\2.png";
            String sImageFile3 = axMxDrawX1.GetOcxAppPath() + "\\3.png";
         
            // 绘制一个图片标记对象。
            Int64 lId = axMxDrawX1.DrawImageMark(frstPt.x, frstPt.y, -20, 0, sImageFile1,
                sImageFile1 + "," + sImageFile2 + "," + sImageFile3, true);
            // 开始闪烁实体,运行动画。
            axMxDrawX1.TwinkeEnt(lId);

L. 得到鼠标左键点击下的实体

可以响应控件的鼠标左键按下事件,然后用我们FindEntAtPoint,或MxDrawSelectionSet::SelectAtPoint函数,得到鼠标坐标下面的实体。

例如

         private void axMxDrawX1_MouseEvent(object sender,                AxMxDrawXLib._DMxDrawXEvents_MouseEventEvent e)
        {
            //"lType 是事件类型,1鼠标移动,2是鼠标左键按下,3是鼠标右键按下,4是鼠标左键双击.lRet 返回非0,消息将不在往下传递"
            if(e.lType == 4)
            {
                // 判断当前是否正在运行选择命令。
                MxDrawResbuf ret = (MxDrawResbuf)axMxDrawX1.Call("Mx_IsRuningCommand", "");
                if ((ret.AtString(0) == "Ok")
                    && ret.AtString(1) != "intellisel"
                    )
                    return;
                
                // 鼠标左键双击.
                // 构建选择集,找到鼠标左建双击下的实体。
                MxDrawSelectionSet ss = new MxDrawSelectionSet();
                MxDrawResbuf filter = new MxDrawResbuf();
                //filter.AddString("LINE",5020);
                MxDrawPoint point = new MxDrawPoint();
                point.x = e.dX;
                point.y = e.dY;
                // 得到点击对象。
                ss.SelectAtPoint(point,filter);
                if(ss.Count > 0)
                {
                    MxDrawEntity ent = ss.Item(0);
                    MessageBox.Show("点击了" + ent.ObjectName + "对象");
                    /*
                    if (ent is MxDrawLine)
                    {
                        MxDrawLine line = (MxDrawLine)ent;
                    }
                     */
                }
               
                e.lRet = 1;
                // 取消后面的命令,不让鼠标事件再往下传递.
                axMxDrawX1.SendStringToExecute("");
            }
            else    if(e.lType == 3)
            {
               // MessageBox.Show("右键按下");
            }
        }

M. 动态提示

鼠标移动到实体上后,停留一会,控件可能得到该实体对象,然后能动态提示一些信息。响应控件事件: DMxDrawXEvents::InputPointToolTipEvent,详细说明参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawXEvents__InputPointToolTipEvent@IDispatch_@BSTR_.htm,调用函数SetDynToolTipPopTime设置动态提示时间。

在C#中,如下图,增加对该事件的响应 ,

t1.png

在事件代码里,把对象类型名提示出来

        private void axMxDrawX1_InputPointToolTipEvent(object sender, AxMxDrawXLib._DMxDrawXEvents_InputPointToolTipEventEvent e)
        {
            MxDrawDatabase databse = (MxDrawDatabase)(axMxDrawX1.GetDatabase() );
// 得到鼠标下面的对象
            MxDrawMcDbObject obj = (MxDrawMcDbObject)e.pEntity;
            if(obj != null)
            {
   // 返回提示信息
                e.pToolTip = obj.ObjectName;
            }
          
        }

动态提示效果如下:

t2.png

N.其它

调用控件PutEntityInView函数,可以把实体放到视区中间,详细说明参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__PutEntityInView@LONGLONG@DOUBLE.htm

调用控件 DrawEntityToJpg函数,可以把实体显示输出到一个jpg文件,详细说明参考:

http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__DrawEntityToJpg@LONGLONG@BSTR@LONG@LONG@LONG.htm

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文