二次开发CAD 下载本文

1 eb1.restype=0;//实体类型 2 strcpy(sbuf1,”CIRCLE”);

3 eb1.resval.rstring=sbuf1;//实体为CIRCLE 4 eb1.rbnext=&eb2;

5 eb2.restype=-3;//扩展数据 6 eb2.rbnext=&eb3; 7 eb3.restype=1001;

8 strcpy(sbuf2,”APPNAME”);

9 eb3.resval.rstring=sbuf2;//APPNAME应用程序 10 eb3.rbnext=NULL;

11 //选择注册到APPNAME应用程序中的圆的扩展数据 12 acedSSGet(“X”,NULL,NULL,&eb1,ssname1);

如果不止一个应用程序名包含在表中,则acedSSGet()在选择集中所包含实体,必须对所有指定的应用程序都有扩展数据。比如,下面的程序选择带有注册到“APP1”和“APP2”中的扩展数据的圆。 1 eb1.restype=0;//实体类型 2 strcpy(sbuf1,”CIRCLE”); 3 eb1.resval.rstring=sbuf1;//圆 4 eb1.rbnext=&eb2; 5

6 eb2.restype=-3;//扩展数据 7 eb2.rbnext=&eb3; 8 eb3.restype=1001; 9 strcpy(sbuf2,”APP1”);

10 eb2.resval.restring=sbuf2;//应用程序APP1 11 eb2.rbnext=&eb4;

12 eb4.restype=1001;//扩展数据 13 strcpy(sbuf3,”APP2”);

14 eb4.resval.rstring=sbuf3;//应用程序APP2 15 eb4.rbnext=NULL;

16 //选择注册应用程序APP1和APP2的圆扩展数据 17 acedSSGet(“X”,NULL,NULL,&eb1,ssname1);

下面的程序与上面的作用相同。 1 eb1.restype=0;

2 strcpy(sbuf1,”CIRCLE”); 3 eb1.resval.rstring=sbuf1; 4 eb1.rbnext=&eb2; 5

6 eb2.restype=-3; 7 eb2.rbnext=&eb3; 8 eb3.restype=1001;

9 strcpy(sbuf2,”APP[12]”);//”APP[12]” 10 eb3.resval.rstring=sbuf2;

11 eb3.rbnext=NULL;

12 //选择注册到APP1和APP2的圆的扩展数据 13 acedSSGet(“X”,NULL,NULL,&eb1,ssname1); 关系检测

除非用户另外指定,在一个筛选表中的每一项与实体之间,有一个隐含的等量(equals)检测,对于数字量(整数、实数值、点和向量),通过在筛选表中包括关系操作符,用户可指定另外一些关系,关系操作符当做一个特殊的组(即-4组)传递,其值是一个在筛选表中将被应用于下一组检测的字符串。

下面的程序可以挑选半径大于等于2。0的圆: 1 eb3.restype=40;//半径 2 eb3.resval.rreal=2.0; 3 eb3.rbnext=NULL; 4

5 eb2.restype=-4;//筛选操作 6 strcpy(sbuf1,”>=”); 7 eb2.resval.rstring=&eb3; 8

9 eb1.restype=0;//实体类型 10 strcpy(sbuf2,”CIRCLE”); 11 eb1.resval.rstring=sbuf2;//圆 12 eb1.rbnext=&eb2; 13

14 //选择半径大于等于2。0的圆

15 acedSSGet(“X”,NULL,NULL,&eb1,ssname1); 条件筛选

条件操作符也可由-4组指定,但它们必须是配对的。下面的的程序用来挑选半径为1。0的圆,并且在“ABC”层上的所有直线: 1 struct resbuf* prb;prb = acutBuildList(-4, \,-4, \, RTDXF0, \, 40, 1.0, -4, \, -4, \, RTDXF0, \, 8, \, -4, \, -4, \, 0); 2 acedSSGet(\, NULL, NULL, prb, ssname1);

条件操作符不是大小写敏感的,可以使用小写形式。

用于检测扩展数据的条件表达式只能包含-3组。为了选择带有寄存于“APP1”和“APP2”其中之一的扩展数据的所有圆,可以用以下程序来实现:

1 prb = acutBuildList(-4, \, -3, \, -3, \, -4, \, 0); 2 acedSSGet(\, NULL, NULL, prb, ssname1);

////////////

RTNONE = return None 返回为空 RTNORM = return NORMal 返回正常 结果类型码

结果类型码 说 明

RTNONE 无结果值 RTREAL 实数(浮点数)值 RTPOINT 二维点(X和Y;Z==0.0) RTSHORT 短整数(16位) RTANG 角度 RTSTR 字符串 RTENAME 实体名 RTPICKS 选择集名 RTORINT 方位

RT3DPOINT 三维点(X、Y和Z) RTLONG 长整数(32位) RTVOID 无值(空)符号 RTLB 表开头(用于嵌套表) RTLE 表结尾(用于嵌套表) RTDOTE 点(用于点对) RTT AutoLISP真值(true) RTNIL AutoLISP无值(nil) RTDXF0 DXF组码零(仅用于acutBuildList()函数) RTNORM 用户输入值有效,正常

RTERROR 函数调用失败 RTCAN 用户按了Esc键 RTREJ AutoCAD拒绝无效请求 RTFAIL AutoLISP通信失败 RTKWORD 用户输入键盘或任意文字

