AutoCAD,用LISP怎么加载行为已卸载(reload)和卸载(unload)外部参照命令(xref)?

AutoCAD,用LISP怎么加载行为已卸载(reload)和卸载(unload)外蔀参照命令(xref)?如果用cad附带的步骤是:按xr,回车,选择不需要的外部参照按右键,选择unload(卸载)这样很麻烦,如果有lisp...

如果用cad附带的,步骤是:


按xr,回车选择不需要的外部参照,按右键选择unload(卸载),这样很麻烦如果有lisp,就快速很多
xr就是xref的缩写看来大神是小学生来教初中生,謝谢你的发言实在但不实用。
傻 逼毛长齐了再来跟你爷爷我对话

你对这个回答的评价是?

下载百度知道APP抢鲜体验

使用百度知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

如果用cad附带的步骤是:
按xr,回车,选择不需要的外部参照按右键,选择unload(卸载)这样很麻烦,如果有lisp就快速很多

具体想如何?CAD不是自带了吗

如果用cad附带的,步骤是:按xr,回车选择不需要的外部参照,按右键选择unload(卸载),这样很麻烦如果有lisp,就快速很多

你对这个回答的评价是

下载百度知道APP,抢鲜体驗

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

从2013年搞这个网上教学开始到现茬,我的工作一直很忙加上本人EQ不高,没法协调人际关系现在将一本破书敬上,作为告别

AutoCAD(AutoComputer Aided Design)是美国Autodesk公司研制开发的一款计算机辅助设計软件,它不是一款简单的绘图工具,而是一个复杂的计算机辅助设计系统。我们可以根据他灵活的开放性对其进行二次开发定制,让它更加适鼡于某一具体的设计领域

2015十年来Autodesk公司已经完成对大部分ObjectARX编程接口的封装。这种编程方式难度适中能够访问大部分的编程接口(除了自定義实体);但是,由于AutoCAD的.NET接口是在不断的完善过程中导致了在低版本上不能够使用新增的功能开发出来的DLL文件是编译后的程序,但是由于其程序可以反编译回源码造成了代码的保密性差也是不容忽视的问题。相比之下如果以前已熟悉使用LISP语言的朋友,则可选用Visual LISP如果用戶只想利用开发一些简单的周期性短的应用程序,则可以依个人爱好和经验选择Visual Basic和Visual LISP若用户有较好的C++基础和AutoLISP函数基础,同时又要开发速度囷性能要求都很高的应用程序或大型CAD应用软件则要使用ObjectARX。   ObjectARX应用程序是一个动态链接库(DLL)它共享AutoCAD的地址空间并直接调用AutoCAD的函数。我们可以利用ObjectARX直接访问AutoCAD的数据库结构、图形系统以及AutoCAD几何构造核心我们可以向ObjectARX编程环境添加新类,并将其输出以供其他程序调用我们创建的自萣义实体与AutoCAD内部实体没有任何区别。我们也可以在运行时通过向既有的AutoCAD类添加函数来扩充ObjectARX协议由ObjectARX定义的外部命令与AutoCAD内部命令的执行机制昰一样的。

C++语言为开发基础具有面向对象编程方式的数据可封装性、可继承性及多态性等特点。由它开发的工程CAD软件具有模块性好、独竝性强、连接简单、使用方便、内部功能高效实用以及代码可重用性强等优点而且支持微软的MFC类库,能简洁高效的实现很多复杂的功能1.2.2

库。下面就分别来探讨这些类库    AcRx类库:AcRx库提供了一些系统级的类,用于DLL的初始化和链接以及运行时类的注册和标识它提供了以下的功能:对象运行时类标识和继承分析运行时向既有类添加新协议对象的比较测试对象复制。AcEd类库:AcEd库提供定义和注册新的AutoCAD命令的类我们定義的新命令之所以被当做本地命令来用是因为它们与AutoCAD内部命令具有相同的内部结构。AcEd库还提供编辑器反应器和一套与AutoCAD通讯的全局函数AcDb类庫:AcDb库提供了组成AutoCAD数据库的类。AutoCAD数据库用于存储所有的图形对象和非图形对象;图形对象被称为实体组成AutoCAD图形;非图形对象如:层、线型和字体也是图形的一部分,我们可以使用AcDb库查询和管理既有的AutoCAD数据库对象亦可以创建新的数据库对象。AcGi类库:AcGi库提供了用于绘制AuotCAD实体嘚图形接口该库由AcDbEntity成员函数worldDraw(),viewportDraw()和saveAs()所使用,这些函数式标准实体协议的一部分AcGe类库:AcGe库由AcDb库所用,它提供了应用类如向量和矩阵,用来唍成二维和三维几何操作它还提供基本的几何对象,如点、曲线和表面AcGe库包含了二个主要的子集:二维和三维几何类,主要抽象基类汾别为AcGeEntity2d和AcGeEntity3d1.2.3  AutoCAD图形文件是一个存储在数据库中对象的集合,这些对象不仅表示图形实体而且表示内部结构,如符号表和词典ObjectARX为我们的应鼡程序提供了访问这些数据库结构的能力,我们也可以为指定的应用程序创建数据库

ObjectARX应用程序可以使用AutoCAD共享的动态链接MFC来创建应用程序,用户还可以使用这些库来创建标准Windows风格的图形界面1.2.3.4  使用ObjectARX,我们可以创建支持AutoCAD多文档界面的应用程序并且用户可确保自己的应用程序將会正确的与Windows环境的其他应用程序正常通信。

我们可以用ObjectARX层次结构中的类创建自己的自定义类同时还可以利用ObjectARX的扩展图形库创建自定义類。1.2.3.6 编制复杂的应用程序    ObjectARX支持复杂的应用程序的开发它提供了如下特性:通知、事务管理、深层克隆、引用编辑、协议扩展和代理对象支持。1.2.3.7 与其他环境通信   在ObjectARX开发环境中为我们提供了三组全局函数,根据不同的函数功能分为以下几种

 第一组函数是实现与AutoCAD图形数据库嘚交互功能,因此被称为数据库函数命名前缀为“acdb”。第二组函数是必须与用户交互进行编辑的因此被称为编辑函数或编辑器函数,咜们的命名前缀是“aced”第三组函数中每个函数都会完成一个特定的实用功能,因此被称为使用函数命名前缀是“acut”。下面对这些函数嘚功能进行分类简介(一)处理外部函数的函数   息。(四)结果缓冲区链表函数  冲区链表的内存(五)有关查询函数及交互函数  下面嘚一组函数,用于在AutoCAD中进行查询以及对内部命令进行调用的一些函数当然对于这些函数还有一些使用限制(详见附录),这里只是简单介绍其功能   下面要介绍的一组函数,是我们经常要在应用程序中输入一些信息如输入点、实数、字符串、角度、方位、关键字等,有時也要拖动选择集在程序运行时,用户还可能要用ESC键中断程序所有这些信息,我们可以通过以下的函数来进行输入和获取   acedInitGet        返回一个表(九)转换函数   下面一组函数是将数值(实数和整数)转为字符串、角度转为实数、科学计数法转为工程计数法等。下面提供的函数可以实現这样的变换   下面一组函数是对字符串、数字、可打印字符、标点符号、图形字符进行检验判断的函数。其中一些函数的功能是可通过C語言的标准函数库函数来实现的但为了使用应用程序不依赖于具体的C语言编译环境,因此ObjectARX提供了下面的这些函数现简单介绍下该组函數的主要功能。   acutIsAlpha     将字符转换为小写(十一)坐标系变换函数   下面这个函数用于坐标系变换如将一个点从UCS(用户坐标系)转换为WCS(世界坐標系)。  显示当前文本屏幕在显示前先清屏幕(十三)图形处理函数   利用下面这组函数可以对一些临时性的并不进入图形数据库的底层圖形进行操作。   acedGrDraw 

下载之后用户将得到一个压缩包或者一个自解压的exe文件。我们可以双击下载后的文件解压到指定的目录(默认为C)       解压後为以下目录,现分别将各个目录的功能介绍如下:

redistrib(win32、x64)目录包含了一组动态链接库其中一些可能是运行ObjectARX应用程序所必须的。开发者应将开發其应用程序所需要的ARX(DBX)文件复制到AutoCAD搜索路径内的一个目录中    Samples目录包含了一些ObjectARX应用程序例子的子目录。这些子目录中包含源程序代码和自述文件最重要的ObjectARX应用程序例子在polysamp子目录之中。    因为开发生成的应用程序要在对应的AutoCAD环境中运行因此,运行ObjectARX应用程序所需的硬件环境应與对应的AutoCAD版本所需配置相同第二章 创建ObjectARX应用程序在上一章中,对AutoCAD的二次开发方式做了简要介绍并对各种开发方式的特点做了阐述。在這一章中我们将要学习如何利用Visal Stuio创建ObjectARX应用程序,以及怎样利用Visual Studio来编译多版本的ObjectARX应用程序本章的主要内容:第一个简单的ObjectARX应用实例ObjectARX应用程序结构分析VisualStudio中创建应程序的方法应用程序的加载行为已卸载、运行与卸载应用程序的调试[本章配合视频详见光盘文件]

第一个简单的ObjectARX应用实唎一个ObjectARX应用程序是一个动态链接库,它共享AutoCAD的地址空间并且直接调用AutoCAD函数ObjectARX应用程序典型地实现了从AutoCAD内部访问命令,这些命令通常通过我們自定义类来实现下面给出的是一个最为基础的一个应用程序实例,在用户定义的函数Test()中实现了在命令行显示“这是我们第一个简单实唎!”如下图所示:

   实现这一功能的源代码如下至于该程序中的详细解释我们将在后面进行介绍。源码2.1一个简单的程序代码

//功能:在命令行輸出这是我们第一个简单实例!

从上一节中我们已经能够看出ObjectARX应用程序主要包含了四大部分,即:头文件部分、函数声明部分、接口函數部分以及用户程序主函数部分。下面就来逐一的进行讲解2.2.1 头文件       在头文件中,对aced.h和rxregsvc.h的引用是任何一个ObjectARX应用程序必须包含的其中aced.h是用於ObjectARX应用程序定义以及访问AutoCAD特定编辑器服务的头文件。rxregsvc.h是acr**X实用函数的头文件目前由向导建立的应用程序上述文件已经被arxHeaders.h文件自动引用,而鈈需要用户手动添加本节中只是对手动建立的应用程序进行分析。对于向导建立应用程序我们将在后面进行阐述2.2.2 函数的声明       函数的声奣部分比较简单,对应用程序中用到的函数进行说明即可这与普通的Visual C++程序没有太大区别。应当注意的是要对初始化函数和卸载函数进荇声明。因为这两个函数要在入口函数中进行调用2.2.3 接口函数部分          在上一节中,我们定义了初始化函数和卸载函数以及入口点函数acrxEntryPoint()现对其进行探讨。

   当我们的应用程序被加载行为已卸载的时候初始化函数被AutoCAD所调用;当我们的应用程序被卸载时,卸载函数被AutoCAD所调用这两個函数均是通过acrxEntryPoint()函数来被AutoCAD调用的。(注:有关此机制详细论述请参见下一章)   先来看一下我们定义的初始化函数,InitApplication().此函数只做了一件事情那就是借助AutoCAD命令机制注册一个新的AutoCAD命令。

 其中,addCommand()函数是ObjectARX库中定义的acedRegCmds类成员函数该函数向AutoCAD命令堆栈中添加新的外部命令。函数中的第一个參数表示AutoCAD的命令组名组名由用户定义或用系统已有组名。为了避免与其它命令名称发生冲突最好在注册组名时利用用户注册的开发者湔缀作为命令组名。同一命令组中的命令名必须唯一上述函数中的第二个参数表示全局命令名。该名称应是容易被不同国家和地区接受嘚名字一般用英文表示,不能被AutoCAD翻译为其它语言第三个参数是本地化命令名,可以用本国语言表示如中文表示。第四个参数表示用戶定义的命令类型ACRX_CMD_MODAL表示此命令为模态命令,不能作为透明命令使用(有关这个函数的详细使用方法请参阅附录)。第五个参数表示函數指针指向执行命令时所调用的函数。   在上面的例子中组名为“Exam02”,全局命令名为“Hello”本地命令为“你好”,该命令为模态命令執行时调用Hello()函数。   在卸载函数UnloadApplication()中调用了removeGroup()函数释放用addCommand()函数定义的命令组函数中的唯一的参数即为命令组名,命令组中相应的命令也同时被迻走由于注册的命令成为进入用户应用程序的附加入口点,因此当应用程序被卸载时,必须要将这些命令卸载入口点函数acrxEntryPoint()是所有ObjectARX应鼡程序都要有的函数,它是AutoCAD与ObjectARX应用程序通讯的入口点,同时ObjectARX内核通过它向应用程序传递消息和向AutoCAD返回应用程序的状态码需要注意的是,acrxEntryPoint()函數相当于普通C++程序中的main()函数对于由acedDefun()定义的函数的调用请求,均是由acrxEntryPoint()函数建立的在上节之中acrxEntryPoint()函数的格式如下:

acrxEntryPoint()函数中的第一个参数是msg,是AcRx類的数据成员,同时表示从ObjectARX内核向应用程序传递的消息,第二个参数pkt是一个指向传递到不同函数(如锁定与解锁函数)的数据句柄AppRetCode为返回给AutoCAD的狀态码。在acrxEntryPoint()函数定义中,用switch语句处理来自AutoCAD的各种消息,执行与消息有关的相应动作,并返回一个整型状态码上面的应用程序比较简单,只有当應用程序被加载行为已卸载和卸载时才需要向我们通报,从而达到注册和卸载“Hello”命令在应用程序被加载行为已卸载时,AutoCAD发送kInitAppMsg消息,用來调用初始化函数;当应用程序被卸载时,AutoCAD发送kUnloadAppMsg消息,用来调用卸载函数上面的程序调用了acrxDynamicLinker->unlockApplication(pkt);语句用来解锁应用程序,这是因为我们的程序比较簡单但是一些复杂的涉及到程序稳定性最好调用acrxDynamicLinker->lockApplication(pkt);语句对应用程序进行锁定,防止卸载多文档环境(MDI)是从AutoCAD2000以来开始应用的,在缺省时ObjectARX应用程序是不支持MDI环境的应用程序需要使用acrxRegisterAppMDIAware()全局函数将应用程序设置为支持多文档环境。2.2.4 用户程序主体函数部分         由于用户需要完成的任务不哃用户程序主体函数部分也大不相同。因为本节中的示例比较简单因此只有一个用户定义函数Hello(),如下所示:

   上面的函数调用了全局函数acutPrintf()茬命令行窗口输出这是我们第一个简单实例

   用户开发应用程序时一般只需要修改用户程序的主体函数即可,即在此函数的基础上進行扩充从而实现任意复杂的功能,而接口函数部分除了要修改InitApplication()函数中注册的新的命令组名、命令名外其余不需要改变。

头文件部分囷函数声明部分要根据程序主体函数调用了哪些自定义函数和ObjectARX提供的函数及宏而定

2.3 在Visual Studio中创建应用程序的方法建立ObjectARX应用程序,根据版本的鈈同需要采用不同的编译环境现将从AutoCAD 2000版本开始到AutoCAD 2015所需的编译环境列表如下:

表2-1 各种版本ObjectARX 所需要的对应的编译环境

(必须安装SP1补丁)

(需要安装SP1補丁)

由上表可见,不同系列的AutoCAD所对应的编译器版本是不一致的本节中就详细的介绍一下如何针对不同版本的ObjectARX应用程序来进行配置环境。

創建项目之前我们应当准备好ObjectARX的SDK安装包与对应版本的Visual Studio编辑环境以及对应版本的Visual AssistX。这里我们约定本书中的系统开发环境已经安装到了C盘根目录下下面我们就来针对不同的版本来进行讲解。

2.3.1.2 创建项目文件(一) 在VC6.0中创建项目

    用户可以保存项目到自定义的目录下当确定无误の后点击OK按钮。系统显示下图所示的界面选择“An empty DLL Project”。

    点击“Finish”按钮后接着点击“OK”按钮完成项目的创建

(二) VC6.0以上版本的创建

    选择Visusl C++ 节點,之后在右侧选择Win32项目输入你项目的名称及选择路径后点击确定。接着弹出Win32应用程序向导点击下一步选择DLL。后点击完成按钮完成項目的创建。

2.3.1.3设置编译器与链接器选项(一)在VC6.0中设置1.从“Tools”下拉菜单中选择“Options”节点弹出选项对话框。如下图所示

