arx & c++ 开发技巧讲解

以下是做CAD二次開發一年多來的一些讀書筆記﹕
节选于《AutoCAD高级开发技术:ARX编程及应用》
跟大家分享
一.图块设计技术:
在AutoCAD数据库中,以各图块实际上市存储在块表记录里的实体集合。每个图块从一格AcDbBlockBegin对象开始,紧接着是一个或多个AcDbEntity对象,最后以AcDbBolckEnd对象结束,按其所属关系得层次结构分为三层:第一层为块表,是属于数据库管理的根对象;第二层为块表记录,是属于块表管理的对象;第三层为组成图块的实体对象,是属于块表记录管理的基本对象。因而,在AutoCAD数据库中,定义图块的第一个过程式向块表中加入一条新的块表记录,然后将组成图块的实体对象写入该块表记录中。
1.AutoCAD数据库中图块的引用
在AutoCAD系统中插入已定义的块并不是将块中所有实体复制到数据库中,而是通过块引用机制向块表记录增加一个AcDbBlockReference类引用对象。所谓的块引用实际上是用户用Insert命令或ARX引用程序向AutoCAD数据库中插入的图块。在ARX应用程序中,利用定义的AcDbBlockReference类实例及相应的成员函数可以设置插入块的有关特性,如插入点、旋转角以及XYZ方向的比例系数等。插入不带属性的简单图块的编程技术相对比较简单,做法如下:
A.创建一个指向AcDbBlockReference类对象实例的指针。
B.调用该类的成员函数setBlockTableRecord()设置引用图块的ID号。
C.调用该类的成员函数setPosition(),setRotation()和setScaleFactors()分别设置块引用的插入点、旋转角和XYZ方向的比例系数等。
D.打开当前图形模型空间的块表,利用getBlockTable()函数获得指向当前图形的块表指针。
E.调用appendAcDbEntity()函数将块引用加入当前数据库模型空间块表记录中。
2. 属性块的引用:
在块定义中的附加属性信息必须通过调用AcDbBlockReference类的成员函数appendAttribute()才能加入到块引用中。
定义属性块时,属性实质上是附加于构成图块的某一实体上的一个或多个非图形信息。因此,在插入属性时必须检索出属性块定义时的所有附加信息,然后将其附加于块引用的相应实体上,这就需要遍历块中的全部实体。
通过属性块的ID号打开其块表记录,从而获得指向块表记录的指针。程序代码为:
AcDbBlockTableRecord *pBlockDef; //定义指向块表记录的指针
acdbOpenObject(pBlockDef,blockid,AcDb::kForRead); //获得指向块表记录的指针
参数blockid为属性的ID号,然后,定义一个用于遍历块表记录的浏览器,获得指向块表记录的浏览器指针,如:
AcDbBlockTableIterator *pIterator; //定义指向块表记录浏览器的指针
pBlockDef->newIterator(pIterator); //获得指向块表记录的浏览器指针
成员函数newIterator()用于创建块表记录的浏览器对象,参数pIterator为指向块表记录的浏览器指针。在此基础上建立一个循环结构,用于遍历图块中的全部实体,得到指向某一实体的指针,其结构如下:
AcDbEntity *pEnt; //定义指向实体的指针
AcDbAttributeDefinition *pAttdef; //定义指向属性定义的指针
For (pIterator->state(); !pterator->done(); pIterator->step())
{
pIterator->getEntity(pEnt,AcDb::kForRead); //得到指向实体的指针
pAttdef = AcDbAttributeDefinition::cast(pEnt); //得到指向属性定义的指针
//处理属性插入的代码
……
pEnt->close(); //关闭尸体对象
}
实体属性的插入代码的执行机理如下:
1). 创建AcDbAttribute类对象,获得指向该对象的指针。
如: AcDbAttribute *pAtt = new AcDbAttribute;
2). 设置新建的AcDbAttribute类对象的属性值及特性,如属性位置,字高,旋转角度,属性文本等.
3) . 调用appendAttribute()函数将属性附加于pBlkRef指向的块引用中。
如: pBlkRef->appendAttribute(attid,pAtt);
其中,pBlkRef为指向块引用的指针,pAtt为前面创建的AcDbAttribute类对象的指针。
3. AutoCAD数据库中图块的检索
对于AutoCAD数据库来说,图块的检索主要包括用户定义的有名块和图形中已插入的块引用两个方面。
1). 先介绍当前图形数据库中块的检索技术:
用ads_tblnext()函数可以得到当前图形的数据库中表示块定义得链表,将改链表存储于结果缓冲区类型的变量中,利用结果缓冲区中的联合体成员就可以获得块名、基点等信息。重复调用ads_tblnext()函数将遍历整个数据库链表中的所有块表记录,从而得到全部已定义的图块信息。
2) . 用户定义数据库中块的检索:
对于在ARX应用中定义的其他数据库,只能用ARX库的函数才能检索出该数据库中所定义的图块,程序的主要设计技术如下:
A. 利用AcDbBlockTable类的成员函数newIterator()创建块表浏览器.
如: pBTable->newiterator(pBIterator);
pBTable为AcDbBlockTable类指针;pBIterator为AcDbBlockTableIterator类块表浏览器指针.
B. 利用循环结构和块表浏览器遍历块表。
C.利用AcDbBlockTableIterator类成员函数getRecord()获得块表记录。
如:pIterator->getRecord(pBTRecord,AcDb::kForRead);
D. 利用块表记录类的成员函数getName()得到块名。
4. 块中实体的检索:
在检索任意数据库中的图块时,主要是利用块表浏览器遍历块表,从而获得图块名。而在获得块名的前提下,利用ARX库提供的块表记录浏览器遍历块表记录中的所有实体,从而实现对块中实体的检索。方法为:
A.用一种合适的方式获得图块名,得到指向该图快的块表记录。
B.生成块表记录浏览器。
C.遍历块中的多有实体,得到检索结果。
现在知道图框的名字是A3,要求遍历图框中属性:pBlkRef为AcDbBlockReference实体。
AcDbObjectIterator *pBlkRefAttItr=pBlkRef->attributeIterator();
for (pBlkRefAttItr->start(); !pBlkRefAttItr->done();pBlkRefAttItr->step())
{
AcDbObjectId attObjId;
attObjId = pBlkRefAttItr->objectId();
AcDbAttribute *pAtt = NULL;
Acad::ErrorStatus es = acdbOpenObject(pAtt, attObjId, AcDb::kForRead);
if (es != Acad::eOk) 
{
acutPrintf("\nFailed to open attribute");
delete pBlkRefAttItr;
continue;
}
if (strcmp(pAtt->tag(),"TITLE:") == 0)
{
CString title = pAtt->textString();
if (strcmp(title,"PROGRESS(D)") == 0)
{ //操作
}
else if (strcmp(title,"PROGRESS(P)") == 0)
{
//操作
}
}
pAtt->close();
}
二.容器对象:符号表的操作和使用技术
符号表的操作主要分为向符号表中加入一条符号表记录,符号表记录的检索和符号表记录中对象的处理等,每一种操作都是通过相应的符号表类提供的成员函数来实现的。
1.层表的操作和使用技术:
A. 创建新层:
1). 以写的方式调用getSymbolTable()函数打开当前数据库的层表,获得指向该表的指针。
2) 调用构造函数AcDbLayerTableRecord()创建层表建立对象。
3) 设置层名。
4) 设置层的有关属性。
5) 调用add()函数将层表记录加入到层表中。
6) 关闭层表和层表记录。
2. 层的属性设置和查询函数
层的属性包括:颜色、冻结状态、锁定状态、开关状态、在新视口中层的冻结状态和线型,下面列出的设置和查询函数均是AcDbLayerTableRecord类的成员函数。
A.设置颜色:setColor(const AcCmColor color);
B.设置冻结状态:setIsFrozen(bool frozen);
如果参数frozen为true表层冻结;frozen为false表层冻结。
C.设置锁定状态:setIsLocked(bool locked);
如果参数locked为true表层锁定;locked为false表层解锁。
D.设置开关状态:setIsOff(bool off);
如果参数off为true表层关闭;off为false表层打开。
E.设置在新视口中层的冻结状态:setVPDFLT(bool frozen);
如果参数frozen为true表在新视口中层将冻结;frozen为false表在新视口中层解冻。
F.设置线型:setLinetypeObjectId(AcDbObjectId id);
在调用构造函数AcDbLayerTableRecord()创建层表记录时,上述参数的缺省值为:
Color为7(white),isFrozen为false,isLocked为false,isoff为false,VPDFLT为false,线型的ID号为NULL。
3. 层属性的修改和查询实例的基本方法:
A.以读方式打开层表,获得指向层表的指针。
B.调用层表类的成员函数getAt(),以写的方式获得指定层名的层表记录指针。
C.调用属性设置函数修改属性或调用属性查询函数获得属性;
4. 数据库中层的检索的基本方法:
A.利用AcDbLayerTable类的成员函数newIterator()创建层表浏览器。
B.利用循环结构和块表浏览器遍历块表。
C.利用AcDbLayerTableIterator类的成员函数getRecord()获得块表记录。
D.利用成员函数getName()得到层名。
5. 设置图形数据库的当前层:
调用AcDbDatabase类的成员函数setClayer()设置图形数据库的当前层,其函数原型为:
Acad::ErrorStatus setClayer(AcDbObjectId objId);
函数的参数为层表的ID号。获得层表记录ID号的主要方法有:
1) 将新建的层表记录加入层表时,用下面的形式调用add()函数:
AcDbLayerTable::add(AcDbObjectId & layerID,AcDbLayerTableRecord *pRecord);
在关闭层表和层表记录的代码后,加入“acdbCurDwg()->setClayer(layerID);”设置当前层。
2) 若层已经存在,则可利用获得指定符号表ID号的形式调用getAt()函数:
AcDbLayerTable:: getAt(const char* entryName, AcDbObjectId& recordId, bool getErasedRecord = false) const;
然后调用加入“acdbCurDwg()->setClayer(layerID);”设置当前层。
6. 定义字体样式
AutoCAD数据库的字体样式是字体样式中的一条记录,其缺省的字体样式名为STANDARD,字体文件名为txt.shx。用STYLE定义一个新的字体样式包括建立样式名,选择字体文件和确定字体效果三步操作。用户新定义的字体样式是作为一条字体样式表记录加入字体样式表中。
A.以写方式调用getTextStyleTable()哈数打开当前图形数据库的字体样式表,获得指向该表的指针。
B.调用构造函数AcDbTextStyleRecord()创建字体样式表记录对象。
C.设置字体样式名和字体文件名。
D.设置字体的效果,包括倒置、反向、垂直、宽度比例和倾斜角的设置。
E.调用add()函数将字体样式表记录加入字体样式表中。
F.关闭字体样式表和字体样式表记录。
7. 尺寸标注样式和尺寸变量
尺寸标注样式是AutoCAD数据库中尺寸标注样式表的一条记录,其缺省的尺寸标注样式名为STANDSRD,该样式由系统自动建立。尺寸变量是确定组成尺寸标注线、尺寸界线、尺寸文字以及箭头的样式、大小和它们之间相对位置等的变量。
对标注样式名为STANDARD的尺寸变量进行修改,首先要打开当前图形数据库的尺寸标注样式表,并调用getAt()函数获得指向尺寸标注样式表记录STANDARD的指针,然后调用AcDbDimStyleTableRecord类成员函数设置尺寸变量。
建立新的尺寸标注样式与建立图层和定义字体样式基本相同。,其步骤为:
A.以写的方式调用getDimStyleTable()函数打开当前图形数据库的尺寸标注样式表,获得指向该表的指针.
B.调用构造函数AcDbDimStyleRecord()创建尺寸标注样式表记录对象。
C.设置尺寸标注样式名。
D.调用AcDbDimStyleRecord类的成员函数设置尺寸变量。
E.调用add()函数将尺寸标注样式表记录加入到尺寸标注样式中。
F.关闭尺寸标注样式表和尺寸标注样式表记录。
8. 符号表记录的建立:
9种符号表作为AutoCAD数据库中的根对象和容器,包含的下级对象为相应的符号表记录。符号表本身只能由AutoCAD系统建立而不能由应用程序创建,应用程序只能创建符号表记录。如块表中的块表记录,层表中的层表记录,字体样式表中的字体样式记录等,虽然各种具体的符号表记录名称不同,但建立的基本方法相同。归纳主要以下几步:
A.以写的方式调用get##BASE_NAME##Table()函数打开数据库的## BASE_NAME##表,获得指向该表的指针。
B.调用构造函数AcDb##BASE_NAME##Record()创建相应的符号表记录对象。
C.调用setName()函数设置相应的符号表记录名。
D.調用符号记录表的成员函数设置其属性。
E.调用add()函数将所创建立的符号表记录加入其符号表。
F.关闭符号表和符号表记录。
9. 符号表记录的编辑:
对于符号表的符号表记录,可以通过符号表记录类的成员函数对其属性进行编辑,如更改字体样式表的字型文件、文字的字高和宽度比例等。符号表记录的编辑实现技术可以分三步:
A.以读的方式调用get##BASE_NAME##Table()函数打开数据库的##BASE_NAME##表,获得指向该表的指针。
B.调用符号表类的成员函数getAt()获得符号表记录指针。
C.调用相应的符号表记录成员函数修改其属性。
10.符号表记录的查询:
符号表记录的查询主要利用符号表浏览器和循环结构实现,步骤如下:
A.利用AcDb##BASE_NAME##Table类的成员函数newIterator()创建符号表浏览器。
B.利用循环结构和块表浏览器遍历块表。
C.利用AcDb##BASE_NAME##TableIterator类的成员函数getRecord()获得符号表记录。
D.利用成员函数getName()得到符号表记录名。
例子:
AcDb##BASE_NAME##Table *pTable;
acdbHostApplicationServices()->workingDatabase()
->get##BASE_NAME##Table (pTable,AcDb::kForRead);
AcDb##BASE_NAME##TableIterator *pIter;
pTable ->newIterator(pIter);
pTable ->close();
AcDb##BASE_NAME##TableRecord *pRecord;
for (pIter ->start();!pIter ->done();pIter ->step())
{
pIter ->getRecord(pRecord,AcDb::kForWrite);
char *m_name;
pRecord ->getName(m_name);
//添加相应的操作
free(m_Layername);
pRecord ->close();
}
delete pLayerIter;