并非所有的ADSRX库函数都返回这些状态码,某些库函数直接返回数值。我们最感兴趣的返回类型码是RTNORM、RTERROR、RTCAN和RTKWORD。

AutoCAD中ObjectARX C++常用的方法

3.8 在AutoCAD中选择实体

1. ads_name[在AutoCAD 2000中仍为此名]、acdbNameSet()[ads_name_set()]、acdbNameEqual()[ads_name_equal()]、acdbNameClear()[ads_name_clear()]、acdbNameNil()[ads_name_nil()]

在ADS、ADSRX或ObjectARX中,选择实体的方法没有变化,但在ObjectARX 2000中改变了一些函数名(其他函数名没有改变,对于第6章讨论的数据类型和DCL对话框也基本是这样的)。

我们介绍一种新的数据类型:ads_name。这种类型数据用来保存成功选择实体的结果。通常,选择实体是为

了用户能获得并修改实体特性。这里是老式的ADS和现代的API ObjectARX完全不同的地方。在讨论ADS和ObjectARX在获得实体数据方面的差别之前,先来看一看ads_name的定义。

ads_name数据类型是一个具有两个long型元素的数组,因此不能使用赋值操作符使一个ads_name对象等于另一个ads_name对象。这种情形类似于前文的ads_point数据类型。正如ads_point数据类型一样,

AutoCAD提供了一个名为acdbNameSet()的宏,用来使一个ads_name对象等于另一个ads_name对象。

ADS/ADSRX提供了许多宏来处理ads_name对象。要使一个ads_name对象等于另一个ads_name对象,可以用acdbNameSet()宏。

要判断两个ads_name对象是否相等,可以用acdbNameEqual()宏。

要把一个空值(NULL)赋给一个ads_name对象,可以用acdbNameClear()宏。要测试一个ads_name对象的值是否有效,可以用acdbNameNil()

宏。

2. acedEntSel()[ads_entsel()]、acdbEntGet()[ads_entget()]、acdbEntMod()[ads_entmod()]、acdbEntUpd()[ads_entupd()]

请牢记选择集也是ads_name对象(我知道这可能引起不小的混淆)。我们很快就会讨论选择集。前文谈到ADS和ObjectARX在获得和更改实体数据的方法上是完全不同的,在后面的章节中我们将讨论ObjectARX的方法。

在ADSRX中,使用acdbEntGet()函数获得实体数据,使用acdbEntMod()和acdbEntUpd()函数修改和更新实体。下面是这些函数的定义: 用acedEntSel()函数选择的实体将和ads_name对象相关联。在详细讨论acedEntSel()函数之前,先要谈一下acdbEntGet()、acdbEntMod()和acdbEntUpd()函数。

acdbEntGet()函数返回一个结果缓冲区的单链表。使用resbuf对象的rbnext字段可以遍历和检测结果缓冲区链表。若rb为一个resbuf结果缓冲区,则语法如下:

之后还可以改变某些结果缓冲区中的值,当最终完成后调用acdbEntMod()函数修改实体的内部数据。正如所见,该函数要求一个 resbuf 对象。如果正在处理一个如块或多段线一样的复杂对象,可以使用

acdbEntUpd()函数来观察由各个acdbEntMod()函数调用所做的修改效果。从本质上讲,使用ADSRX就是处理结果缓冲区链表。ObjectARX的方法与此是完全不同的,且差别巨大。对于有大量旧数据的用户,由于有ADSRX,这些函数在ObjectARX中仍然可以使用(Autodesk公司的人把ADS放进了ObjectARX)。由于本书是讨论ObjectARX,因此,关于acdbEntGet()、acdbEntMod()和acdbEntUpd()函数的讨论就到此为止。

现在回到acedEntSel()函数,因为该函数在ObjectARX中仍然得到广泛应用。再一次把acedEntSel()函数的定义说明如下:

acedEntSel()函数暂停运行等待用户输入,并在entres中返回实体名,在ptres中返回选择实体使用的点。参数str指定acedEntSel()函数暂停前显示的字符串。参数str是可选的,如果是NULL,AutoCAD显示缺省提示“Select objects:”。当用户指定一个复杂实体响应acedEntSel()函数时,则返回多段线或块的标题。如果acedEntSel()函数调用成功,则返回RTNORM,失败则返回RTERROR,如果用户取消(按Esc

键)则返回RTCAN。acedEntSel()函数可以和acedInitGet()函数结合使用,如前面实例代码段所示。acedEntSel()函数在ObjectARX中是怎样使用的呢?AutoCAD把图形作为数据库来处理。在每个打开的AutoCAD图形中的每一个实体都有一个唯一的AutoCAD数据库对象ID与之关联。通过其对象的ID号我们可以打开AutoCAD实体,确定要处理什么类型的实体。然后我们可以使用实体的获得和设置方法(函数)来操作实体。一旦有了一个ads_name对象,我们就能得到关联的AutoCAD数据库对象ID(数据类型为AcDbObjectId)。

下面就是得到一个AutoCAD数据库对象ID的函数定义:ads_name对象是使用acedEntSel()函数选择实体成功的结果。

下面是一段使用acedEntSel()函数的ObjectARX代码:该函数用pEnt返回AcDbEntity指针,注意是怎样用acedEntSel()函数选择AutoCAD实体的。