返回介绍

实体

发布于 2023-08-09 23:10:34 字数 16691 浏览 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,句柄,如下:

    var changeColor = mxOcx.NewComObject("IMxDrawModifyTheColor");
    changeColor.Do(mxOcx.GetDatabase(), 0x010101);

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

D. 修改显示顺序

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

function MxOrder() {

    var database = mxOcx.GetDatabase();
    var ret = database.GetProp("getMinDrawOrder");
    var lMin = ret.AtLong(0);

    var ret2 = database.GetProp("getMaxDrawOrder");
    var lMax = ret2.AtLong(0);

    var sTemp = mxOcx.DrawImage(0, 0, 0, 0, "D:\\mxcad.jpg");
    var ent = database.ObjectIdToObject(sTemp);

    var res = mxOcx.NewResbuf();
    res.AddLong(lMin + 2);

    ent.SetProp("drawOrder", res);
    mxOcx.ZoomAll();
}

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

ceng.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

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

            // 让用户在图上选择一个对象。
            var ent = mxOcx.GetEntity("选择实体");
            if (ent == null)
                return;
            // 移动实体
            // 移动基点
            var ptBase = mxOcx.NewPoint();
            ptBase.x = 0;
            ptBase.y = 0;
            // 移动到点.
            var ptMoveTo = mxOcx.NewPoint();
            ptMoveTo.x = 100;
            ptMoveTo.y = 100;
            ent.Move(ptBase, ptMoveTo);

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

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

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

G. 删除实体

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

比如 :

mxOcx.Erase(lId);

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

            // 让用户在图上选择一个对象。            
            var ent = mxOcx.GetEntity("选择实体");
            if (ent == null)
                return;
            // 删除对象。
            ent.Erase();

