LOGO
帮助文档
旧版文档
简介图层操作文字样式标注样式全局字典块表线型实体打开保存图纸比较
简介

在此示例将演示如何获取CAD控件图纸上一些常用信息,如符号表(块表、层表、文字样式表、线型表、点样式表)、字典。点击此处在线演示


下面将介绍如何获取符号表的一些信息,如下图所示:


15123534486359648.png

图层操作

DWG数据库中,图层存放在图层层表中,层表类名:MxDrawLayerTable,它的详细接口说明参考:http://www.mxdraw.com/help/frames.htm?frmname=topic&frmfile=IMxDrawLayerTable.htm


层表中每一条记录称为层表记录,类名:MxDrawLayerTableRecord,它的详细接口说明参数:http://www.mxdraw.com/help/frames.htm?frmname=topic&frmfile=IMxDrawLayerTableRecord.htm


每一个层,有颜色,线型,关闭/打开,冻结等属性,DWG数据库默认总是有一个"0"层,该层不能被删除。


图层操作在线演示例子:点击此处在线演示


视频演示:



A. 当前层


当前层表示DWG数据库默认层,向数据库中添加一个对象时,默认放到该层上,该属性随图存放,通过系统变量CLAYER操作,系统变量设置参考:http://www.mxdraw.com/help_2_48.html


设置当前层代码JS:


    // 新建一个图层
    mxOcx.AddLayer("MyLayerName");
    // 设置当前层
    mxOcx.SetSysVarString("CLAYER", "MyLayerName");
    // 设置控件Draw函数使得的层
    mxOcx.LayerName = "MyLayerName";


或者这样:


     // 添加层
     mxOcx.AddLayer("aaaa");
     // 得到当前数据库
     var database = mxOcx.GetDatabase();
     // 设置当前层
     database.CurrentlyLayerName = "aaaa";


B.添加图层


调用控件AddLayer方法添加图层,详细接口说明见:http://www.mxdraw.com/help/frames.htm?frmname=topic&frmfile=MxDrawXLib___DMxDrawX__AddLayer@BSTR.htm


例如JS代码:


            // 新建一个图层
            mxOcx.AddLayer("MyLayerName");
            // 设置控件Draw函数使得的层
            mxOcx.LayerName = "MyLayerName";


或使用层表Add方法来添加一个图层


        // sNewLayerName新创建的图层名        
        var sNewLayerName = "TestNewLayer";
        
        //返回控件的数据库对象
        var database = mxOcx.GetDatabase();
        
        var layerTable = database.GetLayerTable();
        // 向层表中新增一个层表记录
        var layerTableRec = layerTable.Add(sNewLayerName);
        // 设置新图层的颜色。SetRGB
        var color = layerTableRec.Color;
        color.SetRGB(255, 0, 0);
        layerTableRec.Color = color;
        // 把新建的层设置成当前层
        database.CurrentlyLayerName = sNewLayerName;


C.遍历所有图层


下面代码是遍历层表中所有层表记录,并得到所有图层名,在遍历的循环中,得到每个层表记录对象,可以去修改它的属性


function GetAllLayer() {
    var database = mxOcx.GetDatabase();
    // 得到所有图层名
    var sRet = null;
    //返回数据库中的层表对象
    var spLayerTable = database.GetLayerTable();
    //创建一个遍历层表中所有图层的遍历器
    var spIter = spLayerTable.NewIterator();
    //移动当前遍历器位置
    for(;!spIter.Done();spIter.Step(true,true))
    {
        //返回遍历器当前位置的记录
        var spLayerRec = spIter.GetRecord();
        //符号表记录名属性
        var sName = spLayerRec.Name;
        // 0零层不参加比较
        if(sName != "0")
        {
            if(sRet == null)
                sRet = sName;
            else
            {
                sRet = sRet +","+sName;
            }
        }
    }
    alert(sRet);
}


D.  隐藏图层


隐藏一个图层的实现思路,得到数据库层表对象,然后根据层名得到层表记录对象,设置层表记录IsOff属性值。


例如代码,让用户在CAD图上选择一个对象,然后隐藏对象所在的图层C#:


  // 隐藏选择实体的层。

var ent = mxOcx.GetEntity("选择要关闭图层的实体:");
if(ent == null)
{
    return;
}
if (ent == null)
{
    return;
}
var sLayerName = ent.Layer;
var database = mxOcx.GetDatabase();

var layerTable = database.GetLayerTable();

var layerTableRec = layerTable.GetAt(sLayerName, false);
if(layerTable != null)
{
    layerTableRec.IsOff = true;
}


E. 显示图层


如下例子,得到层表,然后循环得到所有层表记录,并打开图层显示


例如代码 JS:


function OpenAllLayer() {
    var database = mxOcx.GetDatabase();
    //返回数据库中的层表对象
    var spLayerTable = database.GetLayerTable();
    //创建一个遍历层表中所有图层的遍历器
    var spIter = spLayerTable.NewIterator();
    //移动当前遍历器位置
    for(;!spIter.Done();spIter.Step(true,true))
    {
        //返回遍历器当前位置的记录
        var spLayerRec = spIter.GetRecord();
        var sName = spLayerRec.Name;
        var layerRec=spLayerTable.GetAt(sName,false);
        if(layerRec)
        {
            layerRec.IsOff = false;
            alert("成功显示图层");
        }
 
    }
 
}


F. 锁定图层


锁定后的图层上的实体不能编辑,但可以选择,如果想也不能选择,设置控件InitSet属性值为:SelectLockLayer=N


下面演示,遍历所有图层表记录,并设置图层为锁定状态,


例如代码 JS:


  function LockeAllLayer() {
    //返回控件的数据库对象
    var database = mxOcx.GetDatabase();
    //返回数据库中的层表对象
     var layerTable = database.GetLayerTable();
    //创建一个遍历层表中所有图层的遍历器
    var iter = layerTable.NewIterator();
    for (; !iter.Done(); iter.Step())
    {
        //返回遍历器当前位置的记录
        var layerRec = iter.GetRecord();
        layerRec.IsLocked = true;
        alert("成功锁定图层");

    }
}


F. 冻结图层


被冻结上的图层实体,不会参显示数据的生成,这样可以加快显示速度,和打开图纸的速度,它与关闭属性相比,冻结后的图层不但看不见,并且在内存中也不参加显示。


             // 冻结选择实体的层。
        
        var ent = mxOcx.GetEntity("选择要冻结图层的实体:");
        if(ent == null)
        {
            return;
        }
        if (ent == null)
        {
            return;
        }
        var sLayerName = ent.Layer;
        var database = mxOcx.GetDatabase();
        
        var layerTable = database.GetLayerTable();
        
        var layerTableRec = layerTable.GetAt(sLayerName, false);
        if(layerTable != null)
        {
            layerTableRec.IsFrozen = true;
            alert("成功冻结图层");
        }


G.调用图层管理界面


例如代码JS:


 mxOcx.SendStringToExecute("MxLayerManager");


H.得到图层上所有对象


我们通过构造选择集,使用图层名过虑来得到某个层上所有对象,关于选择集的类说明参考:http://www.mxdraw.com/help/frames.htm?frmname=topic&frmfile=IMxDrawSelectionSet.htm


例如代码 JS:


         // 创建一个过滤数据连表对象。
         var filter = mxOcx.NewResbuf();
         // 把层名加入过滤条件,8是DXF组码,0表示是的是一个层名。
         filter.AddStringEx("0", 8);
         //定义选择集对象
         var ss = mxOcx.NewSelectionSet();
         // 选择图上的所有对象。
         ss.Select2(5, null, null, null,filter);
         var i = 0;
        var listId = new Array();
         // 遍历所有对象,得到对象id.
         for (; i < ss.Count;i++)
         {
             var e =  ss.Item(i);
             listId.push(e.ObjectID);
         }
         return listId;


I. 设置指定图层上的实体不能选择


通过控件InitSet属性,来设置特定图层上的实体不能选择,有关IniSet的详细说明,参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__Iniset.htm


比如 JS:


 
            // 设置Layer1,Layer2,Layer3图层上的实体不能选择
            mxOcx.Iniset = "DisableSelectLayer=Layer1;Layer2;Layer3";


J. 设置CAD实体对象,到指定层上


实体对象都有一个层属性,可以直接修改该属性。


比如JS:


        var   ent = mxOcx.GetEntity("选择图层的实体:");
        if(ent == null)
        {
            return;
        }
        if (ent == null)
        {
            return;
        }
        
        // 得到数据库对象.
        var database = mxOcx.GetDatabase();
        // 得到层表.
        var layerTable = database.GetLayerTable();
        var sLayerName = "layer";
        // 得到层。
        var layer = layerTable.GetAt(sLayerName, true);
        if (layer == null)
        {
            // 如果没有层,就新建一个层。
            mxOcx.AddLayer(sLayerName);
        }
        else
        {
            // 如果层被删除,就反删除。
            layer.SetProp("unErase", null);
        }
        // 设置实体层名到指定层上。
        ent.Layer = sLayerName;
        alert("已将该实体设置到指定图层");


K.判断该层上是否有对象,是不是一个 无用 的层。


在CAD图上,一般需要遍历所有块表记录中的实体对象,才判断某个图层上是有对象实体,然后才能放心删除一个图层,因为一个图层上如果有实体对象,你删除该图层时,实体对象就会引用一个无效的图层。


所以控件专门提供一个定制函数,用来判断该图上是否有实体对象:


比如 JS:


       MxDrawResbuf param = (MxDrawResbuf)axMxDrawX1.Call("ExApp_isUselessLayer", "图层1");
        if(param.AtLong(1) == 1)
        {
            MessageBox.Show("该图层上没有对象");
        }


L.删除数据库所有无用的图层


我们提供一个定制函数,来遍历图上的所有对象,判断出图层上没有对象,然后删除。


