nullObjectARX TrainingObjectARX Training华中科技大学CAD中心
武汉天喻软件有限责任公司
2010年2月
ObjectARX应用的介绍ObjectARX应用的介绍ObjectARX是一个仅在AutoCAD上进行二次开发的一套开发环境,通俗点讲就是一系列的API
ObjectARX的应用举例:
扩展AutoCAD功能
为各种工程
开发便利的工具
ObjectARX概述ObjectARX概述ARX——AutoCAD Runtime eXtension
DBX ——DataBase eXtension
ARX = .DLL + 2 exported functions
{ acrxEntryPoint & acrxGetApiVersion }AutoCAD.EXEARX AppsARX AppsObjectARX APIsObjectARX开发特点ObjectARX开发特点不同的ACAD版本用不同的开发包及开发环境
ACAD2000~ACAD2002 : VC++ 6.0
ACAD2004~ACAD2006 : VS.NET 2002
ACAD2007~ACAD2009 : VS.NET 2005
ACAD2010~ : VS.NET 2008
ACAD2007开始字符串采用UNICODE编码
ARX之间不能连续依赖
A.arx依赖B.arx, B.arx依赖C.dbx,则A.arx不能加载
与ACAD已有功能地位一致ObjectARX类库构成ObjectARX类库构成AcRx:用于帮定一个应用程序以及运行类的注册和识别。
AcEd:用于注册自定义命令和AutoCAD事件通告。
AcDb:AutoCAD图形数据库。
AcGi: 用于AutoCAD 的图形类。
AcGe:用于AutoCAD 的线型和几何对象通用类。
ADS: AutoCAD 的早期版本C语言函数库。
ObjectARX类结构ObjectARX类结构类图classmap.dwg
位置:\ObjectARX 2006\classmap用ObjectARX能做些什么?用ObjectARX能做些什么?访问、编辑和扩展AutoCAD图形数据库
和AutoCAD系统相互通信
使用MFC创建用户接口
支持多文档应用
创建自定义类和自定义实体
可以开发复杂的应用
和其他开发环境进行协作培训安排-1培训安排-1一、基础
AUTOCAD数据库结构及操作,ads_name-句柄-ID及转换,aced常用函数,WCS/UCS及转换,菜单/工具条/对话框制作
二、自定义对象
显示/存储/夹点/移动/拷贝/范围/list/捕捉点/炸开/相交点/sub事件
三、自定义对象生成与编缉
双击修改/Jig/属性页培训安排-2培训安排-2四、一些重要对象
字典/层/线型/字体样式
五、扩展数据
六、反应器
八、总结所需基础所需基础ACAD基本操作
C++
VC
MFC(界面)
COM(属性页等)
STL(提高效率)AutoCAD图形数据库概述AutoCAD图形数据库概述AutoCAD图形实际上是一系列存放在一个AcDbDatabase类型的对象中的AcDb对象。
一个dwg就是一个数据库
具备数据库的基本组织结构。
包括九个符号表和一个命名对象词典AutoCAD图形数据库结构AutoCAD图形数据库结构AcDbDatabase数据库
|------AcDb符号表
| |------块表(AcDbBlockTable)
| |------尺寸标注样式表(AcDbDimStyleTable)
| |------层表(AcDbLayerTable)
| |------线型表(AcDbLinetypeTable)
| |------已注册应用程序表(AcDbRegApptable)
| |------字体样式表(AcDbTextStyleTable)
| |------用户坐标系表(AcDbUCSTable)
| |------视口表(AcDbViewportTable)
| |------视图表(AcDbViewTable)
|-------命名对象词典
访问:AcDbDatabase::getSymbolTable向数据库中添加实体
向数据库中添加实体
Acad::ErrorStatus addEntityToModelSpace(AcDbEntity * pEnt, AcDbObjectId & EntId)
{
Acad::ErrorStatus eRet;
AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTable *pBlockTable;
eRet = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if ( eRet != Acad::eOk)
{
return eRet;
}
AcDbBlockTableRecord *pBlockTableRecord;
eRet = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
if ( eRet != Acad::eOk)
{
pBlockTable->close();
return eRet;
}
pBlockTable->close();
eRet = pBlockTableRecord->appendAcDbEntity(EntId, pEnt);
if ( eRet != Acad::eOk)
{
pBlockTableRecord->close();
return eRet;
}
pBlockTableRecord->close();
return Acad::eOk;
}怎样遍历AutoCAD图形数据库?怎样遍历AutoCAD图形数据库?void FindObjectId(AcDbObjectId & objId)
{
AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTable *pBlockTable;
pDb->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb:: kForRead);
pBlockTable->close();
AcDbBlockTableRecordIterator *pIter;
pBlockTableRecord- >newIterator(pIter); // Create an iterator
for (pIter->start(); !pIter->done(); pIter->step())
{
….........
AcDbEntity *pEntity;
if (pIter->getEntity(pEntity, AcDb::kForRead) != Acad::eOk) continue;
If(pEntity->isKindOf(AcDbCircle::desc()) objId = pEntity->ObjectId();
}
pBlockTableRecord- >close();
}怎样创建和使用已有的AutoCAD图形数据库?怎样创建和使用已有的AutoCAD图形数据库?要使用AcDbDatabase数据库,与使用其它数据库一样,首先要声明一个数据库对象。AcDbDatabase类的声明,调用类的构造函数:
AcDbDatabase ::AcDbDatabase(bool buildDefaultDrawing = true, bool noDocument = false);
其中,buildDefaultDrawing参数控制是否创建一个包括所有默认数据记录的数据库。
该参数的默认值为true,这样在AcDbDatabase数据库创建时,将在新建的数据库中包含一个AutoCAD图形数据库必须包含的基本数据要素,这些要素包括九个符号表及其初始记录(比如0层、STANDARD文字样式等),命名对象词典(组词典和多线样式词典)以及必要的系统变量设置。这样就可以向新建的数据库中添加各种实体和对象。如:AcDbDatabase *pDb= new AcDbDatabase(true);
若指定该参数为false,AutoCAD将创建一个完全空的AcDbDatabase数据库。这样的AcDbDatabase数据库不能直接向其中添加实体或对象,需读入一个图形文件来拓展该图形数据库,然后再逐步添加或修改数据库中的实体或对象。
读入图形数据库使用函数:AcadErrorStatus AcDbDatabase::readDwgFile(const char* fileName );
若要使用已有的图形,比如“test.dwg”文件,则使用下列代码:
AcDbDatabase *pDb= new AcDbDatabase(false);
pDb->readDwgFile(“test.dwg”);
AcDbDatabase构造函数的noDocument参数控制打开的数据库是否与当前文档关联,此参数用于“多文档处理”中。
注意:在这种情况下,AcDbdatabase()的参数必须指定为false(当然,0或者Adesk::kFalse都可以)。因为使用pDb->readDwgFile()函数时,pDb必须是一个完全空白的数据库,也就是说,哪怕使用了AcDbDatabase(false);新建数据库后,只要对数据库进行了操作,就不能再使用readDwgFile()函数,否则会导致严重的内存错误。数据库对象AcDbObject概述数据库对象AcDbObject概述每一个数据库对象具有以下三种表示方法:
句柄 —— AcDbHandle
对象id —— AcDbObjectId
指针 —— AcDbObect *三者之间的相互关系三者之间的相互关系 注意: Handle不变 ,ObjectId变化之间相互关系和转换之间相互关系和转换1. AcDbHandle -> AcDbObjectId
AcDbDatabase ::getAcDbObjectId(&AcDbObjectId ,FALSE, AcDbHandle );
2. AcDbObjectId -> AcDbHandle
AcDbHandle = AcDbObjectId::handle ();
3.AcDbObjectId -> AcDbObject *
acdbOpenObject(AcDbObject *&,AcDbObjectId,AcDb::OpenMode);
4.AcDbObject * -> AcDbHandle
AcDbHandle = AcDbObject::getAcDbHandle();
5.ads_name 和 AcDbObjcetId
一个ads_name 是 一个包含两个long型元素的数组
这个数组的第一个元素就是AcDbObjcetId
6. ads_name 和 AcDbObjcetId相互转换
acdbGetAdsName(ads_name, objId);
acdbGetObjectId(objId, ads_name);
怎样访问数据库对象?怎样访问数据库对象?打开对象的方法:
acdbOpenObject() 该函数为模板函数,能打开任意对象
acdbOpenAcDbObject()
acdbOpenAcDbEntity()
打开对象的模式:
AcDb::kForRead //只读
AcDb::kForWrite //可写
AcDb::kForNotify //
升级和降级访问:
AcDbObject::upgradeOpen(); //升级为写
AcDbObject::downgradeOpen(); //降级为读
删除对象
AcDbObject::erase()用事务方式访问用事务方式访问事务
AcTransaction * AcTransactionManager::startTransaction
AcTransactionManager::endTransaction()
AcTransactionManager::abortTransaction(),
virtual Acad::ErrorStatus getObject(AcDbObject*& obj, AcDbObjectId objectId, AcDb::OpenMode mode, bool openErasedObject = false)
对象访问限制对象访问限制如果一个对象被写打开,则在关闭前不能再被读打开或写打开
如果一个对象被读打开,则在关闭前不能再被写打开,但可被读打开(一个对象最多可同时被打开128次)对象类型识别
对象类型识别
desc():
a static member function that returns the class descriptor object of a particular (known) class.
cast():
a static member function that returns an object of the specified type, or NULL if the object is not of the required class (or a derived class).
isKindOf():
returns whether an object belongs to the specified class (or a derived class).
isA():
returns the class descriptor object of an object whose class is unknown.
AcRxClass
例如:
AcDbEntity* curEntity = somehowGetAndOpenAnEntity();
if (curEntity->isKindOf(AcDbEllipse::desc())) { }
If(curEntity->isA() == AcDbEllipse::desc()){ }
AcDbLine * pLine = AcDbLine ::cast(curEntity )AutoCAD里的交互AutoCAD里的交互AcEd 全局函数
String, number acquisition
acedGetInt used to get an integer value acedGetReal used to get a real value acedGetString used to get a string acedGetDist used to get the distance between two points
Point, angle acquisition
acedGetAngle used to get a angle value acedGetPoint used to pick a point acedGetCorner
Entity selection
acedEntSel used to select a single entity acedNEntSel used to select a single, nested entity acedNEntSelP used to select a single, nested entity acedSSGet used to select multiple entities
Others
acedGetKword used to get a key word acedInitGet used to initialize acedGetXXXX functions acedGetFileD used to retrieve file selection from a file dialog向ACAD发送命令向ACAD发送命令acedCommand:立即执行
acedCommand(RTSTR, "zoom", RTSTR, "e", 0);
sendStringToExecute:作为下一个命令执行
CString strCmd;
strCmd.Format("_HNBMReservedAreaModified %d %d ", (long)ReservedAreaHandle, nType);
acDocManager->sendStringToExecute(acDocManager->curDocument(), strCmd, false, true, false);
共同点:都不能执行有用户交互的命令
WCS,UCS,OCS(ECS)WCS,UCS,OCS(ECS)规则:数据库中对象保存的点坐标是WCS坐标(建议);而一些acedXX函数(如acedGetPoint,acedEntSel等)、list命令一般是UCS坐标。
WCS与UCS相互转换
//UCS坐标系
fromrb.restype = RTSHORT;
fromrb.resval.rint = 1;
//WCS坐标系
torb.restype = RTSHORT;
torb.resval.rint = 0;
acedTrans(pt_ucs,&fromrb,&torb,FALSE,resultPt);
acdbUcs2Wcs
acdbWcs2Ucs
AcDbEntity::getEcs
UCS常用函数及类UCS常用函数及类函数:Acad::ErrorStatus acedGetCurrentUCS(AcGeMatrix3d& mat);
(以下函数和类可看作符号表的操作模式)
函数:Acad::ErrorStatus getSymbolTable(AcDbUCSTable*& pTable,AcDb::OpenMode mode);
类:AcDbUCSTable
类:AcDbUCSTableRecord
ARX应用向导ARX应用向导应用向导:ObjectARX 2006的在\ObjectARX 2006\utils\ObjARXWiz
下。
功能:与MFC应用向导类似
产生工程
产生特定类及函数
ARX,DBX加载/卸载ARX,DBX加载/卸载加载
ap(appload)
arx
其它方式(lisp文件,注册表等)
卸载
ap
arxARX软件结构ARX软件结构加载:On_kInitAppMsg
卸载:On_kUnloadAppMsg
命令映射(arx2006或以上):
static void INTECAD_INTESelect(void)
{
}
ACED_ARXCOMMAND_ENTRY_AUTO(CINTECADApp, INTECAD, _INTESelect, INTESelect, ACRX_CMD_TRANSPARENT, NULL)
ARX & MFCARX & MFCObjectARX 完全支持MFC。
两个MFC基类 AdUi and AcUi。
注意:在调用资源时加上这句话 CAcModuleResourceOverride resOverride;
对话框对话框资源转换,多个ARX时可能需要
CAcModuleResourceOverride resOverride;
或
AfxSetResourceHandle (_hdllInstance) ;
AfxSetResourceHandle (acedGetAcadResourceInstance ()) ;
菜单与工具条菜单与工具条通过菜单文件
COM方式添加例1:基本操作例1:基本操作建立应用程序
建立命令
实现功能:选中一实体,然后输出其信息
例2:重复产生同半径的圆例2:重复产生同半径的圆对话框输入半径
用鼠标指定圆心数据库结构查看工具数据库结构查看工具ARXDBG工具的使用
位置:\ObjectARX 2006\samples\database\ARXDBG
文档:ArxDbg.doc本节结束本节结束下节将介绍自定义实体的内容自定义对象类自定义对象类一般从 AcDbObject 或AcDbEntity派生
AcDbObject:不须显示,如字典对象
AcDbEntity:可显示/操作的实体
从其他(如AcDbLine等实体类)派生:根据需要
自定义类可继续从另一个自定义继承,从而继承体系成树状结构
编写时遵守一定的规则
放在DBX工程中自定义类特点自定义类特点头文件
ACRX_DECLARE_MEMBERS
ACDB_REGISTER_OBJECT_ENTRY_AUTO
版本
CPP文件
ACRX_DXF_DEFINE_MEMBERS
AcDbProxyEntity::kNoOperation
assertReadEnabled ()与assertWriteEnabled () ;
读写控制
显示刷新
UNO/REDODBX加载/卸载DBX加载/卸载在ARX中调用
acrxLoadModule/acrxUnloadModule
ARX在使用DBX的LIB库时,可能会出现诸如:acrxGetApiVersion找不到或ARX加载失败的问
.解决方法:
在ARX和DBX工程中都增加def文件,文件内容如下:
EXPORTS
acrxEntryPoint PRIVATE
acrxGetApiVersion PRIVATE
自定义对象-读入/写出自定义对象-读入/写出作用
文件(DWG,DXF)读写
UNDO/REDO
CLONE
函数
virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);
virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;
AcDbDwgFilerAcDbDwgFiler类中常用函数
virtual Acad::ErrorStatus readInt32(Adesk::Int32*)
virtual Acad::ErrorStatus writeInt32(Adesk::Int32)
virtual Acad::ErrorStatus readString(char**)
virtual Acad::ErrorStatus writeString(const char*)
virtual Acad::ErrorStatus readPoint3d(AcGePoint3d*)
virtual Acad::ErrorStatus writePoint3d(const AcGePoint3d&)
virtual Acad::ErrorStatus readAcDbHandle(AcDbHandle*)
virtual Acad::ErrorStatus writeAcDbHandle(const AcDbHandle&)
virtual Acad::ErrorStatus readBytes(void *, Adesk::UInt32)
virtual Acad::ErrorStatus writeBytes(const void *, Adesk::UInt32)
读字符串
char *str=NULL;
pFiler->readString(&str);
m_strPanelType=str;
acutDelString(str);自定义对象-显示自定义对象-显示函数:
virtual Adesk::Boolean worldDraw( AcGiWorldDraw* mode);
virtual void viewportDraw(AcGiViewportDraw* mode);
区别
worldDraw函数用来生成跟视图无关的几何图形,它只生成一组几何图形,其他的因为视图的变化而导致的几何图形变化都由AutoCAD来自动调整,举个例子,你生成一个立方体,这个立方体从不同的角度看所看到的外形是不一样的,但是worldDraw只生成一个角度的几何图形,其他的都由AutoCAD来自动的调整了。
viewportDraw则不同,它可以根据不同的视图生成不同的几何图形,当你的视图改变的时候,它自动将几何图形调整到正确的状态。有时候这两个函数需要配合使用,例如,如果你画圆,那就可以用worldDraw,因为无论你怎么变换视图圆还是圆。但是如果你生成一些表示立体的几何图形有时候就需要借助于viewportDraw了,因为对于立体图形来说不同的视图看到的是不一样的。 举个例子来说明其区别就是worldDraw画出来的立体图形,你改变了角度(也算viewport改变)后看到的有可能就不是立体图形了,但是你用viewportDraw画出来的就不会出现这样的问题。
AcGiWorldDraw与AcGiViewportDrawAcGiWorldDraw与AcGiViewportDraw类似,但AcGiViewportDraw有视口相关的矩阵和方向函数
通过geometry得到绘图类AcGiWorldGeometry 的对象
通过subEntityTraits得到环境设置类AcGiSubEntityTraits 对象AcGiWorldGeometry与AcGiGeometryAcGiWorldGeometry与AcGiGeometrycircle
circularArc
Polyline(多段线)
polygon
text
pline(多义线,类似于AcDbPolyline)AcGiSubEntityTraitsAcGiSubEntityTraits常用函数
virtual void setColor(const Adesk::UInt16 color) = 0;
virtual void setTrueColor(const AcCmEntityColor& color) = 0;
virtual void setLayer(const AcDbObjectId layerId) = 0;
virtual void setLineType(const AcDbObjectId linetypeId) = 0;
virtual void setFillType(const AcGiFillType) = 0;
virtual void setLineWeight(const AcDb::LineWeight lw) = 0;
virtual void setLineTypeScale(double dScale = 1.0) = 0;
注意
一个自定义对象的不同部分可分属不同层
是否填充只针对circle,polygon等封闭图形
例1 自定义实体-读写/显示例1 自定义实体-读写/显示生成一等边三角形的自定义实体
中心
外接圆半径
方位角自定义对象-夹点自定义对象-夹点virtual Acad::ErrorStatus getGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const;
virtual Acad::ErrorStatus moveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset);
自定义对象-移动自定义对象-移动virtual Acad::ErrorStatus transformBy( const AcGeMatrix3d& xform);
自定义对象-拷贝自定义对象-拷贝virtual Acad::ErrorStatus deepClone(AcDbObject* pOwnerObject, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary = true) const;
virtual Acad::ErrorStatus wblockClone(AcRxObject* pOwnerObject, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary = true) const;
自定义对象-炸开自定义对象-炸开virtual Acad::ErrorStatus explode(AcDbVoidPtrArray& entitySet) const;自定义对象-捕捉点自定义对象-捕捉点virtual Acad::ErrorStatus getOsnapPoints( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const;
自定义对象-范围自定义对象-范围 virtual Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const;
自定义对象-list自定义对象-list作用:调试检查用.
virtual void list() const;
自定义对象-相交点自定义对象-相交点virtual Acad::ErrorStatus intersectWith(const AcDbEntity* pEnt,AcDb::Intersect intType,AcGePoint3dArray& points,int thisGsMarker = 0,int otherGsMarker = 0) const;自定义对象- sub事件自定义对象- sub事件 virtual Acad::ErrorStatus subErase(Adesk::Boolean erasing);
virtual Acad::ErrorStatus subOpen(AcDb::OpenMode mode);
virtual Acad::ErrorStatus subClose();理解拖动夹点与平移实体的工作方式理解拖动夹点与平移实体的工作方式在拖动夹点时,ACAD调用自定义对象重载的moveGripPointsAt函数。但这时你要注意:此时的this指针指向的自定义对象A并非数据库中待修改的对象B,A只是ACAD复制的一个用于操作的临时对象,它的所有持久性(即保存到文件中的)参数与B相同,非持久性参数保持构造函数时的值。A并没有被加入到数据库中,所以在moveGripPointsAt不能通过database()函数获取数据库指针;A中的参数没有累积性,即在moveGripPointsAt中更改了一个类成员变量m的值,下一次调用moveGripPointsAt时,m的值与B中m值相同,而不是修改过的值。
transformBy与moveGripPointsAt类似。本节结束本节结束下节将介绍自定义对象生成与编缉
双击修改
动态生成(Jig)
属性页实体的双击修改实体的双击修改在ARX工程中:从AcDbDoubleClickEdit派生并重载函数:
virtual void startEdit(AcDbEntity *pEnt, AcGePoint3d pt);
virtual void finishEdit(void);
在On_kInitAppMsg中:
if(!acrxDynamicLinker->loadModule(/*MSG0*/"ACDBLCLKEDITPE.ARX",Adesk::kFalse))
{
AfxMessageBox("'ACDBLCLKEDITPE.ARX' Load Failed");
}
// Initialize Double Click Editing
AcDbDoubleClickEdit::rxInit();
acrxBuildClassHierarchy();
TYTriangleDoubleClickEdit *pTriangleDoubleClickEdit=new TYTriangleDoubleClickEdit;
TYTriangle::desc()->addX(AcDbDoubleClickEdit::desc(),pTriangleDoubleClickEdit);
实体的双击修改实体的双击修改On_kUnloadAppMsg函数中:
TYTriangle::desc()->delX(AcDbDoubleClickEdit::desc());
startEdit函数
文档加锁
设置资源
显示对话框
修改实体
文档解锁例1:自定义实体的双击修改例1:自定义实体的双击修改可改:
外接圆半径
填充动态创建动态创建AcEdJig
virtual DragStatus sampler () ;
virtual Adesk::Boolean update () ;
virtual AcDbEntity *entity () const ;
DragStatus drag();nullAcEdJIg中的用户输入函数AcEdJIg中的用户输入函数 DragStatus acquireString(char *str);
DragStatus acquireAngle(double &ang);
DragStatus acquireAngle(double &ang, const AcGePoint3d& basePnt);
DragStatus acquireDist(double &dist);
DragStatus acquireDist(double &dist, const AcGePoint3d& basePnt);
DragStatus acquirePoint(AcGePoint3d&);
DragStatus acquirePoint(AcGePoint3d&, const AcGePoint3d&basePnt);
注意:不能使用acedXXX函数
AcEdJig:其它函数AcEdJig:其它函数const char* keywordList();
void setKeywordList(const char*);
const char* dispPrompt();
void setDispPrompt(const char*, ...);
AcEdJig::CursorType specialCursorType();
void setSpecialCursorType(CursorType);
AcEdJig::UserInputControls userInputControls();
void setUserInputControls(AcEdJig::UserInputControls);
例2:动态生成自定义实体例2:动态生成自定义实体用向导生成或手工书写
向导生成的AcEdJig派生类有错:
头文件中除去ACRX_DECLARE_MEMBERS
CPP文件中除去ACRX_CONS_DEFINE_MEMBERS练习练习自定义实体
具有N条边的多边形
画出多边形及外接圆
可输入边数N和外接圆半径
动态创建
在创建过程中显示图形
在创建过程中显示并可修改尺寸(选作)
双击修改属性页属性页优点:
可批量修改多个实体的属性
操作步骤少
与ACAD的已有操作更加一致
缺点:
实现有点复杂
用户操作习惯问题生成工程生成工程
ATL工程生成ATL类生成ATL类派生
接口
IDL
DBX中实体类中:
头文件:
static bool s_bHasClsid;
static CLSID s_clsid;
实现:
initCLSID()
getClassID属性名称及分组属性名称及分组GetDisplayName
GetCategoryName
ShowProperty预定义值预定义值GetPredefinedStrings
GetPredefinedValue显示对话框显示对话框MapPropertyToPage
IOPMPropertyDialog字典字典字典内可保存多个从AcDbObject派生的对象
可用于保存全局变量,选项设置null AcDbDictionary *pNameDict;
AcDbDictionary *pNameList;
pDb->getNamedObjectsDictionary(pNameDict,AcDb::kForWrite);
if (pNameDict->getAt("TYSOFTHNBMCAD_DICT",(AcDbObject*&)pNameList, AcDb::kForWrite) == Acad::eKeyNotFound)
{
pNameList = new AcDbDictionary;
AcDbObjectId DictId;
pNameDict->setAt("TYSOFTHNBMCAD_DICT", pNameList, DictId);
}
pNameDict->close();
///打开或创建控制信息对象
AcDbObjectId objId;
HNBMDictItem *pDictItem;
if((pNameList->getAt("TYSOFTHNBMCAD_DICT_ITEM", objId))
== Acad::eKeyNotFound)
{
pDictItem = new HNBMDictItem;
Acad::ErrorStatus err=pNameList->setAt("TYSOFTHNBMCAD_DICT_ITEM", pDictItem, objId);
if(err!=Acad::eOk)
{
acutPrintf("\nerror in set archinfo!");
delete pDictItem;
pNameList->close();
return;
}
pDictItem->close();
}
pNameList->close();
null AcDbDictionary *pNameDict;
AcDbDictionary *pNameList;
pDb->getNamedObjectsDictionary(pNameDict,AcDb::kForRead);
if (pNameDict->getAt("TYSOFTHNBMCAD_DICT",(AcDbObject*&)pNameList,
AcDb::kForRead) == Acad::eKeyNotFound)
{
pNameDict->close();
return NULL;
}
pNameDict->close();
AcDbObjectId objId;
HNBMDictItem *pDictItem;
if((pNameList->getAt("TYSOFTHNBMCAD_DICT_ITEM", objId))== Acad::eKeyNotFound)
{
pNameList->close();
return NULL;
}
pNameList->close();
if (acdbOpenObject((AcDbObject*&)pDictItem, objId,AcDb::kForRead) == Acad::eOk)
{
return pDictItem;
}
层层 AcDbLayerTable *pLayerTable;
es=pDB->getSymbolTable(pLayerTable, AcDb::kForWrite);
if(es!=Acad::eOk)
{
pLinetypeTable->close();
return;
}
if(!pLayerTable->has("木作线(RoomLine)"))
{
pLayerTableRecord =new AcDbLayerTableRecord;
pLayerTableRecord->setName("木作线(RoomLine)");
pLayerTableRecord->setIsFrozen(false);
pLayerTableRecord->setIsOff(false);
pLayerTableRecord->setIsLocked(false);
pLayerTableRecord->setVPDFLT(false);
color.setColorIndex(3);
pLayerTableRecord->setColor(color);
pLinetypeTable->getAt("Continuous", LinetypeId);
pLayerTableRecord->setLinetypeObjectId(LinetypeId);
pLayerTableRecord->setLineWeight(AcDb::kLnWtByLwDefault);
pLayerTable->add(pLayerTableRecord);
pLayerTableRecord->close();
}
pLayerTable->close();
线型线型 pDB->loadLineTypeFile("DASHED", "acad.lin");//虚线
pDB->loadLineTypeFile(“CENTER”, “acad.lin”);//中心线
AcDbLinetypeTable *pLinetypeTable=NULL;
Acad::ErrorStatus es=pDB->getSymbolTable(pLinetypeTable, AcDb::kForRead);
if(es!=Acad::eOk)
return;
AcDbLayerTable *pLayerTable;
es=pDB->getSymbolTable(pLayerTable, AcDb::kForRead);
if(es!=Acad::eOk)
{
pLinetypeTable->close();
return;
}
AcDbObjectId LinetypeId;
pLinetypeTable->getAt("CENTER", LinetypeId);
pLineTypeTable->close();
文字样式文字样式 AcDbTextStyleTable *pTextStyleTable=NULL;
Acad::ErrorStatus es=pDB->getSymbolTable(pTextStyleTable, AcDb::kForWrite);
if(es==Acad::eOk)
{
if(!pTextStyleTable->has("宋体-35"))
{
AcDbTextStyleTableRecord *pTextStyleTableRecord=new AcDbTextStyleTableRecord;
pTextStyleTableRecord->setName("宋体-35");
pTextStyleTableRecord->setFont("宋体", FALSE, FALSE, GB2312_CHARSET, DEFAULT_PITCH|FF_ROMAN);
pTextStyleTableRecord->setTextSize(3.5);
pTextStyleTableRecord->setXScale(0.8);
pTextStyleTable->add(pTextStyleTableRecord);
pTextStyleTableRecord->close();
}
if(!pTextStyleTable->has("HZ-35"))
{
AcDbTextStyleTableRecord *pTextStyleTableRecord=new AcDbTextStyleTableRecord;
pTextStyleTableRecord->setName("HZ-35");
pTextStyleTableRecord->setFileName("txt.shx");
pTextStyleTableRecord->setBigFontFileName("hztxt.shx");
pTextStyleTableRecord->setTextSize(3.5);
pTextStyleTableRecord->setXScale(0.8);
Acad::ErrorStatus es=pTextStyleTable->add(pTextStyleTableRecord);
pTextStyleTableRecord->close();
}
pTextStyleTable->close();
}
扩展数据扩展数据XData 容量受限制,只能存储<=16K
AcDbObject::xData ()
AcDbObject::setXData()
(