三.对象字典的操作
对象字典和符号表均是AutoCAD图形数据库中的容器对象。在9种符号表中,每一种符号表只能用来存储特定的对象,如块表用来存储块表记录,层表用来存储层表记录等,而对象字典却不受此限制,它可以存储任何类型的对象,包括其他对象字典、数据库对象和应用程序创建的对象。因此,所谓的对象字典实际上是一种通用的对象容器。
1. 组字典的操作使用技术:
组是实体等数据库对象的有序集合,是组字典的成员。从层次关系来看,组是管理其所包含对象的容器,而组字典则是管理组对象的容器。一个组实际上可以认为是一个选择集,但又不同于一般的选择集,它是組字典中一個有名的常驻对象。当组中的一个实体被删除时,该实体自动地从组中移出;当恢复被删除的是天时,该实体又自动地加入到该组中。使用组可以简化操作,容易实现对一批对象的颜色、层和线型等属性的统一修改。
组字典中可以包含若干个组,每个组通过其组名来区分。
A.直接从数据库中获得指向组字典的指针:
Acad::ErrorStatus getGroupDictionary(AcDbDictionary*& pDict,AcDb::OpenMode mode);
B.从对象字典中获得组字典的指针:
由于组字典是对象字典中的一个名为“ACAD_GROUP”的成员,因此先获得数据库中指向对象字典的指针,然后调用getAt()函数获得指向组字典的指针。
AcDbDictionary *pNamedObj,*pGroupDict;
acdbCurDwg()->getNamedObjectsDictionary(pNamedObj,AcDb::kForRead);
pNamedObj->getAt("ACAD_GROUP",(AcDbObject *&)pGroupDict,AcDb::kForWrite);
2. 将组加入组字典中:
setAt(const char* srchKey,AcDbObject *newValue,AcDbObjectId& retObjId);
各参数的意义为:srchKey为组名,用字符串表示;newValue为加入到组字典中的新组的指针;retObjId为函数返回的已加入组字典中的组对象的ID号。如果在组字典中已有同名的组存在,则将被新加入的组取代。调用该函数时,必须先创建组对象,将指向组对象的指针和定义的组名作为输入参数,并获得加入组字典中的组对象ID号。
其中组对象为AcDbGroup类。具体的操作查相关的类函数即可!
3.建立多线样式:
多线是指多条互相平行的直线,各条线的线型、颜色和他们之间的间距等属性可互不相同。多条的这些属性由多线样式定义。定义一个多线样式的步骤为:
A.通过getMLStyleDictionary()函数获得指向图形数据库中的多线样式字典的指针。
B.用多线样式的构造函数AcDbMlineStyle()创建多线样式对象。
C.利用AcDbDictionary类的成员函数setAt()将所建立的多线样式加入字典中。
D.调用有关函数设置多线样式的属性,如设置多次按名称、元素特性和多线特性等。
4.用户对象字典的操作和使用技术:
在AutoCAD数据库中,对象字典是字典类数据库对象的总称。按其层次关系可分为两类,一是由AutoCAD数据库直接管理的第一层对象字典;二是由第一层对象字典管理的第二层对象字典。为了便于区别,我们把第一层对象字典成为有名对象字典,用户在应用程序中定义的字典成为用户字典。前面提到的组字典、多线样式字典和用户对象字典均属于第二层对象字典,其中组字典和多线字典是系统自动生成的对象字典。
对象字典的第三层为字典中的对象。如:组诗组字典中的对象,多线样式是多线样式字典中的对象,在用户对象字典中可以包含任何类型的对象,如实体对象、自定义对象和数据库对象等。有名对象字典中的各用户对象字典之间,通过其字名来表示;用户字典中的对象利用其对象名来区分。
4.1 用户对象字典的定义和字典对象的查询:
在有名对象字典中定义一个用户对象字典的实质是创建一个AcDbDictionary类对象,并将其加入有名对象字典中,其步骤为:第一,调用AcDbDatabase类的成员函数getNameObjectDictionary()得到有名对象字典的地址(即指针);第二,定义新的用户对象字典并加入有名对象字典中。
例子:
AcDbDictionary *pNamedObj; //定义有名对象字典
acdbCurDwg()->getNamedObjectsDictionary(pNamedObj,AcDb::kForWrite);
AcDbDictionary *pDict = new AcDbDictionary; //定义用户对象字典
AcDbObjectId eid;
pNamedObj->setAt("Name",pDict,eid);
而在用户字典中对象查询的第一步是建立字典浏览器遍历对象字典:
AcDbDictionaryIterator *pDictIter = pDict->newIterator();
字典对象查询的第二步是得到指向对象的指针:
pDictIter->getObject(pObj,AcDb::kForRead);
在获得对象指针的前提下,可以利用对象的成员函数进行查询、检索和编辑等操作。
另外,用户字典中的对象名可以用AcDbDictionaryIterator类的成员函数name()获得。而该对象名表示的对象类名可以用“pObj->isA()->name()”形式获得。
需要注意的是:将块表记录中的实体对象加入用户字典,并不是将实体复制到字典中,而是在字典中存储其对象的指针。因此,当块表记录中的实体被删除后,在字典中相应的对象名和指针也不再存在。
4.2 用户对象字典:扩展记录的加入和查询。
扩展记录属于AcDbxrecord类的对象,可用来定义任何类型的数据。扩展记录的数据项采用结果缓冲区链表的形式定义,每一项由DXF组码和相应的组值构成。扩展记录是一个在应用程序中定义的数据库对象,属于有名对象字典的下级对象或某一对象的扩展字典和其他扩展记录的下级对象。
在ARX中创建扩展记录的主要步骤如下:
1.获得数据库中指向有名对象字典的指针。
2.建立一个新的用户脆响字典,并加入有名对象字典中。
3.创建新的扩展记录,并加入用户对象字典中,如:
AcDbXrecord *pXrec = new AcDbXrecord;
pDict->setAt("XREC1", pXrec, xrecObjId);
4.用ads_buildlist()函数构造由扩展记录数据项组成的缓冲区链表,其一般形式为:
ads_buildlist(<组码1>,<组值1>,<组码2>,<组值2>,……,0);
5. 调用AcDbXrecord的成员函数setFromRbChain()设置扩展记录所指向的链表指针。
三.ARX应用程序中的尺寸标注技术
1. 尺寸对象的组成和常用的尺寸标注类:
尺寸标注也是AutoCAD数据库中块表记录中的一种对象。一个完整的尺寸对象由尺寸标注线,尺寸界线,尺寸箭头和尺寸文字构成。
在AutoCAD数据库中,AcDbDimension类为尺寸标注的基类,其派生类主要有对齐标注(AcDbAlignedDimension),两线定角标注(AcDb2LineAngularDimension),三点定角标注(AcDb3PointAngularDimension),直径标注(AcDbDiametricDimension),半径标注(AcDbRadialDimension),坐标尺寸标注(AcDbOrdinateDimension),定角标注(AcDbRotatedDimension)等。
尺寸标注类是实体类(AcDbEntity)的派生类,其主要成员函数的原型为:
1.设置尺寸文字位置:
Acad::ErrorStatus setTextPosition(const AcGePoint3d& unnamed);
2. 设置尺寸标注样式:
Acad::ErrorStatus setDimensionStyle(AcDbObjectId unnamed);
3. 设置尺寸文字:
Acad::ErrorStatus setDimensionText(const char* unnamed);
4. 设置尺寸文字旋转角度:
Acad::ErrorStatus setTextRotation(double unnamed);
5. 查询尺寸文字:
Char* dimensionText()const;
6. 查询尺寸文字位置:
AcGePoint3d textPosition()const;
7. 查询尺寸文字旋转角度
double textRotation()const;
2.尺寸标注的鼠标拖动技术:
实现尺寸标注线和尺寸文字为字的鼠标拖动的关键是跟踪鼠标的移动,并根据鼠标的位置动态显示尺寸标注。用ads_grread()憾事跟踪鼠标的移动,其函数原型为:
Int ads_grread(int track,int *type,struct resbuf *result);
参数track为控制位,其值为1则将鼠标的坐标存入result中;type表示输入的种类,如按鼠标左键,则type=3;
尺寸标注的鼠标拖动原理为:
首先,设置ads_grread()函数控制位track=1,在循环结构中用ads_grread()函数追踪鼠标的移动,获得当前鼠标位置的x,y坐标。用ads_grread(track,&type,&result)形式调用,则点的x和y坐标值可分别用result.resval.rpoint[X]和result.resval.rpoint[Y]形式获得。其次,以写方式打开尺寸标注对象,用获得的X,Y坐标设置尺寸标注线和尺寸位置,并关闭对象。循环执行,实现尺寸步标注对象的拖动。如果按鼠标左键拾取一个点,则type=3,结束循环。
例子:公差标注设置函数:
void SetDimtpAndDimtm(double tp,double tm)
{
AcDbDimStyleTable *pDimStyleTbl;
acdbCurDwg()->getDimStyleTable(pDimStyleTbl,AcDb::kForRead);
AcDbDimStyleTableRecord *pDimStyleTblRcd;
pDimStyleTbl->getAt("",pDimStyleTblRcd,AcDb::kForWrite);
if (fabs(tp) == fabs(tm))
{
pDimStyleTblRcd->setDimtfac(1.0)
}
else pDimStyleTblRcd->setDimtfac(0.5);
if (tp == 0.0 && tm == 0.0)
{
pDimStyleTblRcd->setDimtol(0);
}
else
{
pDimStyleTblRcd->setDimtp(tp);
pDimStyleTblRcd->setDimtol(1);
pDimStyleTblRcd->setDimtm(tm);
}
pDimStyleTblRcd->close();
pDimStyleTbl->close();
}
3.图案填充函数介绍:
图案填充函数AcDbHatCh也是实体立体(AcDbEntity)的派生类,与尺寸标注类似,图案填充也是 AutoCAD数据库中块表记录中的一种对象。
生成图案填充对象的步骤为:
A.调用图案填充类的构造函数创建AcDbHatch类对象。
B.调用AcDbHatch类的成员函数设置填充图案的法向矢量,关联,标高,缩放比例,填充图案,填充方式和填充边界等属性。
C.调用evaluateHatch()显示填充图案。
D.将AcDbHatch类对象写入当前图形数据库的块表记录中。
4.ARX应用程序中视图管理技术和应用:
视图和视口是AutoCAD环境中图形显示中经常涉及到的基本概念。图形屏幕上用于显示图形的一个矩形区域称为视口,可以把整个图形屏幕作为一个视口,也可以把整个视图屏幕设置成多个视口。当前视口中显示的复杂图形按不同的窗口大小设置,并以视图名为表示在图形数据库中保存。在需要时,显示指定视图以满足对图形编辑和浏览的需要。
视图的管理包括视图的定义,显示,属性设置和查询等功能。在AutoCAD的交互环境中,用户可以使用VIEW命令对视图进行命名,保存,恢复和删除。在ARX应用程序中,主要是通过使图表类及视图表记录类的成员函数实现视图的管理功能。
视图类作为视图表(AcDbViewTable)中的一条视图记录(AcDbViewTableRecord)保存在AutoCAD数据库中。把当前视口中指定窗口每得图形定义为一个新的视图的操作等价于向数据库中添加一个AcDbViewTableRecord类对象。其实现步骤为:
A.调用视图标记录类的构造函数创建AcDbViewTableRecord类对象;
B.调用AcDbViewTableRecord类的成员函数设置视图名,视图中心点,视图高度和宽度等属性;
C.获得当前图形数据库中的视图表指针,将AcDbViewTableRecord类对象添加到数据库中。
视图的查询首先要获得当前图形数据库中指定视图师表记录的指针,然后调用相应的成员函数得到该视图的属性。
四.ARX中的实体造型技术和应用
三维造型包括线框模型、表面模型和实体模型三种形式,其中三维实体具有体的特征。能夠較全面地反映形体的物理特征。在机械CAD中,利用实体造型技术用户不仅可以通过并、交、差布尔运算生成所需的机械零部件模型,而且还能够对形体进行剖切成剖视图以进行体积、重心和惯性矩等物性计算和分析,进而在实体模型的基础上生成NC代码,在ARX应用程序中,并不是直接使用AutoCAD系统本身提供的有关实体造型和编辑命令,而是通过直接生成数据库对象及调用AcDb3dSolid类的成员函数来进行实体造型。
1.基本三维实体生成方法:
在AutoCAD数据库中,三维实体属于AcDb3dSolid类对象,该类是AcDbEntity类的派生类。
对于一个具体的几何实体,即ACIS对象来说,AcDb3dSolid实体是一个容器和接口。
通过AcDb3dSolid类的成员函数可以生成各种基本的三维实体以及实现实体的布尔运算。生成三维实体的基本步骤为:
A.调用AcDb3dSolid类的构造函数创建一个容器对象:
如:AcDb3dSolid *p3dObj = new AcDb3dSolid;
B.调用AcDb3dSolid类的成员函数创建基本三维实体对象。其一般形式为:
指向AcDb3dSolid类对象的指针-〉创建基本三维实体对象成员函数。
B.将AcDb3dSolid类对象写入当前图形数据库的块表记录中,其代码设计方法与二维对象的添加完全相同。