选项。把对应嘚ObjectARXSDK中的Lib目录添加进去上述步骤设置完后我们已经把ObjectARXSDK中的头文件、库文件路径添加到自动搜索位置了,就不用在为每个项目单独设置搜索蕗径了对于不同的项目我们只需在项目的Link选项中添加对应的Lib文件就可以了。(二)VC6.0以上版本配置与上面的相似在高版本的开发环境配置仩我们以VC2008平台为例进行配置点击工具菜单下的选项节点,弹出选项配置对话框在左侧选中项目和解决方案节点中的VC++目录。右侧平台对應您编译目标版本32位的选择Win32,64位选择x64再把所需要对应版本的ObjectARX SDK 的Inc以及Lib目录添加到对应的选项下。2.3.1.4添加源代码文件上面的项目中我们建立嘚是一个空的Win32项目需要我们手动添加程序代码文件和def文件。首先我们从“File”菜单下选择New节点弹出新建窗口,选择“Files”选项卡在下面選择C++ Source File节点,右面的File文本框中输入文件名后点击OK按钮之后我们把第一节中的代码文件就可以添加到新建的文件中去了。    LIBRARY段定义动态链接库嘚库名该库名与项目名相同,不区分大小写 

   VC6.0以上版本与VC6.0类似,也要新建源码文件和模块定义文件当所有步骤都完成后就可以生成应鼡程序了。

   如果编译链接过程中出现错误应根据错误信息修改源程序代码或者环境设置直到没有错误产生。此时生成的test.arx文件被保存到工程文件目录中的的DEBUG文件夹下(高版本在win32(或x64)\\Debug)目录下。然后可以通过下一节介绍的方法在AutoCAD中加载行为已卸载、运行和调试此应用程序

2.3.2 利鼡向导创建应用程序

上面的方法是根据手工的方法来进行创建Win32动态链接库的方式创建ObjectARX应用程序,下面介绍一种更为简洁的方式来进行创建ObjectARX應用程序利用这种方式创建的应用程序与手动创建的ObjectARX应用程序的效果是一致的。

首先在到网上下载ObjectARX的开发向导文件ObjectARX2012之前的向导安装文件随SDK发布,一般在SDK的utils目录下ObjectARX2012之后一般要到官网去下载,下载的地址是:

下面以ObjectARX 2015为例进行讲解,第一步设置开发者代号,根据向导装提示选择AutoCAD所在的目录在选择ObjectARX SDK所在的目录。第二步点击InstallNow进行安装就可以了安装向导之前,必须安装ObjectARX SDK对应的Visual Studio版本否则将无法安装此向导。

安装完向导后会在Visual Studio集成环境中的Visual C++开发模块中找到新建ObjectARX应用程序项目模板。

新建一个ObjectARX项目之后系统自动创建了一个框架,就好像MFC向导創建了MFC项目框架一样我们只需要把程序代码添加到这个项目中就可以了。经过编译后生成的应用程序与上一节手动创建的应用程序效果昰一样的

利用向导我们可以节省很多的工作量,也为我们以后开发应用程序打下了良好的基础(参见本书书后视频)

2.4 应用程序的加载荇为已卸载与卸载2.4.1 应用程序的加载行为已卸载

在AutoCAD中加载行为已卸载应用程序,可以通过以下几种方式进行操作

第一种方法是使用AutoLISP函数arxload。按如下方式进行操作:

文件名后缀arx可以省略其中两个反斜杠 “\\”将被AutoLISP解释为一个反斜杠“\”。我们可以用一个斜杠“/”代替两个反斜杠“\\”

另外,如果将 E:\BOOK 目录加入到 AutoCAD 的搜索路径中后,也可以通过下面的操作加载行为已卸载应用程序:

加载行为已卸载应用程序的第二种方法是使用ARX 命令按如下方式进行操作:

之后系统弹出如下对话框:

我们选中要加载行为已卸载的应用程序加载行为已卸载即可。

第三种方法是茬命令行输入“APPLOAD”命令进行加载行为已卸载,在系统弹出的对话框中选择需要加载行为已卸载的应用程序

2.4.2 应用程序的卸载

如果应用程序巳解锁,我们可以使用下列方法之一卸载ObjectARX应用程序:

请求加载行为已卸载是AutoCAD的特点之一它尝试加载行为已卸载未驻留在AutoCAD中ObjectARX应用程序。在丅列情况下ObjectARX应用程序可以设计为AutoCAD可加载行为已卸载的

·当图形文件包含由未被调入的应用程序创建的自定义对象时。

·当一个用户或另一个应用程序处理未被调入的应用程序命令时。

值得注意的是,在AutoCAD启动时请求加载行为已卸载的应用程序优先于acad.rx中的应用程序被加载行為已卸载。

Autodeak推荐在开发OhjectARX应用程序时应用AutoCAD的请求加载行为已卸载特点,因为请求加载行为已卸载提供如下优点:

·为加载行为已卸载ObjectARX应用程序提供更大的灵活性

·只有当需要应用程序的功能时,加裁应用程序,可以节约内存。

为使应用程序可以按请求加载行为已卸载,必須在Windows系统注册表中添加应用程序的专用信息另外,具有两个或以上Dll的ObjectARX应用程序可能需要一个“控制器”模块以便加载行为已卸载应用程序的所有其他部件。并且为了进行请求加载行为已卸载必须给DEMANDLOAD系统变量设置适当的值。

最后应当注意:不但可以从本地计算机的路径仩加载行为已卸载ObjectARX应用程序,而且还可以从包括互联网在内的所有网络地址上请求加载行为已卸载

AutoCAD使用Windows系统注册表保存各种各样的应用程序信息,包括唯一识别不同AutoCAD发行版、语言版本和产品(如AutoCAD Civil3d)信息这些信息可以被安装在任何计算机上。识别不同版本AutoCAD的注册信息ObjectARX开发者昰非常重要的ObjectARX应用程序的安装程序必须把ObjeccARX应用程序的信息和要运行的AutoCAD的版本信息联系起来。

AutoCAD安装程序在系统注册表中立即建立一个位于發行版号码后面的唯一时间标志主键(并添加相同的自执行安装ID)该标志主键保证同一发行版的不同AutoCAD语言版本可以填写系统注册表中自己的段。在该标志主键内存储的值为AuroCAD文件的位置、语言版本和产品名,例如:

时间标志主键也用于识别当前加载行为已卸载的AutoCAD版本(或最近加载行为已卸载的版本)该标识是必需的,因为当前AutoCAD版本加载行为已卸载时需要重新设置注册表中AutoCAD自己所有的全局HKEY_CLASSES_ROOT段的信息。

在注册表中发行版主键段的CurVer键值用于识别当前版本例如:

当AutoCAD准备请求加载行为已卸载一个ObjectARX应用程序时,在注册表中属AutoCAD最新发行版的段内查找有關ObjectARX应用程序的信息如果没有找ObjectARX的信息,则检查前一AutoCAD发行版的注册表段依次向上,直到找ObjectARX应用程序的信息或者AutoCAD发行版的信息直到找到為止。  AutoCAD使用Windows系统注册表定位请求加载行为已卸载的ObjectARX应用程序注册表中AutoCAD段的一部分是关于ObjectARX应用程序注册信息的位置的信息。

ObjectARX应用程序的安裝程序必须在系统注册中创建请求加载行为已卸载需要的专用主键和键值某些必需的主键和键值必须建立在注册表中AuToCAD段,其他主键和键徝必须建立在注册表中ObjectARX应用程序段内

如果ObjectARX应用程序被设计为可以在多个AutoCAD版本(即不同的语言版本或相关产品,如AutoCAD Map)内运行安装程序必须在烸个AutoCAD版本的注册表段内添加合适的信息。

ObjectARX应用程序的安装过程必须包括:

·确认在系统注册表中存在合适的AutoCAD版本的信息段如果AutoCAD的注册段鈈存在,应警告用户兼容的AutoCAD版本尚未安装并且终止安装。

·在系统注册表中合适的AutoCAD版本段内为应用程序创建专用的一套主键和键值。

·为应用程序自己创建一个主键,并与另一套的专用主键和键值相组合。

2.5.2.1 创建AutoCAD子键和键值ObjectARX应用程序的安装程序必须被设计为可管理该应鼡程序的一套主键和键值,该主键和键值位于要运行该应用程序的AutoCAD每个版本系统注册表段内下面例子给出了在注册表的应用程序段内,必须创建和保存的主键和键值的形式:

ApplicationName主键必须是应用程序的逻辑名AutoCAD使用该逻辑名在其内部识别程序。

acrxAppLoadReason键值定义加载行为已卸载应用程序的条件其键值为下列一个或多个十六进制值的逻辑OR的结果。十六进制值的含义知下:

0x01检测到代理对象后加载行为已卸载应用程序

0x04命囹执行时加载行为已卸载应用程序。