比如 JS:


axMxDrawX1.Cal("ExApp_DeleteUselessLayer");


M.修改图层亮度


控件提供,让CAD图层上的所有对象,按指定亮度显示功能,比如亮度设置0,表示对象显示成灰色,一般一些背景不让修改的对象放在背景层上,然后把亮度设置成0.


Mx_SetLayerBright函数详细说明,参考:http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_SetLayerBright@LPCTSTR@DOUBLE@LONG.htm


Mx_SetBright 函数详细说明,参考:http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_SetBright@IN_LONG@CString.htm


例如设置图层 222按50%显示, JS代码:


    var param = mxOcx.NewResbuf();

// 图层名
    param.AddStringEx("222");

// 图层亮度.
    param.AddDoubleEx(50);

// 不自动调用更新函数。
    param.AddLongEx(0);

    mxOcx.CallEx("Mx_SetLayerBright", param);


N. 得到图层亮度


下面是得到图层的亮度,222表示的是图层名字。


JS代码:


    var ret = mxOcx.Call("Mx_GetLayerBright", "222");
    if (ret.AtString(0) == "Ok")
    {
        alert(ret.AtDouble(1).toString());
    }


O. 删除图层


在删除图层前,最好判断一个该图层上是否有CAD绘图对象,如果有的话就不要删除图层


JS代码:


private bool DeleteLayer(String sLayerName)
        {
            // 判断图上是否对象。
            MxDrawResbuf param = (MxDrawResbuf)axMxDrawX1.Call("ExApp_isUselessLayer", sLayerName);
            if (param.AtLong(1) != 1)
            {
                // 图上还有对象,不能删除。
                return false;
            }
            // 得到数据库对象.
            MxDrawDatabase database = (MxDrawDatabase)axMxDrawX1.GetDatabase();
            // 得到层表.
            MxDrawLayerTable layerTable = database.GetLayerTable();
            // 得到层。
            MxDrawLayerTableRecord layer = layerTable.GetAt(sLayerName, false);
            if (layer == null)
            {
                // 没有该层
                return false;
            }
            else
            {
                // 删除图层。
                layer.Erase();
                return true;
            }
        }
文字样式

DWG数据库中,文字样式存放在文字样式表中,表类名:MxDrawTextStyleTable,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawTextStyleTable.htm


文字样式表中每一条记录称为一种文字样式,类名:MxDrawTextStyleTableRecord,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawTextStyleTableRecord.htm


文字样式是随图纸保存,不同的图纸使用的文字样式都可能会不一样。


文字样式设置命令:Mx_Style, 比如:


mxOcx.SendStringToExecute("Mx_Style")

调用样式界面,如下图:


txtstyle.png


文字样式主要属性有:字体文件名,大字体文件名,新建文本高度,新建文本宽度缩放比例,文字倾斜角度,TrueType字体数据等


DWG数据库默认总是有一个"Standard"文字样式,该文字样式不能被删除。


文字样式在线演示例子:点击此处在线演示


视频演示:



A. 当前文字样式


当前文字样式表示向DWG数据库添加一个文字对象时,使用的默认的文字样式,通过系统变量TEXTSTYLE操作,系统变量设置参考:


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


设置当前文字样式JS


            // 添加文字样式
            mxOcx.AddTextStyle1("MyTextStyle", "txt.shx", "hztxt.shx", 1);
            // 得到当前数据库
            var database =mxOcx.GetDatabase();
            // 设置当前文字样式
            database.CurrentlyTextStyle =  "MyTextStyle";


取当前文字样式代码:


var sCurrentTextStyle = database.CurrentlyTextStyle;


B. 添加文字样式


下面代码,得到当前数据库中的文字样式表,然后向样式表中添加一个文字样表记录


JS代码:


function CreateText(){
    //返回控件的数据库对象
    var database =mxOcx.GetDatabase();
    //返回数据库中的文字样式表对象
    var mxtst = database.GetTextStyleTable();

    var txtStyle = mxtst.GetAt("duanceng", true);
    if(txtStyle != null)
    {
        // 当前数据已经有该文字样。
        // 如果被删除,就反删除。
        txtStyle.SetProp("unErase", null);
        return;
    }
    
    //增加新的文字样式
    var mxtstr = mxtst.Add("duanceng");
    //设置样式
    //设置文字的TrueType字体,如果文字样式设置了TrueType字体,就不会使用前面设置shx字体
    //参数一为turetype字体名 参数二为是否粗写  参数三为是否斜写  参数四为windows字符集  参数五暂没使用
    mxtstr.SetFont("黑体", false, false, 0, 0);
    //返回文字的高度
    mxtstr.textSize = 5;

}


调用上面函数,增加"aa"文字样式


 AddTextStyle("aa");

或者也可以这样


使用ocx.AddTextStyle1(添加线形字体文字样式),ocx.AddTextStyle2(添加TrueType字体文字样式)添加文字,该函数详细接口说明参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__AddTextStyle1@BSTR@BSTR@BSTR@DOUBLE.htm


比如VB代码


        MxDrawX1.AddTextStyle1 "MyTextStyle", "italicc.shx", "gbcbig.shx", 0.7
        MxDrawX1.TextStyle = "MyTextStyle"
        MxDrawX1.DrawColor = 255
        MxDrawX1.DrawText 0, 3000, "梦想绘图控件3.0 www.mxdraw.com", 100, 0, 0, 1


比如添加一个黑体字体的文字样式


       '添加TureType字体
        MxDrawX1.AddTextStyle2 "MyTrueTypeStyle", "黑体", 0.7
        MxDrawX1.TextStyle = "MyTrueTypeStyle"
        MxDrawX1.DrawText 0, 3150, "梦想绘图控件3.0 www.mxdraw.com", 100, 0, 0, 1


效果展示:


addtxtstyle.png


C. 得到所有文字样式


下面代码是遍历文字样式表中所有文字样式,并得到所有文字样式名,在遍历的循环中,得到每个文字样式记录对象,可以去修改它的属性


  function GetAllText() {
    var database = mxOcx.GetDatabase();
    // 得到所有图层名
    var sRet = null;
    //返回数据库中的文字样式表对象
    var spTextStyleTable = database.GetTextStyleTable();
    //创建一个遍历层表中所有图层的遍历器
    var spIter = spTextStyleTable.NewIterator();
    //移动当前遍历器位置
    for(;!spIter.Done();spIter.Step(true,true))
    {
        //返回遍历器当前位置的记录
        var spTextStyleRec = spIter.GetRecord();
        //符号表记录名属性
        var sName = spTextStyleRec.Name;
        // 0零层不参加比较
        if(sName != "0")
        {
            if(sRet == null)
                sRet = sName;
            else
            {
                sRet = sRet +","+sName;
            }
        }
    }
    alert(sRet);
}


D. 删除文字样式


在删除文字样式前,最好判断图上有没有文字对象正在使用该文字样式,如果有的话就不要删除文字样式


JS代码如下:


   function DelText() {
    var winWidth = 440;
    var winHeight = 140;
    var winLeft = (screen.width - winWidth) / 2;
    var winTop = (screen.height - winHeight) / 2 - 20;
    var str = 'dialogHeight:' + winHeight + 'px;dialogWidth:' + winWidth + 'px;dialogTop:' + winTop + 'px;dialogLeft:' + winLeft + 'px;resizable:yes;center:yes;status:no;'
    var rt = window.showModalDialog("Gettext.htm?tmp=" + Math.random(), "输入图层名", str);
    var txt;
    if (typeof (rt) == "undefined") {
        return;
    } else {
        var arr = rt.split(",");
        txt = arr[0];
    }
    var database = mxOcx.GetDatabase();
    //返回数据库中的文字样式表表对象
    var TextStyleTable = database.GetTextStyleTable();
    //得到层表中的文字样式表对象
    var TextStyleRec = TextStyleTable.GetAt(txt, false);
    if (TextStyleRec == null)
        return;
    //删除对象
    TextStyleRec.Erase();
    alert("成功删除文字样式");
}


E.调用文字样式管理界面


Mx_Style是文字样式命令名


例如代码 JS:


mxOcx.SendStringToExecute("Mx_Style");


F. 修改文字对象的文字样式


文字对象都一个TextStyle属性,用这个属性可以设置,或取到文字对象的文字样式。


下面代码演示设置一个文字对象的字体为黑体,如果没有文字样式,就添加文字样式。


        var  ent = mxOcx.GetEntity("选择实体对象:");
        if(ent == null)
        {
            return;
        }
        // 得到数据库对象.
        var database = mxOcx.GetDatabase();
        // 得到文本式表.
        var textStyleTable = database.GetTextStyleTable();
        var sTextStyleName = "MyTextStyleName";
        // 得到文本式
        var textStyle = textStyleTable.GetAt(sTextStyleName, true);
        if (textStyle == null)
        {
            // 如果没有就新建一个。
            mxOcx.AddTextStyle2(sTextStyleName, "黑体", 0.7);
        }
        else
        {
            // 如果被删除,就反删除。
            textStyle.SetProp("unErase", null);
            textStyle.SetFont("黑体", false, false, 0, 0);
        }
        // 设置实体文字样式。
        ent.TextStyle = sTextStyleName;
        alert("已将该实体设置文字样式");


G. 得到图所有文字对象使用的字体文件


下面代码会遍历图上所有CAD文字对象,然后取它使用的字体信息


        var database = mxOcx.GetDatabase();
//返回数据库中的文字样式表表对象
        var textStyleTable = database.GetTextStyleTable();
// 定义选择集对象
        var ss = mxOcx.NewSelectionSet();
//构造一个过滤链表
        var spFilte = mxOcx.NewResbuf();
//得到当前空间的所有实体
        ss.AllSelect (spFilte);