H. 扩展记录

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

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

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

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

        // 让用户在图上选择一个对象。        
        var ent = mxOcx.GetEntity("选择实体");
        if (ent == null)
            return;
        // 写扩展字典
        var param = mxOcx.NewResbuf();
        //创建扩展字典,如果对象已经有扩展字典,该函数什么都不做。
        ent.SetProp("createExtensionDictionary", param);
        // 得到扩展字典
        var dict = ent.GetExtensionDictionary();
        if (dict == null)
            return;
        // 向扩展字典中增加一个自己的字典,用于写自己的数据.
        var myDict = dict.AddObject("MyDict", "McDbDictionary");
        // 向字典中增加一个扩展记录。
        var xRecord = myDict.AddXRecord("MyGlobalData");
        if (xRecord == null)
            return;
        // 做准备写入的扩展记录数据.
        var xData2 = mxOcx.NewResbuf();
        xData2.AddLong(99999);
        xData2.AddDouble(666);
        var ptTest = mxOcx.NewPoint();
        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

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

            var  ent = mxOcx.GetEntity("选择实体");
            if (ent == null)
                return;
            var pt1Ob = mxOcx.NewPoint();
            var  pt2Ob = mxOcx.NewPoint();
            // 得到最小外包。
            var  points = ent.GetBoundingBox2();
            ent.Close();
            var pt1Ob = points.Item(0);
            var pt2Ob = points.Item(1);
            if(pt1Ob != null && pt2Ob != null)
            {
                // 成功得到。
                var app = mxOcx.NewComObject("IMxDrawApplication");
                app.ZoomWindow(pt1Ob.x,pt1Ob.y, pt2Ob.x,pt2Ob.y);
            
                alert(pt1Ob.x);
                alert(pt1Ob.y);
                alert(pt2Ob.x);
                alert(pt2Ob.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

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

        //实例化一个构造选择集进行过滤,该类封装了选择集及其处理函数。        
        var  ss = mxOcx.NewSelectionSet();
        //构造一个过滤链表
        var filter = mxOcx.NewResbuf();
        ss.CurrentSelect(filter);
        
        for (var i = 0; i < ss.Count; i++)
        {
            var ent = ss.Item(i);
            if (ent.ObjectName == "McDbLine")
            {
                // 是个直线。
                var line = ent;
                var spt = line.StartPoint;
                alert(spt.x);
                alert(spt.y);
                var ept = line.EndPoint;
                alert(ept.x);
                alert(ept.y);
        
            }
            else if (ent.ObjectName == "McDbPolyline")
            {
                // 是个多义线.
                var pl = ent;
                var j = 0;
                // 循环,得到端点坐标
                for (j = 0; j < pl.NumVerts; j++)
                {
                    var pt = pl.GetPointAt(j);
                    alert(pt.x);
                    alert(pt.y);
        
                }
            }
        }

K. 闪烁实体

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

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

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

            // 让用户在图上选择一个对象。            
            var ent = mxOcx.GetEntity("选择实体");
            if (ent == null)
                return;
            // 准备闪烁颜色.
            var colors =  mxOcx.NewResbuf();
            colors.AddLongEx(255);
            colors.AddLongEx(65280);
            mxOcx.SetTwinkeColor(colors);
            // 设置闪烁间隔的时间
            mxOcx.SetTwinkeTime(2000);
            // 开始闪烁
            mxOcx.TwinkeEnt(ent.ObjectID);

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

例如下:

        //新建一个COM组件对象 参数为COM组件类名
        var getPt = mxOcx.NewComObject("IMxDrawUiPrPoint");
        getPt.message = "点取图片的插入中点";
        if (getPt.go() != 1) {
            return;
        }
        var frstPt = getPt.value();
        if (frstPt == null) {
            return;
        }
        //控件程序在磁盘的文件路径
        var sImageFile1 = mxOcx.GetOcxAppPath() + "\\1.png";
        var sImageFile2 = mxOcx.GetOcxAppPath() + "\\2.png";
        var sImageFile3 = mxOcx.GetOcxAppPath() + "\\3.png";
        // 绘图制一个图象标记对象
        //参数一为绘制位置,是图片的中心点X ;参数二为绘制位置,是图片的中心点Y;参数三为缩放比例;参数四为旋转角度;
        //参数五为图片显示文件名;参数六为闪烁文件设置;参数七为图片数据是否随图保存
        var lId = mxOcx.DrawImageMark(frstPt.x, frstPt.y, -20, 0, sImageFile1,
            sImageFile1 + "," + sImageFile2 + "," + sImageFile3, true);
        //闪烁实体
        //参数一为被闪烁的实体对象id;参数二为闪烁次数,默认为-1表示不限闪烁次数,成功返回true
        mxOcx.TwinkeEnt(lId);

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

增加ImplementMouseEventFun事件响应函数:

document.getElementById("MxDrawXCtrl").ImplementMouseEventFun = MouseEvent;

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

例如

        // 控件鼠标事件        
        function MouseEvent(dX, dY, lType) {
        
            //"lType 是事件类型,1鼠标移动,2是鼠标左键按下,3是鼠标右键按下,4是鼠标左键双击.lRet 返回非0,消息将不在往下传递"
            if(lType == 4)
            {
                // 判断当前是否正在运行选择命令。
                var ret = mxOcx.Call("Mx_IsRuningCommand", "");
                if ((ret.AtString(0) == "Ok")
                    && ret.AtString(1) != "intellisel"
                )
                    return;
        
                // 鼠标左键双击.
                // 构建选择集,找到鼠标左建双击下的实体。
                var ss =  mxOcx.NewSelectionSet();
                var filter = mxOcx.NewResbuf();
                //filter.AddString("LINE",5020);
                var point = mxOcx.NewPoint();
                point.x = dX;
                point.y = dY;
                // 得到点击对象。
                ss.SelectAtPoint(point,filter);
                if(ss.Count > 0)
                {
                    var ent = ss.Item(0);
                    alert("点击了" + ent.ObjectName + "对象");
        
                }
        
                // 取消后面的命令,不让鼠标事件再往下传递.
                mxOcx.SendStringToExecute("");
                return 1;
        
                
            }
            else    if(lType == 3)
            {
                // MessageBox.Show("右键按下");
            }
        }

M. 动态提示

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

1. 增加InputPointToolTipEvent事件响应函数:

document.getElementById("MxDrawXCtrl").ImpInputPointToolTipFun = DoInputPointToolTipFun;

2. 在事件中返回需要提示的字符串,在事件代码里,把对象类型名提示出来:

function DoInputPointToolTipFun(ent) {

    {
        var sClassName = ent.ObjectName;

        var tip = "<b><ct=0x0000FF><al_c>"+sClassName+
            "</b><br><ct=0x00AA00><hr=100%></ct><br>";

        mxOcx.SetEventRetString(tip);
    }
    ent = null;
    CollectGarbage();
}

动态提示效果如下:

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 和您的相关数据。
    原文