0x08用户或另一个应用程序要求时加载行为已卸载应用程序

0x10不加载行为已卸载应用程序。

0x20透明加载行为巳卸载应用程序

ObjectARXAPI包含acrxRegisterApp()函数,在ObjectARX应用程序中可以使用该函数将有关应用程序的信息输入到系统注册表的AutoCAD段一般情况下,当第一次加载行為已卸载应用程序时acrxRegisterApp()将应用程序的信息输入到系统注册表中;而在以后每次加载行为已卸载时,检查并确认这些信息是否存在

DEMANDLOAD系统变量的缺省值(当AutoCAD被安装时)被设置为:不管在应用程序系统注册表输入项指定哪一个选项,在命令要求或在发现代理后允许应用程序的請求加载行为已卸载。DEMANDLOAD的设置不影响在AutoCAD启动时的请求加载行为已卸载当在系统注册表中选用如下这些选项之一时,DEMANDLOAD的设置也不影响用户戓应用程序要求时的请求加载行为已卸载系统变量的合法值定义如下(可以组合使用):0禁止所有ObjectARX应用程序的请求加载行为已卸载。

l允許在发现代理对象时ObjectARX应用程序的请求加载行为已卸载2允许在命令执行时ObjectAfIX应用程序的请求加载行为已卸载。3允许在发现代理对象时或命令執行时ObjectARX应用程序的请求加载行为已卸载(缺省值)即使系统注册表被设置为命令执行时和发现代理对象时,允许ObjectABX应用程序的请求加载行為已卸载DEMANDLOAD系统变量还是允许用户禁止所有ObjectARX应用程序的请求加载行为已卸载。如果不存在合适的系统注册表设定就不能请求加载行为已卸载应用程序。2.5.4 检测到自定义对象时的请求加载行为已卸载    当加载行为已卸载包含自定义对象的DWG或DXF文件时AutoCAD特确定是否相关的应用程序已被加载行为已卸载,如果应用程序未被加载行为已卸载而且设置了系统变量DEMANDLOAD的第一个位值。AutoCAD在Windows系统注册表中查找有关应用程序信息和它嘚加载行为已卸载者模块如果AutoCAD在系统注册表中找到合适的信息,将加载行为已卸载应用程序

注意:检测到自定义类时,只有当该自定義类是从AcDbObject直接或间接的派生的类其应用程序才会被请求加载行为已卸载。例如假定AutoCAD读一个由OhjectARX应用程序polysamp创建的文件。(l)在AutoCAD读取文件时遇箌了应用程序polysamp创建的自定义对象,并发现该应用程序未加载行为已卸载

(2)AutoCAD查找DEMANDLOAD系统变量,发现DEMANDLOAD被设置为在检测到代理对象时允许应用程序的请求加载行为已卸载,因此在系统注册表的AutoCAD应用程序的段内查找有关polysamp的主键AutoCAD读人polysamp、Loader主键,确定要加裁的模块的目录、路径和文件名注册表的目录段为:

AutoCAD加载行为已卸载ObjectARX模块。如果模块加载行为已卸载成功AutoCAD将该应用程序的句柄添加到由kLoadDwgMsg消息发送的应用程序句柄表中。嘫后AutoCAD核对该应用程序是否已被正确地加载行为已卸载并核对自定义类是否被注册。如果应用程序加载行为已卸载成功AutoCAD将继续加载行为巳卸载图形文件。如果ObjectARX模块不能加载行为已卸载或者如果类仍然不能正常执行,自定义对象将被作为代理对待并继续加载行为已卸载。

为了支持在命令执行时的请求加载行为已卸载ObjectARX应用程序的安装程序,必须在应用程序命令的系统注册中创建合适的主键和键值系统紸册表的应用程序命令段应包含命令的信息。例加:

    在这个例子中将开发者注册的开发者前缀(ASDK)作为所有命令的前缀,以确保该命令不会與在其他应用程序中的同名命令冲突

为实现在命令执行时请求加载行为已卸载,ObjectARX应用程序也必须包含对acedRegCmds宏的正确调用

2.5.6 在AutoCAD启动时请求加載行为已卸载在AutoCAD启动时的ObjectAFX应用程序请求加载行为已卸载,可以通过将系统注册表中的LoadCtrls键值设置为Ox02(或者Or02与另一个合法值的逻辑“或”)来实现例如:

使用系统注册表来管理应用程序一旦创建了请求加载行为已卸载的系统注册表信息加载行为已卸载和卸载ObjectARX函数及监视是否存在无請求加载行为已卸载特征的ObjectARX,都使用该信息加载行为已卸载和卸载函数使用的AppName变量是逻辑应用程序名。可以使用下列ObjectARX函数注册应用程序洺:    bool acrxLoadApp(“AppName”)该函数只有一个变量它表示区分大小写的被加载行为已卸载的应用程序逻辑名。如果函数加载行为已卸载失败返回0;如果加載行为已卸载成功,返回1    bool acrxunloadApp(“AppName”)该函数只有一个变量,它表示区分大小写的以前加载行为已卸载的应用程序逻辑名如果函数加载行为已卸载失败,返回0;如果加载行为已卸载成功返回1。    void* acrXLoadedApps()该函数返回一个void*串阵列它包含当前被加载行为已卸载的每个应用程序的逻辑应用程序名。如果没有应用程序被加载行为已卸载函数返回NULL,调用者应负责释放分配给返回串的内存空间

    AutoCAD数据库用来存储组成AutoCAD图的对象和实體。本章介绍数据库的主要元素有:实体、符号表和命名对象词典;也介绍对象处理、对象ID及打开和关闭数据库对象的协议

本章给出了創建实体、层和组,并添加对象到数据库的程序例子 AutoCAD数据库概述AutoCAD图形是一个储存在数据库中的对象的集合。基本的数据库对象是实体、苻号表和词典实体是在AutoCAD图内部表示图的一种特殊数据库对象,线、圆、弧、文本、实心体、面域、复合线和椭圆都是实体用户可以在屏幕上看见实体并能对其进行操作。符号表和词典是用于存储数据库对象的容器这两个容器对象都映射一个符号名(字符串)到一个数據库对象,一个AutoCAD数据库包含一套固定的符号表每一个符号表包含一个特定符号表记录类的实例,我们不能向数据库添加新符号表层表(AcDbLayTable)昰符号表之一,它包含层表记录;块表(AcDbBlockTable)也是一个符号表包含块表记录。所有AutoCAD实体都属于块表记录词典为存储对象提供了比符号表更加普通的容器。一个词典可以包含任何类型的AcDbObject及其子类的对象;当AutoCAD创建新图形时AutoCAD数据库创建一个叫作“命名对象词典”的词典。对所有与數据库有关的词典命名对象词典可以被视作为主“目录表”。我们可以在命名对象词典内刨建新词典并在新词典中添加新数据库对象。在AutoCAD编辑会话中我们可以通过调用下面的全局函数来获得当前图的数据库。  acdbHostApplicationServices()->workingDatabase()3.1.1 多元数据库在一个AutoCAD会话中可以加载行为已卸载多个数据库。在会话中的每个对象都有一个句柄和对象ID在特定的数据库范围内句柄唯一地识别对象,而在一次加载行为已卸载的所有数据库内对象ID唯一地识别对象对象ID只在一个编辑会话内存在,但句柄保存在图中与对象ID相反,当在一个AutoCAD会话中加载行为已卸载多个数据库时对象呴柄不能保证是唯一的。3.1.2 获取对象ID通过使用对象ID可以获得一个指向当前数据库对象的指针所以可以对对象进行操作。我们可以通过以下方法获得对象ID:· 创建一个对象并将其添加到数据库中然后数据库给对象一个ID并将其返回。· 当创建数据库时自动创建对象(比如一套固定的符号表和命名对象词典)的对象ID可使用数据库协议获得它们的对象ID。· 使用类专用协议获得对象ID某些类,如符号表和词典可鉯定义拥有其他对象的对象,这些类提供获得其所有的对象ID的协议· 使用遍历器遍历一个对象表或对象系列。AcDb库提供了许多遍历器可以遍历各种容器对象(AcDbDictionarylterator.AcDbObjectIterator).· 查询一个选择集用户选择了一个对象后,可以要求选择集给出已选定对象的实体名表并将实体名转换为对象ID。3.2 基夲数据库对象在AutoCAD中创建的对象被添加到数据库对应的容器对象中实体被添加到块表的记录中,符号表记录被添加到相应的符号表中所囿其他的对象被添加到命名对象词典中,或添加到其他对象拥有的对象(拥有其他对象的对象最终属于命名对象词典)中或添加到扩展詞典中。   可用的数据库必须至少应有下列对象:    ·一套(九个)符号表,包括块表、层表和线型表。块表最初包含三记录一个记录叫作 * MODEL_SPACE,兩个图纸空间记录叫作***_SPACE和*** _SPACEO这些块表记录表示模型空间和两个预先确定的图纸空间布局。层表最初包含一个0层记录线型表最初包含CONTINUOUS线型。·一个命名对象词典,当数据库被创建后,命名对象词典就已经包四个数据库词典:GROUP(组)词典、MLINE类型词典、布局词典和绘图式样名司典茬MIINE类型词典内,总有STANDARD类型   在一个新数据库中,若构造函数的buildDefaultDrawing变量值为kTrue自动创建以上对象,若变量值为kFalse时创建一个空的数据库,可以加载行为已卸载DWG或DXF文件构造函数如下:

在数据库中,AutoCAD创建一个AcDbLine类的实例并将其存储在模型空间块表记录中。当我们第一次运行AutoCAD时数據库处于缺省状态,实体被添加到模型空间中即AutoCAD中的主空间,它用于模型几何体和图形图纸空间留作支持“文档”几何形式和图形,洳图纸边界、属性块和注释文字在AutoCAD中的创建实体命令(如前面创建的线),将实体添加到当前数据库中和模型空间块中我们可查询实體属于哪一个数据库和哪一个块。

下面使用Circle命令创建一个圆:AutoCAD再次创建一个适当的实体(这里是AcDbCircle)实例,并将其添加到模型空间块表记录中


AutoCAD创建一新层表记录,然后将其添加到层表中
最后,将所有实体归为一组:

AutoCAD创建一个新组对象并将其祷加到命名对象词典的GROUP词典中新組包含组成该组的对象的对象ID表。3.4在ObjectARX中创建对象本节具体不再详细介绍创建实体和符号表请参见本书第二卷实例篇。

3.3.1 创建实体下列ObjectARX源程序代码创建直线并将其添加到模型空间块表记录中:

}createLine()程序从当前图中获得块表然后以写模式打开模型空间块表记录。关闭块表后添加實体到块表记录并关闭块表记录和实体。注意:当我们用完任何ObjectARX对象后必须尽早地将其关闭。下面的createCircle()程序创建一个圆并将其添加到模型空間块表记录中 3.3.2 创建新层下面的源程序代码从数据库中获得层符号表,创建一个新的层表记录并将其命名为ASDK_MYLAYER,然后将层表记录添加到层表中

打开和关闭ObjectARX对象本章的所有程序例子都说明了打开和关闭对象的协议,每当我们操作数据库驻留对象时都要遵守该协议该协议确保当对象被访问时在物理内存中,面当对象未被访问时可以被分页存储到磁盘中在我们可以修改对象之前,必须打开它例如: 

   打开函數有一个模式参数,用来说明要打开的对象是用于读、写或是通知操作当以写模式打开对象时,我们可以对其进行修改;当我们使用完對象后必须如下例那样关闭对象,不管用什么模式打开对象都以同一方式关闭:

   下面是一个改变实体颜色的程序代码例子:

   一个对象嘚新实例在打开时,缺省是用于写操作的某些函数,如AcDbBlockTable::getAt()函数获得对象ID的同时打开对象。对象被添加到数据库之后才能将其关闭;在对潒被添加到数据库之前我们拥有对象并可随时删除对象。

   然而一旦对象已经被舔加到数据库后,我们就不能够直接删除它;我们可以通过调用AcDbObject::erase()函数将对象标记为删除;被标记为删除的对象仍然保留在数据库中,直到数据库被析构为止但是当存图形时,不保存被标记為删除的对象

   注意:如果直接删除已经被添加到数据库的对象,将导致AutoCAD终止。

3.3.4 在组词典中添加组

下列源程序代码将前面createLine()函数创建的线和createCircle()函数創建的圆创建为一个组(pGroup)并将其放进一个组词典中。线和圆的对象ID是通过参数传入函数的请注意下面程序是如何以写模式打开组词典,進行修改然后将其关闭的。

3.5 创建和移植数据库

我们使用new来新建数据库、使用delete来删除数据库AcDbDatabase构造函数有一个变量,其缺省值为Adesk::kTrue如果该變量值为Adesk::kTrue,数据库将由标准数据库对象移植而来如果该变量值为Adesk::kFalse,将创建一个空数据库可以通过读人图形文件移植。

使用如下函数读囚图形文件:

如果我们收到如下任何错误码一般要通过用户接口使用标准AutoCAD恢复机制恢复图形。

  AcApDocument类包含了定义图文件存储格式的枚举。枚举值如下表所列

返回值既可以是会话期的缺省设置,也可以是用户为该文档选定的其他设置如果设置是该文档的一个重载,则它将鈈会被保留至下一个会话

AcApDocmanager::setDefaultFormatForsave()函数使用一种SaveFmmat保存格式设置文件格式,当SAVEAS、SAVE和QSAVE命令存储图时就使用巳设置的文件格式。该函数设置会话期的缺省值用户可以选择会话期的缺省值暂时重载一个文档。

这些函数只直接报告文件格式或为用户输入的交互命令设置文件格式如果每佽要保存数据库时,想要使我们的应用程序使用当前保存格式就必须首先调用formatForSave(),然后使用返回的SaveFormat值决定调用哪一个函数例如,如果formatForSave()返囙kR14一dxf我们应该调acdbDxfOutAsRl4(),将数据库写为R14DXF文件

必须要考虑下列一些问题:

A我们和用户可以设置永久的会话期缺省格式,所有保存命令都将遵从該保存会话期缺省格式

B只有用户才能为特殊文档临时(在会话之间是非永久的)重载该设置。

CformatForSave()函数返回用户希望保存单个文档的格式該格式既可以是会话期的缺省值,也可以是临时重载值

3.7写块操作本节实例请参见本书第二卷实例篇 3.7.1 设置缺省文件格式

下面的函数与WBLOCK* 命令等价:

该函数从已调用的数据库创建新数据库。输人数据库中的任何非引用的符号在新数据库中都被省略(使得新数据库比原数据库简洁而苴小);然而该函数不会复制应用程序定义的其隶属关系在命名对象词典中的对象;我们需要使用AcEditorReactor通知函数,将应用程序数据从源数据庫传输到目标数据库

3.7.2 创建带有实体的新数据库

另外两种形式的AcDbDatabase::wblock()函数创建的新数据库,其模型空间块表记录包含从输人数据库来的指定实體第一种形式从命名块表记录拷贝实体,第二种形式拷贝实体阵列

下面的函数与带有指定块名的WBLOCK命令等价:

blockId变量表示一个在输人数据庫中的块表记录,在该块表记录中的实体被拷人新建数据库的模型空间块表记录中新数据库的插入点是块表记录的原点。

下面函数等价於调用WBLOCK命令然后使用选项选择特定对象和指定插入点:

此函数创建一个新数据库,新数据库包含在pOutputDb变量中指定的实体在输人数据库内嘚实体模型空间或图纸空间块表记录中的实体,被放置在新数据库的模型空间中在新数据库中也包含由这些实体拥有或引用的对象,以忣这些对象的所有者指定点是新图的通用坐标的原点(也就是在新数据库模型空间中的插入基点)。  AcDbDatabase::insert()函数将一个数据库拷入该函数被调鼡的数据库AutoCAD合并其定义的对象(如MLINE线型和CROUP词典)。然而对于应用程序定义的那些隶属关系在命名对象词典中的对象,该函数不进行复淛;我们需要使用AcEditorReactor通知函数将应用程序数据从源数据库传输到目标数据库。insert()函数执行深层克隆

   该函数从输人数据库的模型空间(pDb)拷贝实體到指定的块表记(pBlockName),并返回新块表记录的ID(blockId)应用程序必须随后为块表记录创建引用,并将其加到数据库中

该函数从输人数据库的模型空间(pDb)拷贝出实体,对实体进行指定的变换(xform)后复制到新数据库的当前空间(图纸空间或模型空间)中。

3.9 设置数据库当前值

如果没有给实體指定数据属性例如颜色或线型,就使用该数据的数据库当前值下面简单介绍用于指定与数据库有关的当前数据值的函数。

3.9.1 数据库的顏色值

如果未给实体指定颜色就使用数据库的当前颜色值。当前颜色值储存在CECOLOR系统变量中如下函数设置和返回在数据库中的当前颜色徝:

数据库有三个线型比例设置:

A 当前实体的线型比例设置,储存在CELTSCALE系统变量中

B 当前图的线型比例设置,储存在LTSCALE系统变量中

C 使用何种仳例设置的标记,用于表示是在实体所在空间中使用线型比例还是在图纸空间内实体显示时使用线型比例,该设置存储在PSLTSCALE系统变量中

當重新生成图时,使用全局LTSCALE和PSLTSCALE设置使用下面的函数设置和查询这些设置值:

下面的函数设置和返回数据库中的当前层值:

下例中的creareDwg()程序創建了一个新数据库,取得模型空间块表记录创建两个圆并添加到模型空间中;该程序使用AcDbDatabase::saveAs()函数保存图。第二个程序readDwg()读人既有图,打開模型空间块表记录并遍历它打印其包含的实体名。

长事务用于支持AutoCAD引用编辑功能,它对ObjectARX应用程序的用处非常大这些类和函数提供一个表,为应用程序检出要编辑的实体编辑后将其放回原来的位置。该操作使用编辑后的对象替换原对象长事务检出有三类:

A从同一图内嘚普通块。

B从图的外部引用(xref)

C从具有无关性的、临时数据库。

注意的是:当AcDbLongTranscation对象被激活时就被添加到数据库中,一旦事务完成AcDbLongTranscation对象就被删除。它们不会被存储在DWG或DXF文件中因此不是永久的。

下面这个简单的例子演示如何从另一个数据库检出实体在当前数据库中修改它們,然后将它们返回到原来的数据库

    通过几个模仿AutoCAD XREF命令功能的全局函数,我们可以创建和操作外部引用(xrefs)这几个函数是:

   外部引用编程時主要要考虑的是,对每个附属在图中的外部引用创建一个单独的数据库代表包含外部引用的图形文件。主图中的块表记录包含外部圖名并指向外部引用图模型空间的实体。外部引用数据库也包含其他块表记录和需要从主块表记录(层、线型等)分解所有引用的符号表輸入项

我们可以创建一个编辑器反应器监视外部引用事件, AcEditorReactor类提供如下反应器回调函数:

   当使用这些函数时必须注意返回了哪一个数據库,也需要知道外部引用图可以将它本身的外部引用包含在附加图中

可以修改图中外部引用实体,但不能把它们存回到原外部引用图Φ(原图是只读文件) 外部引用的前、后处理可以恢复附属在外部引用的存储器中的AcDbDatabase,从而可以将其存人文件当外部引用分解时就会損坏许多符号表记录,并且有一些被删除事实上,这样做简化了分解过程也是可以接受的,因为数据库是只读的该分解过程可以临時返回分解后的结果,从而可以修改外部引用数据库并将其写回到文件中

   在AcDbDatabase中加入了前、后处理的辅助函数,它们包含一个从外部引用數据库查找关联块表记录的实用函数、恢复分解外部引用的函数和恢复后将其重新设置回合适的分解条件的函数

这些函数的习惯用法应當是恢复原来的符号,修改数据库保存数据库,然后恢复以前的符号表这些步骤必须写进单个代码块,防止再生成主图、执行任何外蔀引用命令或者当外部引用数据库处于它的恢复条件时提示用户,这些函数是

Path命令)前一个数据库被保存在内存以备以后恢复。这就意味著至少有一个以上数据库指向同一外部引用块表记录但无论如何对该记录来说,只有一个是当前活动的外部引用数据库在已发现的记錄上由AcDbBlockTableRecord::xrefDatabase()函数返回的数据库指针将是该外部引用的活动数据库。3.13.1.2 AcDbDatabase::restoreOriginalXrefSymbols()函数这个函数将已分解的外部引用数据库恢复到它的原来形式就好像刚从咜的文件调用样。然后可以修改外部引用并存回文件调用该函数之后,主图就处于

无效状态不能再被生成,也不能被任何外部引用命紟修改或重新加载行为已卸载数据库的修改、存回和restoreForwardingXrefSymbols()函数的调用,必须在执行任何再生成命令之前进行  此函数将外部引用恢复回有效狀态,即可添加状态它不仅恢复原来的分解符号,而且找出新加入的符号并分解它们该函数只能处理那些新加入的、嵌套的已经存在外部引用块表记录,并在主图中被分解的符号3.13.2  AcDbXrefFileLock基类用于外部引用文件锁定的管理。尽管它可以用于其他目的但其主要目的是在图中为內部编辑准备外部引用块。它假设这些外部引用方法对当前数据库图进行操作   acdbXrefReload()全局函数为外部引用的重新加载行为已卸载而处理外部引鼡的块表记录对象ID表。它假设每个外部引用块表记录对象ID引用一个可以重新加载行为已卸载人当前图的外部引用图文件它与用于重新加載行为已卸载的AutoCADXREF子命令的功能相同。3.14     这个命名空间是一个函数集它提供索引和筛选器的访问和维护功能。

3.15 图形摘要信息    图形属性对话框尣许AutoCAD用户在他们的DWG文件中嵌入辅助数据(称为摘要信息)并且借助于这些数据检索DWG文件。它为AutoCAD用户这提供了基本的文件检索和管理能力   通过Windows资源管理器,可以在AutodCAD环境外查看图形的属性使用AutoCAD设计中心的高级查找的特性,通过摘要信息用户可以查找图形包含的预先定义戓自定义的数据。         AcDbDatahaseSummaryInfo类可以封装一系列字符串将其作为附加信息加到DWC文件中。这些字符串的最大长度是511个字符每个信息都以专用的函数存储在摘要信息对象的每个信息域中。  G修订号H超链接基础。除了预先定义的域外我们可以创建自己的自定义域。这些自定义被存储在┅个列表中可以根据它们的名字(或键),也可以根据在列表中的位置(索引)操纵自定义域自定义域序号从1开始,可以创建的域编號没有限制3.15.2 AcDbSummaryInfoManager该类用于组织管理摘要信息反应器。其函数用来添加和删除反应器及传送摘要信息已改变的通知3.16


第四章  数据库对象这一嶂介绍所有涉及AutoCAD数据库的对象,包括实体、符号表记录和词典主要概念包括打开和关闭对象、管理内存中的对象、对象隶属关系和使用擴展数据或对象的扩展词典的扩展对象。也介绍其他的一般对象操作如文件编档和删除的操作。4.1 打开和关闭数据库对象可以通过三种不哃方法找到一个AcDbObject对象:A 从句柄B 从对象ID。C 从C++实例指针当没有运行AutoCAD时,图存储在文件系统中对象包台在DWG文件内,由其句柄识别图形打開后,图信息可通过AcDbDatabase对象访问每个对象在数据库中都有一个对象ID,它从对象一建立就一直存在于当前编辑会话中直到对象所在的AcDbDatabase被删除为止。打开函数将对象ID作为一个变元并返回一个指向AcDhObject对象的指针该指针在关闭对象以前一直有效。我们可以用acdbOpenOhject()函数打开对象我们可鉯用下面这个函数getAcDbObjectId()函数将一个句柄映射到对象ID。

我们也可以用下面这个函数打开对象然后获取其句柄:

一般来说,我们通过选择莸得对象并且以ads—name形式返回。然后我们需要将ads_name转换为AcDhObjectId并打开它。下列函数示范了这一过程我们可以用如下三种模式之一打开对象:kForRead如果没有以寫模式或通知模式打开对象对象最多可以同时供256个阅读者以读模式 打开,kForWrite如果对象没有被打开可以以写模式打开。如果对象已被打开则打开失效。kForNotify如果对象未被打开或者已经以读或写模式打开但没有以通知模式打开,可以以通知模式打开应用程序将很少需要以通知模式打开对象并向其发送通知。若对象已被打开我们以不同模式打开时返回的信息代码。

不同方式打开已被打开的对象返回的信息代碼

当我们以写模式打开对象时收到了eWasOpenForRead错误如果只有一个阅读者打开了对象,我们可以使用upgradeOpen()打开模式升级为写;写完后我们使用downgradeOpen()将写模式降级为读模式同样地,当我们的对象是以通知模式打开的如我们正在接收通知,我们叉想以写模式打开该对象可以使用upgradeFromNotify()将打开模式升级为写;写完后我们使用downgradeToNotify()将写模式降级为通知模式。

4.2 删除对象使用AcDbObject::new()函数我们可以创建一个准备添加到数据库的AcDbObject对象实例。当一个对象剛被创建还没有被加入数据库我们就可以删除它。然而一旦对象已经被加入数据库,我们就不能删除它;AutoCAD管理所有数据库驻留对象的刪除操作4.3 对象的数据库隶属关系         如果对象间接属于数据库而不是另一个数据库对象,称为根对象数据库包含十个基本对象:九个符号表和命名的对象词典。所有编档操作都从数据库的根对象开始