// 遍历所有对象
        for(var i = 0;i <ss.Count;i++)
        {
            var ent = ss.Item(i);
            // 得到对象使用的文字样式记录.
            var rec = textStyleTable.GetAt(ent.TextStyle);
            if (rec == null)
                continue;
            // 得到TrueType字体属性。
            var pTypeface = "";
            var bold = false;
            var italic = false;
            var charset = 0;
            var pitchAndFamily = 0;
            rec.Font(pTypeface,bold,italic,charset,pitchAndFamily);
            var sShxFileName;
            var sBigShxFileName;
            var sShxFileName1;

            // 如果TrueType字体名为空,表示使用的Shx字体。
            if(pTypeface.Length != 0)
            {
                // 得到西文字体
                sShxFileName = rec.fileName;

                // 得到中文字体
                sBigShxFileName = rec.bigFontFileName;
               sShxFileName1=sShxFileName+sBigShxFileName;
               
                alert(sShxFileName1);
                
            }

        }


H. 文字显示号问题原因和解决办法


打开DWG时,图纸中使用的shx字体文件在本地电脑不能找到时,控件会默认使用缺省的字体txt.shx,hztxt.shx来代替,这样一般文字不会显示成问号,但是如果文字中的特殊符号在默认字体也一样找不到,这时就会显示成问号。 使用缺省的字体的代替的文字样式,可能会出现文字显示大小,样子不一至的效果。


这时最好的办法是,把需要使用的字体拷到MxDrawX.ocx所在目录的shx目录下,如果不知道当前用的MxDrawX.ocx在位置,可以命令行输入mx_about看到控件安装位置


mxabout.png


如下图,打开图时,在命令行提示找不到字体


rtxt.png


修改控件Iniset属性,Iniset="ShxPath=D:/shx"添加一个字体搜索位置,


修改控件Iniset属性, Iniset="DownLoadServerFont=Y",设置打开网络图纸时,自动下载服务器上的字体文件。默认不会下载.,服务器需要 设置MIME,增加shx文件类型支持. 


修改控件Iniset属性, Iniset="SHXWEBSITEADDRESS=http://www.mxdraw.com/shx",设置字体下载位置


修改控件Iniset属性, Iniset="DefaultText=txt.shx", 设置缺省的shx文件


修改控件Iniset属性, Iniset="DefaultBigText=hztxt.shx", 设置缺省的big shx文件


iniset属性接口说明,参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__Iniset.htm

标注样式

DWG数据库中,标注样式存放在标注样式表中,表类名:MxDrawDimStyleTable,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawDimStyleTable.htm


标注样式表中每一条记录称为一种标注样式,类名:MxDrawDimStyleTableRecord,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawDimStyleTableRecord.htm


标注样式是随图纸保存,不同的图纸使用的标注样式都可能会不一样。


标注样式设置命令:Mx_Dimstyle, 比如:


mxOcx.SendStringToExecute("Mx_Dimstyle")


调用样式界面,如下图:


dimstyle.png


标注样式主要属性有:double,int string三个类型标注的变量设置,通过设置三类的变量的值,就能设置标注样式的各种控制值。


比如:GetDimVarDouble,SetDimVarDouble ,设置Double类型属性,可以设置的值有如下:


(m_标注变量名,DXF组码)
m_dimaltf,143
m_dimasz , 41
m_dimcen ,141
m_dimdle , 46
m_dimdli , 43;
m_dimexe , 44;
m_dimexo , 42;
m_dimgap ,147;
m_dimlfac,144;
m_dimrnd , 45;
m_dimscale, 40;
m_dimtfac,146;
m_dimtm  , 48;
m_dimtp  , 47;
m_dimtsz ,142;
m_dimtvp ,145;
m_dimtxt ,140;
m_dimaltrnd,148;


因为我们的标注设置和AutoCAD保持一至,所以如果不清楚,标注变量名具体代表什么属性,可以复制标注变量,然后在百度搜索AutocAD 标注变量名,就能看见。


比如,我们搜索 dimaltf,是什么属性,如下图:


dimver.png


比如,我们要修改标注样式中的文字高度,文件高度控制变量是dimtxt,对应的DXF组码是140,所以如下调用,设置文件高度是100, 140是DXF组码。


dimstyle.SetDimVarDouble(140, 100);


GetDimVarInt,SettDimVarInt ,设置Int类型属性,可以设置的值有如下:


m_dimadec,179
m_dimalt ,170
m_dimaltd ,171
m_dimalttd,274
m_dimalttz,286
m_dimaltu ,273
m_dimaltz ,285
m_dimaunit,275
m_dimclrd ,176
m_dimclre ,177
m_dimclrt ,178
m_dimdec  ,271
m_dimfit  ,287
m_dimjust ,280
m_dimlim  , 72
m_dimsah  ,173
m_dimsd1  ,281
m_dimsd2  ,282
m_dimse1  , 75
m_dimse2  , 76
m_dimsoxd ,175
m_dimtad , 77
m_dimtdec ,272
m_dimtih  , 73
m_dimtix  ,174
m_dimtofl ,172
m_dimtoh  , 74
m_dimtol  , 71
m_dimtolj ,283
m_dimzin , 78
m_dimunit ,270
m_dimupt  ,288
m_dimtzin  ,284
m_dimfrac ,276
m_dimlunit,277
m_dimatfit,289
m_dimtmove,279
m_dimazin, 79


比如,设置标注中的文字显示小数位,设置不显示小数位,调用如下:


curDimRecord.SetDimVarInt(271, 0);


GetDimVarString,SetDimVarString 设置String类型属性,可以设置的值有如下:


m_dimapost,4
m_dimpost,3
m_dimblk,  342
m_dimblk1,  343
m_dimblk2,  344
m_dimldrblk,341
m_dimtxsty,340
m_dimltype,345
m_dimltex1,346
m_dimltex2,347


如下,设置标注两端使用建筑标注效果


curDimRecord.SetDimVarString(342, "_ARCHTICK");


如下图风格:


as.png


标注样式在线演示例子:点击此处在线演示


视频演示:



A. 当前标注样式


当前标注样式表示向DWG数据库添加一个标注对象时,使用的默认的标注样式,通过系统变量DIMSTYLE操作,系统变量设置参考:


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


设置当前标注样式js代码:


// 添加一个标注文本使用的文字样式
var idTextStyleId = mxOcx.AddTextStyle1("MyTextStyle", "italicc.shx", "gbcbig.shx", 0.7);
// 文字高度140,2.5
// 标注精度: 271,4
var idDimStyleId = mxOcx.AddDimStyle("MyDimStyle", "41,0.25,141,0.09,40,203,140,2.5", "271,4",
    "", ("340,{0}",idTextStyleId));
var dimRec = mxOcx.ObjectIdToObject(idDimStyleId);
// 设置小数点分隔符.
dimRec.SetDimVarInt(278, '.');
// 测量比例因子: 144,2
dimRec.SetDimVarDouble(144, 2);
// 设置超出尺寸界线 dimexe , 44
dimRec.SetDimVarDouble(44, 0.01);

// 得到当前数据库
var database = mxOcx.GetDatabase();
// 设置当前文字样式
database.CurrentlyDimstyleName = "MyDimStyle";

//取当前标注样式代码:
var sCurrentlyDimstyleName = database.CurrentlyDimstyleName;


设置控件Draw函数使用标注式,需要如下:


// 设置mxOcx.Drawxxx函数使用的标注样式
mxOcx.DimStyle = "MyDimStyle";


B. 添加标注样式


下面代码,得到标注样式表,然后向标式表中添一个表记录。


实现js代码如下:


  function CreateDim(){
    //返回控件的数据库对象
    var database =mxOcx.GetDatabase();
    //返回数据库中的标注样式表对象
    var mxdim = database.GetDimStyleTable();
    //增加新的标注样式
    var dimstr = mxdim.Add("mydim");
    //设置样式
    dimstr.SetDimVarDouble(40, 20.0);
    //返回数据库中的标注样式表对象
    database.CurrentlyDimstyleName = "mydim";
 
}


也可以使用 AddDimStyle用来增加一个标注样式,详细参考:

http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__AddDimStyle@BSTR@BSTR@BSTR@BSTR@BSTR.htm


比如:


 MxDrawX1.AddDimStyle "MyDimStyle2", "41,0.18,141,0.09,40,200", "77,1,271,3", "", ""
  
 MxDrawX1.DimStyle = "MyDimStyle2"


C. 得到所有标注样式


下面代码遍历标注样式表,然后得到每个样式名称,js代码如下:


  function GetAllDim() {
    var database = mxOcx.GetDatabase();
    // 得到所有图层名
    var sRet = null;
    //返回数据库中的文字样式表对象
    var spDimStyleTable = database.GetDimStyleTable();
    //创建一个遍历层表中所有图层的遍历器
    var spIter = spDimStyleTable.NewIterator();
    //移动当前遍历器位置
    for(;!spIter.Done();spIter.Step(true,true))
    {
        //返回遍历器当前位置的记录
        var spDimStyleTableRec = spIter.GetRecord();
        //符号表记录名属性
        var sName = spDimStyleTableRec.Name;

            if(sRet == null)
                sRet = sName;
            else
            {
                sRet = sRet +","+sName;
            }
    }
    alert(sRet);
}


D. 删除标注样式


在删除标注样式前,最好判断图上有没有标注对象正在使用该样式,如果有的话就不要删除文字样式


js代码如下:


function DelDim() {
  
    var winWidth = 440;
    var winHeight = 140;
    var winLeft = (screen.width - winWidth) / 2;
    var winTop = (screen.height - winHeight) / 2 - 20;
    var str = 'dialogHeight:' + winHeight + 'px;dialogWidth:' + winWidth + 'px;dialogTop:' + winTop + 'px;dialogLeft:' + winLeft + 'px;resizable:yes;center:yes;status:no;'
    var rt = window.showModalDialog("Gettext.htm?tmp=" + Math.random(), "输入图层名", str);
    var txt;
    if (typeof (rt) == "undefined") {
        return;
    } else {
        var arr = rt.split(",");
        txt = arr[0];
    }
    var database =mxOcx.GetDatabase();
    database.CurrentlyDimstyleName = "Standard";
   
    //返回数据库中的样式表对象
    var DimStyleTable = database.GetDimStyleTable();
    //得到样式表表中的样式对象
    var DimStyleRec = DimStyleTable.GetAt(txt, false);
    if (DimStyleRec == null)
        return;
    //删除对象
    DimStyleRec.Erase();
    alert("成功删除标注样式");
}


E.修改标注对象的标注样式


标注对象都一个DimensionStyle属性,用这个属性可以设置或取到标注对象的标注样式。


下面代码演示设置一个标注对象的样式


    var  ent = mxOcx.GetEntity("选择标注对象:");
    if(ent == null)
    {
        return;
    }
    var dim = ent;
    // 得到数据库对象.
    var database = mxOcx.GetDatabase();
    // 得到标注样式表.
    var dimStyleTable = database.GetDimStyleTable();
    var sDimStyleName = "MyDimStyleName";
    // 得到文本式
    var dimStyle = dimStyleTable.GetAt(sDimStyleName, true);
    if (dimStyle == null)
    {
        // 如果没有就新建一个。
        mxOcx.AddDimStyle("MyDimStyleName", "41,0.18,141,0.09,40,200", "77,1,271,3", "", "");
    }
    else
    {
        // 如果被删除,就反删除。
        dimStyle.SetProp("unErase", null);
    }
    // 设置实体文字样式。
    dim.DimensionStyle = "MyDimStyleName";

    alert("已修改对象标注样式");
}
全局字典

CAD图纸中有个全局字典,用来存放图纸中的全局信息,开发者可以通过在字典存放扩展记录方式存放自己的全局数据,字典已经内置了一些数据,比如:组,多线样式,布局信息,图片定义,Wipout等数据,比如下图:


dict1.png


全局字典类名:MxDrawDictionary,详细信息参考:http://www.mxdraw.com/help/IMxDrawDictionary.htm


得到DWG图的全局字典,js代码:


// 得到数据库对象.
var database = mxOcx.GetDatabase();
// 得到全局字典
var dict = database.GetNamedObjectsDictionary();


全局字典在线演示例子:点击此处在线演示


视频演示:



A. 遍历字典


字典中可以再存放字典(嵌套存放),也可以存一个扩展记录,类名:MxDrawXRecord,详细参考:http://www.mxdraw.com/help/IMxDrawXRecord.htm,


下面代码,演示了,使用递归方式,如果去遍历字典中所有数据,js如下


function GetAllDictionaryDataCall(dict) {
    // 创建一个字典遍历器
    var iter = dict.NewIterator();
    var sOut = "";
    for (; !iter.Done(); iter.Step())
    {
        // 遍历到每个字典,取出名称.
        var sName = iter.Name();
        sOut = sOut + "," + sName;
        var obj = iter.GetObject();
        if (obj == null)
            continue;
        if (obj.ObjectName == "McDbDictionary")
        {
            var tmpDict = obj;
            sOut += "," + GetAllDictionaryDataCall(tmpDict);
        }
    }
    return sOut;
    
}


执行


    // 得到数据库对象.    
    var database = mxOcx.GetDatabase();
    // 得到全局字典
    var dict = database.GetNamedObjectsDictionary();
    var sOut = GetAllDictionaryDataCall(dict);
    
    alert(sOut);


B. 写扩展记录


用户自定义的全局数据,通过扩展记录方式写到DWG图中


下面代码,取到图纸全局字典,然后在字典中放一个用户自己的字典,在字典写一个扩展记录数据


如下js代码


function wirteGlobalVer(sName, sVal) {

    // 得到CAD数据库
    var database = mxOcx.GetDatabase();
    // 得到全局字典
    var dict = database.GetNamedObjectsDictionary();
    // 得到用户自定义字典,MyExDataDictName是字典名称
    var myDict = dict.GetAt("MyExDataDictName");
    if (myDict == null)
    {
        // 如果没有,就添加一个字典。
        myDict = dict.AddObject("MyExDataDictName", "McDbDictionary");
    }
    // 得到字典中的扩展记录数据。


    var rec =myDict.GetAt(sName);
    if (rec == null)
    {
        // 如果没有就,添加一个扩展记录.
        rec = myDict.AddXRecord(sName);
    }
    // 创建数据链表.
    var res = mxOcx.NewResbuf();
    // 设置值。
    res.AddString(sVal);
    // 设置扩展记录数据。
    rec.SetXRecordData(res);
    
}


执行


 wirteGlobalVer("MyData", "aaaa");
 alert("写入成功");


DWG中的数据内容如下:


dict2.png


C. 读扩展记录


上面写的数据,能过如下方式读取,


js代码:


function readGlobalVar(sName) {

    // 得到CAD数据库
    var database = mxOcx.GetDatabase();
    // 得到全局字典
    var dict = database.GetNamedObjectsDictionary();
    // 得到用户自定义字典,MyExDataDictName是字典名称
    var myDict = dict.GetAt("MyExDataDictName");
    if (myDict == null)
    {
        // 没有数据。
        return "";
    }
    // 得到字典中的扩展记录数据。
    var rec = myDict.GetAt(sName);
    if (rec == null)
    {
        // 没有数据。
        return "";
    }
    // 得到记录中的数据链表。
    var ret = rec.GetXRecordData();
    if (ret == null)
        return "";
    // 返回写的数据。
    return ret.AtString(0);

}


调用代码 :


var sRet = readGlobalVar("MyData");
if (sRet == "")
{
    alert("没有数据")
}
else
{
    alert(sRet);
}
块表

DWG数据库中,所有图块存放在块表中,块表类名:MxDrawBlockTable,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockTable.htm


块表中每一条记录称为块表记录,类名:MxDrawBlockTableRecord,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockTableRecord.htm


块表记录中存放所有实体数据。每个DWG数据库中,到少有一个名为"*Model_Space"的块表记录(模型空间),CAD图纸打开后,默认看到的对象都存放在模型空间,有一种对象是块引用MxDrawBlockReference,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockReference.htm,块引用又可以指向另一个块表记录。


调用MxDrawDatabase::GetBlockTable 得到DWG数据库中块表


            // 得到当前数据库。
            var database = mxOcx.GetDatabase();
            // 得到块表.
            var blkTable = database.GetBlockTable();


调用MxDrawDatabase::CurrentSpace 得到当前空间(当前显示的块表记录),有了当前空间,就能在CAD图上添加,删除,遍历显示的对象。


得到当前空间:如下代码,


            // 得到当前数据库。
            var database = mxOcx.GetDatabase();
            // 得到当前块表记录.
            var blkRec = database.CurrentSpace();


块表在线演示例子:点击此处在线演示


A. 得到所有图块


下面代码,遍历块表的每条记录,然后得到块名,js如下:


        var database = mxOcx.GetDatabase();
        var blkTab = database.GetBlockTable();
        var iter = blkTab.NewIterator();
        for (; !iter.Done(); iter.Step())
        {
            var blkRec = iter.GetRecord();
            alert(blkRec.Name);
         
        }


B.  判断当前数据库中,是有指定的块名


var database = mxOcx.GetDatabase();

var sBlkName = "Tree";
if (database.GetBlockTable().Has(sBlkName))
{

    alert("有指定块名");
    // 已经插入.
}
else{
    alert("无指定块名")
}


C.  遍历某名称图块下所有实体


        var database = mxOcx.GetDatabase();
        var sBlkName = "Tree";
        var blkRec = database.GetBlockTable().GetAt(sBlkName);
        var iter = blkRec.NewIterator();
        if (iter == null)
            return;
        var iNum = 0;
        // 循环得到所有实体
        for (; !iter.Done(); iter.Step(true, false))
        {
            // 得到遍历器当前的实体
            var ent = iter.GetEntity();
            alert(ent.ObjectName);
        
            iNum++;
        }
        alert(iNum.ToString());


D.   得到当前空间中所有实体


下面代码演示如何得到当前块表记录,然后遍历块表记录,取到每个对象,判断对象类型,然后得到对象的属性数据。


var mxUtility = mxOcx.NewUtility;

// 得到当前图纸空间
var blkRec = mxOcx.GetDatabase().CurrentSpace();

// 创建一个用于遍历当前图纸空间的遍历器
var iter = blkRec.NewIterator();
if (iter == null)
    return;

// 所有实体的id数组。
var aryId =  new Array();

var iLineNum = 0;
// 循环得到所有实体

for (; !iter.Done(); iter.Step(true, false))
{
    // 得到遍历器当前的实体
    var ent = iter.GetEntity();
    if (ent == null)
        continue;

    // 得到实体的id
    aryId.push(ent.ObjectID);


    var c= aryId.length;
    console.log(c);

    if (ent.ObjectName == "McDbLine")
    {
        // 当前实体是一个直线
        var line = ent;
        iLineNum++;
    }
else if (ent.ObjectName ==  "McDbBlockReference")
    {
        // 当前实体是一个块引用
        var blkRef =ent;
        for (var j = 0; j < blkRef.AttributeCount; j++)
        {
            // 得到块引用中所有的属性
            var attrib = blkRef.AttributeItem(j);
            mxUtility.Prompt("n Tag: " + attrib.Tag + "Text:" + attrib.TextString);
        }
    }
}

var sT;
sT = "发现" + aryId.length + "个实体,其中有" + iLineNum + "个直线";
alert(sT);


E   添加块表记录