ARX程序的消息响应:
ARX程序实质上是一动态库,它直接与AutoCAD进行对话,即AutoCAD发送各种消息给ARX程序,ARX程序负责对各种消息作出相应的处理。
kInitAppMsg:
当ARX程序被加载时发送该消息,用以建立AutoCAD和应用程序之间的对话。
kUnloadAppMsg:
当ARX程序卸载时(不论是用户卸载应用程序,还是由AutoCAD终止退出)发送该消息,关闭文件以及执行必要的清理工作。
kOleUnloadAppMsg:
发送该消息确定应用程序是否可以卸载,即该应用程序的ActiveX对象或接口是否被其他应用程序所引用。
kLoadDwgMsg:
当打开一幅图形时发送消息,此时AutoCAD的图形编辑环境进行了初始化,并且,应用程序可以调用ARX的全局函数,而acedCommand()函数除外。
kUnLoadDwgMsg:
当用户退出当前的图形编辑时发送该消息。
下面的代码将实例生成由 某一图层上所有的实体组成的选择集:
struct resbuf *plb;
char sbuf[32];
ads_name ss1;
plb = acutNewRb(8) //图层DXF组码是8
strcpy(sbuf,”PARTS”); //图层名为PARTS
plb->resval.rstring = sbuf;
plb->rbnext = NULL;
acedSSGet(“X”,NULL,NULL,plb,ss1);
acutRelRb(plb); //don’t forget
下面的例子是选择“PARTS”图层上的所有圆,这是一个利用acutBuildList()函数构造结果缓冲区表后再传给acedSSGet()函数的实例:
ads_name ss1;
struct resbuf *rb1;
rb1 = acutBuildList(RTDXFO,”CIRCLE”,8,”PARTS”,RTNONE);
acedSSGet(“X”,NULL,NULL,rb1,ss1);
acutRelRb(plb); //don’t forget

你可能感兴趣的:(arx & c++ 开发技巧讲解)