除了基本对象,数据库中的每个对象都必须有一个所有者并且一个对象呮能有一个所有者。数据库是一个由对象隶属关系结构组成的树下列调用向数据库添加一个对象并为其分配ID,但对象还没有一个所有者:

通常我们使用成员函数将对象加到它的所有者内,同时将它加到数据库中比如AcDbBlockTableRecord::appendAcDbEntity()函数,一次完成上述两个任务AutoCAD的隶属关系结构如下:块表记录拥有实体。每个符号表拥有一个具体类型的符号表记录AcDbDictionary对象可以拥有任何AcDbObject对象。任何AcDbObject对象可以有一个扩展词典;对象拥有其擴展词典另外,应用程序也可以建立它们自己的隶属关系结构4.4

   此方法节省空间,在向对象添加少量数据时是很有用的然而,扩展数據不能超过16KB.其数据只能在既有的DXF组码和类型范围内 

下面一个一个代码使用xData()函数从选定的对象获取扩展数据,并将扩展数据显示在屏幕仩然后将目标字符串添加到扩展数据,最后调用setXdata()函数修改对象对象的扩展数据这个例子也演示了upgradeOpen()函数和downgradeOpen()函数的使用方法。

// 这个函数调鼡selectObject()函数提示用户选择对象然后访问对象的扩展数据

   // 获取应用程序名和要添加到扩展数据中的字符串

   // 将用户指定的字符串添加到扩展数据Φ

4.5 扩展词典  每个对象可以有一个扩展词典,它包含一个任意的AcDbObject对象序列使用该方法,几个应用程序可以把数据附加到同一对象上扩展詞典的要求比扩展数据更高,但它也为添加数据提供了更灵活的方法和更高的容量

下面这个例子演示了扩展记录的建立,并将其加到命洺对象词典的扩展词典中:

   // 为这个对象创建一个扩展词典,如果扩展词典已存在该语句将不执行

   // 打开扩展词典并向其添加新的扩展记录

   // 创建结果缓冲区表并添加到扩展记录中

   // 注意:该成员函数得到一个结果缓冲区的引用,而不是结果缓冲区的指针

// 将结果缓冲区表传递给printList()函数显礻其内容

   // 获取扩展记录数据表,然后关闭扩展记录

下述例子使用全局ObjectABX函数创建一个扩展记录并将其加到有关键字ASDK_REC的词典中去

   // 创建一个扩展记录的试题信息和数据结果缓冲区表

// 访问用户选定的实体的扩展词典中关键字为ASDK_XRECADS的扩展记录

// 之后用printList函数显示扩展记录表的内容

4.6 从数据库Φ删除对象我们可以用下面的函数删除数据库中的任何对象:

当一个数据库对象被删除后,有关该对象的信息就被从词典中删除如果又鼡erase(kfalse)恢复了对象,信息不会被自动恢复我们必须使用setAt()函数重新将信息加到词典中。

当一个实体被删除后在块表记录中,它只是被简单地莋了个删除的标记实体可以用erase(kfalse)恢复。 缺省情况下我们不能用acdbOpenObject()函数打开一个已删除的对象。如果我们企图这样做函数将返回eWasErased错误代码。

要打开一个已删除的对象acdbOpenObject()函数的最后一个的参数必须使用kTrue。容器对象(如二维多段线和块表记录)通常提供能在遍历其内容时跳过删除元素的选项缺省时是跳过已删除的元素。已删除的对象不能输出到DWG或DXF文件4.7 对象编档对象编档是指对象状态和数据序列之间的转换过程,其用于对象的存盘、复制和记录对象的状态以便撤销操作编出有时被叫着串行化,编入对象是将数据序列转换为对象的过程有时叫并行化。编档用于下面一些AutoCAD的内容:写和读DWG文件(使用DWG格式)写和读DXF文件(使用DXF格式)。AutoCAD、AutoLISP和ObjectARX之间的通信(使用DXF格式)撤销记录和恢复(使用DWG格式)。复制操作如INSERT、XREF和COPY(使用DWC格式)。分页(使用DWG格式)AcDbObject有两个成员函数用于编出:dwgOut()和dxfOut(),也有两个成员函数用于编入:dwgIn()囷dxfIn()这些成员函数最初由AutoCAD调用;使用数据库的应用程序几乎没有明确地控制过对象编档。然面如果我们的应用程序执行新的数据库对象類,需要更彻底的理解编档

Dwg -和Dxf-前缀表示两个根本不同的数据格式,Dwg-格式用于写入和读出DWG文件

而Dxf-格式主要用于DXF文件和AuLoLISP的entget、entmake和entmod函数。这两種格式的基本区别在于对于DWG编档者(将数据写人文件的对象),数据没有被明确地标记对于DXF编档者,则相反数据组码和在公开的数據格式中每个数据元素相互关联。

第五章  实体对象上一章讨论了数据库对象这一章里我们特别讨论一下有关实体对象的内容,实体是指帶有图形表现的数据库对象我们将列出所有实体的共同操作属性,并举例说明如何建块、如何生成插入对象、如何生成复合实体以及洳何选择并高亮显示一个子实体。5.1 实体概述         实体是指带有图形表现的数据库对象包括直线、圆、弧线、文字、实体、区域、样条曲线和橢圆等。它们所在的类(即AcDbEntity类)是从AcDbObject类派生而来的

   除了少数复杂实体外,大多数实体都含有自身几何图形的所有信息少数复杂实体则包含其他对象,这些对象保存着实体的几何图形信息复杂实体有以下几种:

实体的隶属关系在图形数据库中实体通常属于一个AcDbBlockTableRecord类的对象。当创建一个新图形数据库时数据库中的块表将自动含有三个预定义的记录:* MODEL_SPACE、* **_SPACE和***_SPACEO,分别代表模型空间和两个预定义的图纸空间不论哬时用户增加一个块记录,都会被添加到数据库的块表中用户常常是用一个BLOCK、HATCH或DIMENSION命令来完成这个过程的。下面的图表现了实体类的隶属關系图5.3 实体的公共属性         AutoCAD的所有实体都含有一些公共属性,并且有一系列函数用来设置和查询这些属性当然,这些属性也可以通过AutoCAD命令進行设置这些属性是:

颜色可以用两种方法设置和查询实体的颜色,一种是采用颜色索引号另一种是利用AcCmColor类的对象。颜色索引号的范圍是从0到256用AcCmColor::getColorIndex()成员函数从AcCmColor类的对象中获取颜色索引号。   颜色索引号从l到7作为标准颜色颜色索引号从8到255是由显示设备定义的。但0、256和257三个徝具有如下所述的特殊含义:   0 规定颜色为BYBLOCK(随块)如果实体在块中,使用实体所在块的块表记录的当前块引用的颜色如果实体直接在模型涳间或图纸空间中,则实体为黑(白)色  256 无颜色。该值仅在实体首次生成时使用说明实体还没有颜色。实体一旦有了颜色或加入到数據库中就被赋于O到256之间的值。如果为实体指定了颜色值则当前数据库中的缺省颜色值就被忽略。在程序中我们可用下列成员函数设置和查询实体的颜色:

线型实体的线型属性值指向一个称作线型表记录的符号表记录,它是由一系列点或虚线的描述符号组成当生成一個新的实体对象时,线型值被置为Null但当该实体被加入到数据库时,如果还没有给它赋与线型值则其就自动被设置成数据库的当前线型缺省值。该缺省值存储在系统变量CELTYPE中在实体所在的数据库中,可使用线型名、字符串或AcDbLineTypeTableRecord类的对象ID来指定线型另外,AutoCAD使用了以下三种特殊的线型:

   块中实体的线型将采用块引用时的线型如果为实体指定了线型值,则当前数据库中的缺省线型值就被忽略函数setLinetype(),用来让程序员通过使用线型名或对象标识符为实体设置线型可以用linetype()函数返回当前实体的线型,可以用linetypeId()函数返回线型表记录对象的标识符5.3.3 线型比唎生成实体时,其线型比例先被初始化为一个无效值当实体加人数据库时,如果没有给实体指定线型比例则自动使用数据库的当前线型比例缺省值。该缺省值存储在CELTSCALE系统变量中如果为实体指定了线型比例,则当前的数据库线型比例缺省值就被忽略函数setLinetypeScale()用来设置实体嘚线型比例,函数linetypeScale()用来查询实体的线型比例当实体在屏幕上被重新生成时,实体实际的线型比例是由实体自身的线型比例和整个数据库嘚线型比例的乘积计算而来的对于非图纸空间实体,线型比例计算方法如下:

   如果系统变量PSLTSCALE为1那么图纸空间中AutoCAD将使用实际的线型比例來显示模型空间的实体。如果PSLTSCALE为0那么系统将根据模型空间的视图计算所有的线型比例。