下面代码,判断块表中是否有指定名称的块表记录,如果没有就增一个块表记录。


        function AddBlockRrecord(sName,blkOriginPoint) {
    // 取当前数据库.
    var curDatabase = mxOcx.GetDatabase();
    // 得到块表
    var blkTable = curDatabase.GetBlockTable();
 
    // 判断块表是否已经有该名称的块名。
    if (blkTable.Has(sName))
    {
        var blkRec = blkTable.GetAt(sName, true);
        // 如果块被删除,就反删除。
        blkRec.SetProp("unErase", null);
        return true;
    }
    // 新增一个块表记录.
    var blkNewRec = blkTable.Add(sName);
    if (blkNewRec == null)
        return false;
    // 设置块表记录的插入基点
    blkNewRec.Origin = blkOriginPoint;
    return true;
}


调用代码:


        var  pt = mxOcx.NewPoint();
        pt.x = 100;
        pt.y = 100;
        AddBlockRrecord("MyBlkName", pt);
        alert("成功");


运行后块表中多了一个我们添加的块表记录


blk1.png


F. 选择实体做成块


下面代码,让用在图上选择实体,然后把实体做成一个图块,然后插入到图上。


js代码如下:


//实例化一个构造选择集进行过滤,该类封装了选择集及其处理函数。
var ss = mxOcx.NewSelectionSet();
//构造一个过滤链表
var spFilte = mxOcx.NewResbuf();
//用户选择对象  得到用户选取的实体
ss.Select2(8, null, null, null, spFilte);
 
var aryId = new Array();
for (var i = 0; i < ss.Count; i++)
{
    var ent = ss.Item(i);
    if (ent != null)
    {
        aryId.push(ent.ObjectID);
        ent.Close();
    }
}
//返回控件的数据库对象
var curDatabase =mxOcx.GetDatabase();
var dMinX = 0, dMinY = 0, dMaxX = 0, dMaxY = 0;
var isFirstEnt = true;
for (var l = 0; l < aryId.length; l++)
{
    var pObj = curDatabase.ObjectIdToObject(aryId[l]);
    if (pObj == null)
        continue;
    var pEnt = pObj;
    if (pEnt == null)
        continue;
    var  points = pEnt.GetBoundingBox2();
 
    var minPt = points.Item(0);
    var maxPt = points.Item(1);
 
    if (minPt != null && maxPt != null)
    {
        if(isFirstEnt)
        {
            dMinX = minPt.x;
            dMinY = minPt.y;
            dMaxX = maxPt.x;
            dMaxY = maxPt.y;
            isFirstEnt = false;
        }
        else
        {
            if (dMinX > minPt.x)
                dMinX = minPt.x;
 
            if (dMinY > minPt.y)
                dMinY = minPt.y;
 
            if (dMaxX < maxPt.x)
                dMaxX = maxPt.x;
 
            if (dMaxY < maxPt.y)
                dMaxY = maxPt.y;
        }
    }
}
 
if(isFirstEnt)
{
    // 没有实体
    return;
}
var pos = mxOcx.NewPoint();
pos.x = dMinX + (dMaxX - dMinX) / 2.0;
pos.y = dMinY + (dMaxY - dMinY) / 2.0;
 
// 检查新创建的块名,在当前数据库是否已经存在.
 
var blkTable = curDatabase.GetBlockTable();
var curSpace = curDatabase.CurrentSpace();
 
var sNewBlakName;
 
var blkNewRec = blkTable.Add("");
sNewBlakName = blkNewRec.Name;
 
blkNewRec.Origin = pos;
 
for (var l = 0; l < aryId.length; l++)
{
 
    blkNewRec.AddCloneEntity(aryId[l]);
    // 把以前实体删除 。
    var pObj = curDatabase.ObjectIdToObject(aryId[l]);
    if (pObj == null)
        continue;
    pObj.Erase();
}
if (blkNewRec != null)
{
    var blkRef = curSpace.InsertBlock(pos.x,pos.y, sNewBlakName, 1.0, 0.0);
    var attrib = blkRef.AppendAttribute();
    attrib.Position = pos;
    attrib.AlignmentPoint = pos;
    attrib.Oblique = 0.0;
    attrib.Rotation = 0.0;
    attrib.Height = 2.0;
    attrib.TextString = "这是一个属性文字的测试";
    attrib.Tag = "TestTag";
    attrib.IsInvisible = false;
 
    blkRef.Position = blkRef.Position;
 
}
 
return;


G. 把一个DWG文件插入到当前文件


调用控件的InsertBlock函数,把一个DWG文件,插入到图上,指定一个块名,放在块表记录中。InsertBlock的函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__InsertBlock@BSTR@BSTR.htm,


如果给的图块名,当前图上已经有该名称的图块,可以调用Mx_InsertBlockEx 自定义函数,告诉控件是否需要重新定义图块。Mx_InsertBlockEx的详细说明: http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_InsertBlockEx@CString@CString@INT@CString@bool.htm


然后调用DrawBlockReference函数绘制块引用,引用InsertBlock创建的块表记录。函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__DrawBlockReference@DOUBLE@DOUBLE@BSTR@DOUBLE@DOUBLE.htm


下面代码,演示如何插入DWG.


            mxOcx.InsertBlock("G:\pt1000.dwg", "MyBlkName");
            mxOcx.DrawBlockReference(0, 0, "MyBlkName", 1.0, 0.0);
            mxOcx.ZoomAll();


H. 把一个图块插入基出,修正到图块的中心点。


下面,会遍历图块中所有实体,然后求所有实体的最小外包,再计算出外包的中心点,再把块记录的Origin属性修改到中心点。sBlkName是图块名。


//返回控件的数据库对象
var databae = mxOcx.GetDatabase();
//返回数据库中的块表对象
var blkTab = databae.GetBlockTable();
var sBlkName = "123";
var blkRec = blkTab.GetAt(sBlkName);
if (blkRec == null)
    return false;
//创建一个遍历块表中所有记录的遍历器
var mBlockTableReciter = blkRec.NewIterator();
var mMaxPt = mxOcx.NewPoint();
var mMinPt = mxOcx.NewPoint();
var mMaxPtTemp = mxOcx.NewPoint();
var mMinPtTemp = mxOcx.NewPoint();
var isFirstEnt = true;
//移动当前遍历器位置
for (; !mBlockTableReciter.Done(); mBlockTableReciter.Step(true, false))
{
    //与用户交互在图面上选择一个实体
    var ent = mBlockTableReciter.GetEntity();
    //返回实体的最小矩形框外包

    var  points = ent.GetBoundingBox2();

    var mMinPtTemp = points.Item(0);
    var mMaxPtTemp = points.Item(1);
    
    if ((mMinPtTemp == null) || (mMaxPtTemp == null))
        break;
    if (isFirstEnt)
    {
        mMinPt.x = mMinPtTemp.x;
        mMinPt.y = mMinPtTemp.y;
        mMaxPt.x = mMaxPtTemp.x;
        mMaxPt.y = mMaxPtTemp.y;
        isFirstEnt = false;
    }
    else
    {
        mMaxPt.x = Math.max(mMaxPt.x, mMaxPtTemp.x);
        mMaxPt.y = Math.max(mMaxPt.y, mMaxPtTemp.y);
        mMinPt.x = Math.min(mMinPt.x, mMinPtTemp.x);
        mMinPt.y = Math.min(mMinPt.y, mMinPtTemp.y);
    }
}
if (isFirstEnt)
{
    // 没有实体
    return false;
}
var mNewBasePt = mxOcx.NewPoint();
mNewBasePt.x = mMinPt.x + (mMaxPt.x - mMinPt.x) / 2;
mNewBasePt.y = mMinPt.y + (mMaxPt.y - mMinPt.y) / 2;
//块表记录的插入原点属性
blkRec.Origin = mNewBasePt;
//重新生成图,重新生成所有显示数据
mxOcx.Regen();
return true;


I. 属性块


下面我们演示如果在AutoCAD中做一个属性块文件,然后在控件中如何插入该属性块,并修改它的属性。


1. 打开AutoCAD软件,画一些图形,比如我画了一个圆,然后用attdef命令,插入一个属性定义,如下图:


attrib.png


插入属性定义,如下图


attrib2.png


2. 使用WBLOCK命令,把我们画的图形输入一个块文件,命令界面如下:


基点,选对圆的中心位置,它是图块的插入原点,点选择对象,选择我们刚画的圆和属性定义,目标指定我们的输出文件位置.


attrib3.png


这样我们做好图块文件MyBlock.dwg


3. 下面代码,会插入MyBlock.dwg文件,然后绘一个属性块,然后修改图块属性文字,


js如下:


// 注释文本内容
var sNoteText = "这是属性文字";
// 注释图块名
var sNote = "NoteBlockName";
// 让用点取一个注释插入点。

//与用户交互到在图上提取一个点
var point = mxOcx.GetPoint(false,0,0,"\n 点取插入点:");

if (point == null)
{
   alert("用户取消..");
    return;
}

var curDatabase = mxOcx.GetDatabase();
// 得到块表对象
var blkTable = curDatabase.GetBlockTable();
// 得到当前空间
var curSpace = curDatabase.CurrentSpace();
// 当前块表中是否已经有名为sNote的块表记录,如有返回
var blkRec = blkTable.GetAt(sNote, true);
if (blkRec == null)
{
    //  没有就新插入块表记录
    //  sBlkFilePath是块文字路径


    var sBlkFilePath = "d:\\MyBlock.dwg";
    // 把dwg文件导入到当前数据库。
    mxOcx.InsertBlock(sBlkFilePath, sNote);
    // 得到新插入的块表记录
    blkRec = blkTable.GetAt(sNote, true);
}
if (blkRec != null)
{
    // 在当前空间中插入一个块引用。
    var blkRef = curSpace.InsertBlock(point.x, point.y, sNote, 4.0, 0.0);
    // 创建属性块的属性。
    var param = mxOcx.NewResbuf();
    blkRef.SetProp("createAttribute", param);
    // 修改属性文字。
    for (var j = 0; j < blkRef.AttributeCount; j++)
    {
        // 得到块引用中所有的属性
        var  attrib = blkRef.AttributeItem(j);
        if (attrib.Tag == "MYATTRIB")
        {
            attrib.TextString = sNoteText;
        }
    }
    // 修改了属性文字,通知块引用更新显示。
    blkRef.AssertWriteEnabled();
}


J. 得到图上所有属性块的属性文本.


下面代码,得到图上所有图块,然后遍历每个图块,再遍历每个属性块的属性


js代码:


// 构造一个选择集.
var ss = mxOcx.NewSelectionSet();
// 创建一个过滤选择条件.
var spFilte = mxOcx.NewResbuf();
// 把块引用对象,当着过滤条件.
spFilte.AddStringEx("INSERT", 5020);
// 得到图上,所有引用对象.
ss.AllSelect(spFilte);
var  str = "";
// 遍历所有块引用。
for (var i = 0; i < ss.Count; i++)
{
    var ent = ss.Item(i);
    if (ent == null)
        continue;
    if (ent.ObjectName == "McDbBlockReference")
    {
        var blkRef = ent;
        // 遍历属性块的属性。
        for (var j = 0; j < blkRef.AttributeCount; j++)
        {
            // 得到块引用中所有的属性
            var attrib = blkRef.AttributeItem(j);
            str += attrib.TextString + "---";
        }
    }
}
alert(str);
线型

DWG数据库中,线型样式存放在线型样式表中,表类名:MxDrawLinetypeTable,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawLinetypeTable.htm


线型样式表中每一条记录称为一种线型样式,类名:MxDrawLinetypeTableRecord,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawLinetypeTableRecord.htm


线型样式是随图纸保存,不同的图纸使用的线型样式都可能会不一样。


文字样式设置命令:Mx_Linetype, 比如:


ocx.SendStringToExecute("Mx_Linetype")


简单线型定义是通一个double数组来表示,大于零表示线型的实线长度,小于零表示线型的虚线长度,比如


1,-1,2,-2定义的线如下


linetype.png


在控件程序所在目录下有个mx.lin线型定义文件,定义了一些常用的线型,线型文件定义格式与AutoCAD线型定义文件一至,可在百度搜索到AutoCAD线型定义文件格式教程。


调用控件函数:LoadLinetypeFromFile从线型文件加载线型,函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__LoadLinetypeFromFile@BSTR@BSTR@VARIANT_BOOL.htm


下面代码,从线型文件加CENTER线型,然使用该线型,画一条直线


 var  lId = mxOcx.LoadLinetypeFromFile(mxOcx.GetOcxAppPath() + "//mx.lin", "CENTER",true);
 mxOcx.LineType = "CENTER";
 mxOcx.DrawLine(0, 0, 100, 100);


修改全局线型比例代码如下:


//返回控件的数据库对象
 var database = mxOcx.GetDatabase();
 
// 设置全局线型比例
database.LinetypeScale = 2.0;


MxDrawDatabase的CurrentlyLineTypeScale属性,设置新增加到数据库的对象的默认线型缩放比例


MxDrawDatabase的CurrentlyLineTypeName属性,设置新增加到数据库的对象的默认线型


在有些时候,明明一些线有线型,但显示成实线的原因是,线型的中空白长度远远小于或远远大于当前视区显示的范围上长度(不在一个数量级上),此时控件会显示成实线,AutoCAD软件也一样。这时可以通修改对象的线型比例或全局线型比例,让线型的显示大小在一个合理范围内,也可通过放大或缩小视区后,然后使用重新命令重新生成显示。


线型在线演示例子:点击此处在线演示


A. 添加线型


使用控件的AddLinetype,AddLinetypeEx函数,添加一种线型,详细接口说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__AddLinetype@BSTR@BSTR.htm


下面代码,添加一个虚线,然后绘制直线使用该线型


        //绘制一个虚线        
        //定义虚线数据据,"MyLineType"是线型名,"6,-8"是虚线的一个单位定义,6是实线长,-8是空格长。
        mxOcx.AddLinetype("MyLineType", "6,-10");
        //设置当前线型为"MyLineType"
        mxOcx.LineType = "MyLineType";
        //绘制一个虚线
        mxOcx.DrawLine(0, 30, 100, 30);
        mxOcx.UpdateDisplay();


下面代码,添加一个带文字的线型,如下:


        //  先添加一个线型中使用的文字样式        
        mxOcx.AddTextStyle1("MyLineTypeTextStyle", "txt.shx", "hztxt.shx", 1);
        //增加一个带有形的线型
        mxOcx.AddLinetypeEx("MyLineType3", "(12.7,(\"T=MxDraw\",\"S=2.54\",\"L=-5.08\",\"R=0.0\",\"X=-2.54\",\"Y=-1.27\"),-10.08)", "MyLineTypeTextStyle");
        // 设置当前绘图函数使用的线型
        mxOcx.LineType = "MyLineType3";
        mxOcx.LineWidth = 0;
        //绘制一个带宽度的红色点划线。
        mxOcx.DrawLine(300, 120, 600, 120);
        mxOcx.LineWidth = 4;
        //绘制一个带宽度红色点划斜线
        mxOcx.DrawLine(300, 220, 600, 220);
        //更新视区显示
        mxOcx.UpdateDisplay();


运行效果如下:


lt.png


B. 得到图上所有线型


下面C#代码,取到数据库的线型表,然后遍历表中所有线型记录对象,并得到线型名输出


        var database = mxOcx.GetDatabase();
        //返回数据库中的线型表对象
        var linetypeTable = database.GetLinetypeTable();
        //创建遍历器
        var iter = linetypeTable.NewIterator();
        if (iter == null)
            return;
        var sRet = null;
        //移动当前遍历器位置
        for (; !iter.Done(); iter.Step(true, false))
        {
            //返回遍历器当前位置的线型样式
            var lineType = iter.GetRecord();
            //得到文字样式名
            sRet = sRet + ',' + lineType.Name;
        }
        alert(sRet);


C.  修对象的线型


下面代码,让用户在图上选择一个对象,然后新增加一个线型,再把对象的线型改成新增加的线型。


        var ent = mxOcx.GetEntity("\n 选择实体对象:");
        if (ent == null)
        {
            return;
        }
        mxOcx.AddLinetype("MyLineType", "6,-10");
        
        // 设置实体线型。
        ent.LineType = "MyLineType";
        alert("已经修改线型");
        mxOcx.UpdateDisplay();
实体

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


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


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


class.png


类继承关系详细 PDF格式图:http://www.mxcad.net:2080/class.pdf


实体在线演示例子:点击此处在线演示


A. 实体ID和句柄 


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


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


            // 让用户在图上选择一个对象。            
            var ent = mxOcx.GetEntity("选择实体");
            if (ent == null)
                return;
            // 得到对象id;
            var id = ent.ObjectID;
            // 得到对象句柄
            var sHandle = ent.handle;
            
            alert(id);
            alert(sHandle);


通过 id得到对象,js代码如下:


            var obj = mxOcx.ObjectIdToObject(id);
            // 或
            // 创建一个当前应用实体对象。
            //得到当前数据库对象
            var database = mxOcx.GetDatabase();
            var obj = database.ObjectIdToObject(id);


通过 Handle得到对象,js代码如下:


            var obj = mxOcx.HandleToObject(sHandle);
            // 或
            // 创建一个当前应用实体对象。
            var database = mxOcx.GetDatabase();
            var obj = database.HandleToObject(sHandle);


B. 实体的类型信息


调用ObjectName函数得到对象的类型名,有了类型名就能判断实体具体是一个什么对象,调用Dxf0函数,得到对象的DXF组码的类型名,这个和AutoCAD中的DXF组码是一样,比如直线的类型名为:McDbLine,DXF0组码值: LINE,DXF0组码值可以用来构造集时的类型过滤。


如下js代码,


                // 让用户在图上选择一个对象。                
                var ent = mxOcx.GetEntity("选择实体");
                if (ent == null)
                    return;
                // 得到Dxf0的值。
                var sDxfType = ent.Dxf0;
                alert(sDxfType);
                if (ent.ObjectName == "McDbLine")
                {
                    // ent是一个直线。
                    var line = ent;
                    // 得到直线开始点。
                    var pt1 = line.StartPoint;
                    alert(pt1.x);
                    alert(pt1.y);
                
                    // 得到直线结束点.
                    var pt2 = line.EndPoint;
                    alert(pt2.x);
                    alert(pt2.y);
                }
                /*
                 else if(...)
                 {
                 // 其它类型.
                 }*/


C. 可见实体属性


图上可见实体的主要属性,有线型,图层,文字样式,颜色,是否可见,显示顺序,详细参见:http://www.mxdraw.com/help/!!MEMBERTYPE_Properties_IMxDrawEntity.htm


我们可以提取,和修改这些属性,如下图:


prop.png


修改Visible属性,可让实体是否可见,比如:


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


比如修改对象颜色:


如js代码:


        // -------------------------------------------------------------------------
        // Summary:
        //         改变实体颜色
        // Parameters:
        //         id            -    实体的id.
        //         iR,  iG,iB    -   实体的颜色
        // Returns:
        //         成功返回true
        // -------------------------------------------------------------------------
        function ChangeColor( id, iR, iG, iB)
        {
            
            var id = mxOcx.DrawLine(200, 0, 300, 100);
         // 由id得到实体对象.
         var ent = mxOcx.ObjectIdToObject(id);
         if (ent == null)
         return false;
        
         var color = mxOcx.NewComObject("IMxDrawMcCmColor");
         color.SetRGB(255,0,0);
        
         // 设置实体颜色。
         ent.TrueColor = color;
         return true;
            
        
        }


注意:由于COM对象的特性,不能这样直接修改颜色,是不起作用,例如下:


ent.TrueColor.SetRGB(iR, iG, iB);