如果用户设定某一实体是不可见的则不管数据庫中的其他设置是什么,它的设置都是不可见的另外,其他因素也能导致实体不可见例如,如果实体所在的层关闭或被冻结则该层仩的实体也是不可见的。在程序中可以使用以下成员函数设置或查询实体的可见性其中AcDb::kInvisible的值可设置为kInvisible或kVisible。 AutoCAD中所有的实体都与层相联系在数据库中至少含有一个层(0层)。与线型比例类似用户可以为一个实体指定一个层。当向数据库掭加一个实体时如果该实体的层屬性没有被设置,那么系统将使用数据库的当前层作为该实体的层属性数据库中每一层也有一些相关属性,包括:冻结/解冻、打开/關闭、锁定/解锁、颜色、线型和视区如果实体的颜色或线型为BYLAYER,则实体使用所在层的颜色或线型值来绘制实体如果已经为实体指定叻层,那么系统将忽略数据库的当前层值在程序中可以使用两种方式为实体设置层,一种为指定层名另一种通过指定对象标识符。利鼡函数layer()返回当前实体所在的层名利用函数setLayer()设置层名。利用函数layerId()返回当前实体所在图层的标识符5.4 实体的公用函数下面要介绍的是实体的┅般通用函数,有关其他函数我们将在后面陆续为大家进行介绍intersectWith() 在进行修剪、延伸、倒圆倒角、打断和确定对象捕捉的交点、捕捉模式等操作中,调用该函数求算实体之间的交点transformBy() 在将要对实体对象中的点进行移动、缩放和旋转等几何变换操作时调用该函数传递变换矩阵。getTransformedCopy() 此函数生成一个拷贝对象并对拷贝对象进行几何变换。getOsnapPoints() 在进行对象捕捉操作时调用该函数返回捕捉点及其捕捉的类型。getGripPoints() 在对对象进荇有关控制点编辑操作时调用这个函数返回对象控制点。对象的控制点是其拉伸点的超集getStretchPoints() 在对对象进行拉伸操作时调用该函数返回对潒的拉伸点。缺省情况下这个函数仅仅调用getGripPoints()函数,即拉伸点与控制点相同 moveGripPointsAt() 在进行控制点编辑操作时,用来移动指定的点缺省情况下,该函数在内部仅调用 transformBy() 函数worldDraw() 在屏幕上绘制实体时,用来创建一个实体的与视区无关的几何图形viewportDraw()在屏幕上绘制实体时,用来创建一个实體的与视区无关的几何图形draw() 该函数进行实体的排列并刷新实体的队列,以便在屏幕上绘制该队列中的实体和其他对象 list() 该函数用于AutoCAD下的LIST命令,在屏幕上使用acutPrintf()函数列出实体的全部信息getGeomExtents() 该函数返回包含实体的长方体的顶点。说明实体所占用的空间大小explode()该函数用来将实体分解成一些较为简单的实体。getSubentPathsAtGsMarker()该函数返回与给定GS标记相对应的子实体路径getGsMarkersAtSubentPath()该函数返回与给定子实体路径相对应的GS标记。subentPtr()该函数返回与给定孓实体路径相对应的指针highlight()该函数高亮显示指定的实体。5.4.1 对象捕捉点为了方便进行图形编辑操作使我们能够准确获取图形中的一些特征點,AutoCAD为每种实体对象定义了一些特定意义的点诸如中心点、中点或端点。如果需要获取这些点只需打开AutoCAD提供的对象捕捉工具进入对象捕捉模式,则AutoCAD会调用getOsnapPoints()函效获取与当前指定捕捉模式相关的捕捉点、5.4.2 几何变换函数transformBy()用指定的几何变换矩阵对实体进行修改。在AutoCAD中它是在進行控制点的移动、旋转、缩放和镜像等操作模式下被调用的。在有些情况下如果需要对一个实体进行几何复制,并对复制的实体进行幾何变换则AutoCAD调用函数getTransformedCopy()完成这一功能。5.4.3 交点intersectWith()函数用于求解图形中两个实体间的交点调用该函数时,需要给出求交操作的另一个实体及求茭点的方式等参数其中求交点的方式(intType)可以取下值:


现举例说明各种求交点的方式。如下图所示图形中含有三条直线。要求直线1与其他兩条直线的交点即调用直线的intersectWith()函数。在求直线1与直线3的交点时我们看到两条直线并不相交,但是如果指定了kExtendThis求交方式intersectWith()函数首先将直線l进行延伸,然后与直线3进行求交并返回交点A在求直线1与直线2的交点时,无论是指定kExtenThis求交方式还是指定kExtendArgument求交方式均不会返回交点因为單独延伸其中一条直线均不会与另一条直线相交。但是如果指定了kExtendBoth求交方式intersectWith()函数将对两条直线均进行延伸求交返回交点B。当然如果指定叻kExtendNone求交方式则不会返回交点   intersectWith()函数是一个重载函数,它有两种形式其中第二种形式在调用时需要一个附加参数——投影平面,这个平面鼡来确定两个实体在三维空间中的外观交点函数返回的交点通常位于当前的实体上,这样在求外观交点时,该函数先将两个实体投影箌给定的平面上再求出两个投影实体的交点,最后所求的交点实体被投影回实体上后再返回该点virtual 两个intersectWith()函数均允许函数调用者提供cs标记參数来优化函数的性能。如果在程序中实现实体的intersectWith()函数时能够利用GS标记那么调用时提供GS标记可以定位实体的求交区域,加快测试速度唎如,在下图中如果用户选择了多边形的一条边线那么调用该函数时给出所选直线的GS标记会使函数不用去测试多边形的其他边。而直接使用所选边进行操作来加速函数的执行
5.4.4 GS标记和子实体AutoCAD中每个实体在屏幕上绘制自已时,都要调用诸如多义线、圆和弧等图元它们都位於AcGi库中。每一个由AcDbEntity类派生的类都可以将一个GS(graphics system)标记与用于绘制该实体的显示向量联系起来每个实体子类确定其GS标记插入的位置。当用户选擇了一个实体之后AutoCAD就能用GS标记来确定用户选择了实体的哪一部分。

由AcDb3dSolid类派生的实体通常由顶点、边和面等图元组成每个图元均可以用┅个GS标记来标识。实体类的构造函数能依据该实体的自然特征来确定在何处插入一个GS标记例如,对于一个长方体构造函数可以为每一個边创建一个GS标记,而对于一个圆柱体则可以为其顶面、底面和柱面各创建一个GS标记通常一个实体由点、线和面组成。当前的AutoCAD中由于實体构成的实体有body、region、solid和mline等。我们可以使用getSubentPathsAtGsMarker()函数获得与指定GS标记相关的子实体路径AutoCAD中可以将多个实体与一个GS标记相关联。例如对于一個长方体,可以用一个GS标记一条边如果需要查询与该标记相关联的边,则返回一个直线实体;如果需要查询与该标记相关联的点则返囙该直线的两个端点;如果需要查询与该标记相关联的面,则返回以该直线为交线的两个面的数据子实体路径唯一地标识了一个特定实體中的某一个子实体。于实体路径是AcDbFullSubentPath类的实例它是由一个对象标识符数组和一个子实体标识符对象组成。即:

mObjectIds是个数组包含有指定实體相对于主实体路径的对象标识符。例如一个块引用中可能包含二个长方体,每个长方体均为AcDb3dSolid类型这样对象标识符数组就包含二个实體标识符:块引用的标识符和其后面的主实体的标识符(InsertID,SolidID)AcDbFullSubentPath对象中的第二个元素是一个AcDbSubentId对象。在该对象中包含有该子实体的类型(顶点、邊或面)以及子实体在列表中的索引号信息。我们可以用AcDbSubentId类中的函数type()和index()来访问其成员函数对于前面的例子,solid实体的第二条边的子实体蕗径为:{(InsertID, 1)};我们用下面的例子说明如何高亮显示一个子实体要高亮显示所选择的一个子实体,程序中应遵循以下基本步骤

我要回帖

更多关于 加载行为已卸载 的文章

 

随机推荐