MxDrawModifyTheColor: 用来批量修改图上所有对象的颜色,详细参见:http://www.mxdraw.com/help/IMxDrawModifyTheColor.htm,可以在打印图纸前,用该接口把图纸所有颜色设黑白色,这样打印出来更清晰。


比如下面js代码,把所有实体颜色修改成灰色:


    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

打开保存图纸

我们控件提供一些打开,保存图纸的函数,下面详细说明一下:


A.  在软件启动时,自动打开图纸


调用控件函数:OpenDwgFile,详细说明参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__OpenDwgFile@BSTR.htm


该函数支持打开dxf,dwg,dwf,png,jpg,bmp,mxg文件


比如js语言:


首先响应控件初始化完成事件,在控件初化完成后,调用OpenDwgFile打开图纸


增加用户自定义事件发生事件响应函数:


document.getElementById("MxDrawXCtrl").ImplementCustomEvent = CustomEvent;


然后在该事件函数中,加入打开文件代码:


function CustomEvent(sEventName)
{
    if(sEventName == "MxDrawXInitComplete")
    {
        // 控件加载完成.

     mxOcx.OpenDwgFile("D:\\MyBlock.dwg");    


    }

}


B. 打开网络路径图纸


使用控件 OpenWebDwgFile函数,打开一个http://开头网络图纸。


比如:


mxOcx.OpenWebDwgFile("http://www.mxcad.net:2080/test.dwg");


C. 把DWG图纸当着背景图打开


使用控件 OpenBackgroundFile函数,详细:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__OpenBackgroundFile@BSTR@VARIANT_BOOL@LONG@VARIANT_BOOL@VARIANT_BOOL.htm


该函数把dwg图纸变灰显示,图纸不能选中编辑。


D.二制流数据中加载图形


使用控件 ReadBinStream函数,可以加载二进制流形式的DWG图纸。


例如js:


    //服务器后台代码,返回前台二进制流数据.
    public JsonResult change()
    {
     FileStream fileStream = new FileStream(Server.MapPath(fileName), FileMode.Open, FileAccess.Read, FileShare.Read);
     BinaryReader binaryReader = new BinaryReader(fileStream);
     byte[] mybyte = binaryReader.ReadBytes((int)fileStream.Length);     return Json(mybyte, JsonRequestBehavior.AllowGet);
    }    
    // 前台客服端代码:
    function Bytes2Str(arr) {

     var str = "";     for (var i = 0; i < arr.length; i++) {

         var tmp = arr[i].toString(16);         if (tmp.length == 1) {

             tmp = "0" + tmp;

         }

         str += tmp;

     }     return str;

   }
    function InitMxDrawX()
 {
     var mxOcx = document.getElementById("MxDrawXCtrl");     if (mxOcx) {     if (!mxOcx.IsIniting()) {
         clearInterval(mxtime);
    
             $.ajax({
                 url: '@Href("~/Home/change")',
                 success: function (text) {
                     
                     alert(typeof (text));

                    var str = Bytes2Str(text);

                    mxOcx.NewFile();
                     mxOcx.ReadBinStream(str, "", "16777215");
                 },
                 error: function () {
                     alert("失败");

                 }
             });         //mxOcx.OpenWebDwgFile("http://192.168.0.13/DWG/后沟.dwg");
     }
     }
 }
 mxtime = setInterval(InitMxDrawX, 100);


E. 最快方式 加载图纸


DWG图纸中有很多看不见的数据,控件打开文件时,可以设置那些内容不让加载,来提高打开文件速度。


比如, 设置控件的Iniset属性的值 READCONTENT=132440最快方式打开图纸, 132440就一个位运算出来的数值,每个二进位代表是需要加那些内容,


js设置如下:


kuaisujiazai.png


每个二进制位代表含义:


enum ReadContent
{
kReadAllDefault = 0xFFF9FFFF,//0xFFFDFFFF=~kFastRelease & ~kReadProxyEntGet
kReadAllProxyEntGet = 0xFFFDFFFF,//0xFFFDFFFF=~kFastRelease
kReadNull       = 0x0,// 下面数据都不读取
kReadExData= 0x1,
kReadHandle= 0x2,
kReadBlockRefPreviewIcon= 0x4,
kReadBlockLayoutName= 0x8,
kNamedObjectsDictionary= 0x10,// 是否读对象字典,如果不读,字典下所有数据都不会读取.
kReadGroupDict              = 0x20,// 是否读取组字典
kReadLayoutDict             = 0x40,
kReadMlineStyleDict         = 0x80,
kReadImageDict= 0x100,
kReadXrecord= 0x200,
kReadDrawOrder= 0x400,
kReadxData= 0x800,
kReadExRecord               = 0x1000,
kReadExternalReference      = 0x2000,
kReadCustomEntity           = 0x4000,// 是否读取自定义实体,如果该为项为真,则自动让kReadHandle值也为真,因为自定义实体需要名柄支持.
kReComputeDimBlock          = 0x8000,// 是否重新生成标注块 。
kReadUserDictionary         = 0x10000,// 读取命名字典下的用户字典.
kFastRelease                = 0x20000,
kReadProxyEntGet            = 0x40000,// 是否读取代理实体的entget.
kFastRead=  kReadBlockLayoutName|kNamedObjectsDictionary|kReadLayoutDict|kReadImageDict|kFastRelease|Mcad::kReadDrawOrder
};


JS代码,最快的速加载图纸,图纸内部看不见的数据,不加载:


        var param = mxOcx.NewResbuf();
        param.AddString("http://www.mxcad.net:2080/test.dwg");
        param.AddLong(132440);
        mxOcx.CallEx("Mx_OpenDwgEx", param);


F. 打开有密码的DWG函数


调用我们的自定义打开文件函数,Mx_OpenDwgEx,该函数可以输入DWG文件密码,和控制那些内容加载,详细参考:


http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_OpenDwgEx@IN_CString@IN_LONG@IN_CString.htm


比如打文件,传入密码,js代码:


        var param = mxOcx.NewResbuf();
        param.AddString("D:hhhh.dwg");
        param.AddLong(0);
        // dwg文件密码
        param.AddString("password");
        mxOcx.CallEx("Mx_OpenDwgEx", param);


G. 直接修改属性DwgFilePath打开DWG文件


如下图设置,在界面启动,自动打开D:\\MyBlock.dwg:


EZU(JL`UY[@DCX$G_R{QCVE.png


H. 清空当前打开内容


调用控件NewFile函数,清空所有内容,比如js


mxOcx.NewFile();


I. 图纸打开完成事件


控件打开图纸完成后,会触发该事件,用户可以在该事件里面做一些加载图纸后的一些工作。


MxDrawXEvents::OpenFileComplete,详细参考:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawXEvents__OpenFileComplete.htm


如下图,添加事件响应,js:


function CustomEvent(sEventName)
{
    if(sEventName == "OpenFileComplete")
    {
        // 控件打开一个文件完成后会调用该事件

        alert("打开图纸完成");

    }


}


J.  保存图纸


调用控件SaveDwgFile保存DWG,详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__SaveDwgFile@BSTR.htm


该函数可以传不同的扩展名,然保存不同类型的文件,它支持保存dxf,dwf,mxg,pdf等文件格式


如下保存111.dwg:


mxOcx.SaveDwgFile("d:\\111.dwg");


调用扩展函数Mx_SetDefaultDwgVersion设置保存函数默认保存的dwg文件版本


如设置成默认保存为CAD2007文件格式的文件:


mxOcx.CallLongParam1("Mx_SetDefaultDwgVersion", 31);


函数的详细帮助如下图:


s1.png


K.  保存DWG文件到服务器上


调用控件的SaveDwgToURL函数,把DWG文件提交到服务器上保存,详细说明:


http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__SaveDwgToURL@BSTR@BSTR@BSTR@BSTR.htm


该函数会把当前图纸保存到一个临时文件中,然后模拟一个文件表单提交给服务器。


例如:


    if (!MxDrawXCtrl_Obj.SaveDwgToURL("http://127.0.0.1.", "/Save.aspx", "ComponentName", "6046")) {
        var ret = MxDrawXCtrl_Obj.Call("Mx_GetLastError","");
        alert(ret.AtString(0));
    }
    else {
        alert("成功");
    }


L. 保存pdf


调用控件ExprotPdf函数,把当前图纸保存为pdf文件,详细说明:


http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__ExprotPdf@BSTR@DOUBLE@DOUBLE@BSTR@VARIANT_BOOL.htm


J. 保存JPG


调用控件SaveJpgFile函数,把当前图纸保存为jpg文件,详细说明:


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


调用控件DrawToJpg函数,把当前显示的指定区域内的图形输出到jpg文件,详细说明:


http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__DrawToJpg@BSTR@DOUBLE@DOUBLE@DOUBLE@DOUBLE@LONG@LONG@LONG.htm


调用控件自定义函数:Mx_WriteJpgToURL,把控前图形保存为jpg文件,并当着一个文件表单提交给服务器,详细说明:


http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_WriteJpgToURL@IN_LPCTSTR@IN_LPCTSTR@IN_LPCTSTR@IN_LPCTSTR@OUT_CString_@IN_LPCTSTR@IN_int@IN_int@IN_COLORREF_@IN_long@IN_double@IN_double@IN_double@IN_do.htm

比较

全图比较

怎么比较两个CAD图纸文件修改前后的不同部分呢?在工程图纸设计中,我们更多情况下可能需要对同一张工程图的前后修改部分进行对比,以确定工程图纸的改动部分及追溯原因,本教程演示了几种常见的比较方法。点击此处在线演示


实现图纸比较功能,首先将两个控件放入网页中,js代码如下:


<p align="center">

  <object classid="clsid:74A777F8-7A8F-4e7c-AF47-7074828086E2" id="MxDrawXCtrl1"  codebase="http://www.mxdraw.com/MxDrawX52.CAB#version=7.0.0.1" width=48% height=85% align="left">
    <param name="_Version" value="65536">
    <param name="_ExtentX" value="24262">
    <param name="_ExtentY" value="16219">
    <param name="_StockProps" value="0">
    <param name="IsRuningAtIE" value="1">
    <param name="EnablePrintCmd" value="1">
    <param name="ShowStatusBar" value="1">
    <param name="ShowMenuBar" value="1">
    <param name="ShowToolBars"  value="1">
    <param name="ShowCommandWindow" value="1">
    <param name="ShowModelBar" value="1">
    <param name="Iniset" value="AutoActive=N,LoadMrx=PropertyEditor">

    <param name="ToolBarFiles" value="MxDraw-ToolBar.mxt,MxDraw-ToolBar-DrawParam.mxt,MxDraw-ToolBar-Draw.mxt,MxDraw-ToolBar-Edit.mxt">
    <SPAN STYLE="color:red">不能装载CAD控件。请确认你可以连接网络或者检查浏览器的选项中安全设置。<a href="http://www.mxdraw.com/MxDrawX52.msi">http://www.mxdraw.com/MxDrawX52.msi 安载CAD控件</a></SPAN>
  </object>
  <object classid="clsid:74A777F8-7A8F-4e7c-AF47-7074828086E2" id="MxDrawXCtrl2"  codebase="http://www.mxdraw.com/MxDrawX52.CAB#version=7.0.0.1"width=48% height=85% align="right">
    <param name="_Version" value="65536">
    <param name="_ExtentX" value="24262">
    <param name="_ExtentY" value="16219">
    <param name="_StockProps" value="0">
    <param name="IsRuningAtIE" value="1">
    <param name="EnablePrintCmd" value="1">
    <param name="ShowStatusBar" value="1">
    <param name="ShowMenuBar" value="1">
    <param name="ShowToolBars"  value="1">
    <param name="ShowCommandWindow" value="1">
    <param name="ShowModelBar" value="1">
    <param name="Iniset" value="AutoActive=N,LoadMrx=PropertyEditor">

    <param name="ToolBarFiles" value="MxDraw-ToolBar.mxt,MxDraw-ToolBar-DrawParam.mxt,MxDraw-ToolBar-Draw.mxt,MxDraw-ToolBar-Edit.mxt">
    <SPAN STYLE="color:red">不能装载CAD控件。请确认你可以连接网络或者检查浏览器的选项中安全设置。<a href="http://www.mxdraw.com/MxDrawX52.msi">http://www.mxdraw.com/MxDrawX52.msi 安载CAD控件</a></SPAN>
  </object>


首先通过id得到两个控件,返回控件的数据库对象,把两个控件里面不同的内容标记出来,具体实现js代码如下:


function AllCompare() {
    var ocx1 = document.getElementById("MxDrawXCtrl1");
    var ocx2 = document.getElementById("MxDrawXCtrl2");

    var database1 = ocx1.GetDatabase();
    var database2 = ocx2.GetDatabase();

    var filter = ocx1.NewResbuf();
    var compare1 = ocx1.NewComObject("IMxDrawCompare");
    //开始比较
    //参数一为比较时使用的原始文件 参数二为修改后的,新的文件 参数三为过滤条件
    compare1.Do(database1, database2, filter);
    //返回比较后,被修改的曲线id
    var aryDifferent1 = compare1.GetCurveIdsOfTheDifferent();
    //把修改的地方,标记出来
    //参数一为缩放比例
    //参数二为当前图纸,是新修改的图纸,该变量为true,那么在原图不能找到的对象,为新增加对象
    compare1.DrawFlag(1.0,false);
    // 反过来比较一下,用来确定,那些对象是新增加的。
    var compare2 = ocx1.NewComObject("IMxDrawCompare");

    compare2.Do(database2, database1, filter);

    var aryDifferent2 = compare2.GetCurveIdsOfTheDifferent();

    compare2.DrawFlag(1.0,true);

    var iErase = 0;
    var iModify = 0;
    var iAdd = 0;

    for (var i = 0;i < aryDifferent1.Count; i++)
    {
        //返回链表中的指定位置的对象id
        var lId = aryDifferent1.AtObjectId(i);
        //返回比较后,被修改的曲线的位置。用于图上标记被修改的对象
        if(compare1.GetIsErase(lId))
        {
            iErase = iErase + 1;
        }
        else
        {
            iModify = iModify +1;
        }
    }
    for(var i = 0; i < aryDifferent2.Count;i++)
    {
        var lId = aryDifferent2.AtObjectId(i);
        if(compare2.GetIsErase(lId))
        {
            iAdd = iAdd + 1;
        }
    }

    var modfColor = ocx1.NewComObject("IMxDrawModifyTheColor");
    modfColor.Do(ocx1.GetDatabase(),3289650);
    //把指定实体颜色
    modfColor.DoEntity(aryDifferent1,255);

    alert(iModify + "对象修改," + iErase + "对象删除," + iAdd + "对象被增加");
}


网页中演示效果如下,用户可以比教在两个控件里面的图纸内容。


@4UK2@HF[TVR]5%S2G6Z(KA.png

选择范围比较

首先通过id得到两个控件,返回控件的数据库对象,把两个控件里面不同的内容标记出来,具体实现js代码如下:


function DoImpCompare(points, filter) {

    var ocx1 = document.getElementById("MxDrawXCtrl1");
    var ocx2 = document.getElementById("MxDrawXCtrl2");

    var database1 = ocx1.GetDatabase();
    var database2 = ocx2.GetDatabase();

    var compare1 = ocx1.NewComObject("IMxDrawCompare");
    compare1.Bound = points;

    compare1.Do(database1, database2, filter);

    var aryDifferent1 = compare1.GetCurveIdsOfTheDifferent();

    compare1.DrawFlag(1.0, false);
    // 反过来比较一下,用来确定,那些对象是新增加的。
    var compare2 = ocx1.NewComObject("IMxDrawCompare");
    compare2.Bound = points;
    compare2.Do(database2, database1, filter);

    var aryDifferent2 = compare2.GetCurveIdsOfTheDifferent();
    
    compare2.DrawFlag(1.0, true);
    
    var iErase = 0;
    var iModify = 0;
    var iAdd = 0;
    for (var i = 0; i < aryDifferent1.Count; i++) {
        var lId = aryDifferent1.AtObjectId(i);
        if (compare1.GetIsErase(lId)) {
            iErase = iErase + 1;
        }
        else {
            iModify = iModify + 1;
        }
    }
    for (var i = 0; i < aryDifferent2.Count; i++) {
        var lId = aryDifferent2.AtObjectId(i);
        if (compare2.GetIsErase(lId)) {
            iAdd = iAdd + 1;
        }
    }
    alert(iModify + "对象修改," + iErase + "对象删除," + iAdd + "对象被增加");
}


用户可以选取范围内的图纸作比较,具体实现js代码如下:


function BoundCompare() {

    var ocx1  = document.getElementById("MxDrawXCtrl1");
    var getPt = ocx1.NewComObject("IMxDrawUiPrPoint");
    getPt.message = "点取第一点";
    if(getPt.go() != 1)
        return;
    var frstPt = getPt.value();
    var getCorner = ocx1.NewUtility();
    var secondPt =  getCorner.GetCorner(frstPt,"点取第二点:");
    if(secondPt == null)
        return;
    var points = ocx1.NewComObject("IMxDrawPoints");
    points.Add2(frstPt);
    points.Add2(secondPt);
    var filter = ocx1.NewResbuf();
    DoImpCompare( points, filter);
}


网页中演示效果如下,用户可以比教在两个控件里面的图纸内容。


@4UK2@HF[TVR]5%S2G6Z(KA.png

选择圆形范围比较

通过圆形范围把两个控件里面不同的内容标记出来,首先需要动态画一个圆,具体实现js代码如下:


  function DoDynWorldDrawFun(dX, dY, pWorldDraw, pData) {
    var sGuid = pData.Guid;
    var ocx1 = document.getElementById("MxDrawXCtrl1");
    ocx1.SetEventRet(0);
    if (sGuid == "DrawCircle") {
        var pt1 = pData.GetPoint("pt1");
        if (pt1 == null)
            return;
        var pt2 = ocx1.NewPoint();
        pt2.x = dX;
        pt2.y = dY;
        var dR = pt1.DistanceTo(pt2);
        pWorldDraw.DrawCircle(pt1.x, pt1.y, dR);
    }

}


用户可以选取圆形范围内的图纸作比较,具体实现js代码如下:


function CircleCompare() {
    var mxOcx  = document.getElementById("MxDrawXCtrl1");
    var getPt1 = mxOcx.NewComObject("IMxDrawUiPrPoint");
    getPt1.message = "指定圆心";
    if (getPt1.go() != 1) {
        return;
    }
    var getPt2 = mxOcx.NewComObject("IMxDrawUiPrPoint");
    getPt2.message = "指定圆上一点";
    getPt2.basePoint = getPt1.value();
    var spDrawData = getPt2.InitUserDraw("DrawCircle");
    spDrawData.SetPoint("pt1", getPt1.value());
    getPt2.setUseBasePt(true);
    if (getPt2.go() != 1) {
        return;
    }
    var cen = getPt1.value();
    var pt2 = getPt2.value();
    var dR = cen.DistanceTo(pt2);
    var circle = mxOcx.NewEntity("IMxDrawCircle");
    circle.Center = cen;
    circle.Radius = dR;
    var points = circle.GetSamplePoints(0.1);

    if (points.Count < 3) {
        alert("圆太小");
    }
    var filter = mxOcx.NewResbuf();
    DoImpCompare(points, filter);
}


网页中演示效果如下,用户可以比教在两个控件里面的图纸内容。


@4UK2@HF[TVR]5%S2G6Z(KA.png