objectArx --- ADS篇
目录一、基本概念
1.1 基本定义
1.2 关键类型
二、数据类型
2.1 ads数据类型
2.2 类型转换
2.2.1 浮点数 与 字符串
2.2.2 角值 转换
2.2 结果缓冲区
2.2.1 定义
2.2.2 结果类型码
2.2.3 简单使用
2.2.4 链表命令
三、用户交互
3.1 函数返回码
3.2 常用
3.3 acedGetXXX函数
3.3.1 常规
3.3.2 acedInitGet
3.3.3 选择实体
3.4 选择集
3.4.1 常用函数
3.4.2 acedSSGet函数详解
四、系统变量
一、基本概念
1.1 基本定义
ADS:autocad design system 简称,早期CAD面向过程编程系统,现在整合入objectarx中
功能:对CAD全局参数编辑,提供与用户交互函数,头文件:adslib.h、adsdlg.h,默认已加入
1.2 关键类型
类型定义
类型名 特性
对象id
AcDbObjectId 在一个CAD进程中管理多个CAD文件,所有打开的数据库对象在内存中都有唯一的id,每个对象在每次加载后id值都不同,此对象是以下各类型的中介
实体名
ads采用name 为ADS存储实体对象的临时变量,关闭文件即丢失,此对象通常用来接收用户选择实体或选择集
句柄
AcDbHandle 数据库文件dwg真实标记实体的数据类型,每次打开文件,同一实体,句柄不变
转换关系
二、数据类型
2.1 ads数据类型
包含:浮点型、整型、字符串、点、实体名
代码
// 整形
int num = 5;
// 打印写法:跟C语言printf一样
acutPrintf(采用T("%d\n"), num);
// 浮点型:typedef double ads采用real;
ads采用real r1=3.14;
acutPrintf(采用T("%0.3f\n"), r1);
// 字符串型:以下二者可相互转换
ACHAR * str = 采用T("兼容性最好\n");
CString cstr = 采用T("此类为mfc项目默认字符串,函数更友好\n");
acutPrintf(str);
acutPrintf(cstr);
// 点:typedef ads采用real ads采用point;
ads采用point pt1, pt2;
// 三个坐标不可留空
pt1 = pt1 = pt1 = 1.0;
// 点覆盖式赋值:用pt1赋值pt2
ads采用point采用set(pt1, pt2);
acutPrintf(采用T("%0.3f\n"),pt2);
// 实体名(由鼠标选择赋值),通常由其获得对象id
// typedef int64采用t ads采用name;
ads采用name en, en1;
// 将en0深拷贝给en1
ads采用name采用set(en0, en1);
2.2 类型转换
2.2.1 浮点数 与 字符串
代码示例
ads采用real rel = 1.23456789;
ACHAR str;
// 浮点数转字符串:浮点数、转换模式、小数位数、待接收字符串
// 转换正常ret为RTNORM,否则见第3.1节
int ret = acdbRToS(rel, 1, 3, str);
acutPrintf(str);
// 字符串转浮点数:字符串、转换模式、浮点数(注意取地址符)
ACHAR str采用a= 采用T("9.87654");
// ret用于存储结果类型码(本篇3.1) 判断是否正常转换:RTNORM为正常
// 转换正常ret为RTNORM,否则见第3.1节
ret = acdbDisToF(str采用a,1,&rel);
acutPrintf(采用T("\n%f"),rel);
转换模式:
1科学记数法:结果为1.235E+00
2十进制:结果为1.235
3工程、4建筑:略
5分数:结果为1 1/4
2.2.2 角值 转换
弧度 转 字符串(由控制符 控制 转换格式)
// 函数acdbAngToS参数:弧度值、控制符、精度、字符串指针
// 转换正常ret为RTNORM,否则见第3.1节
ACHAR str;
// 0弧度转角度
int ret = acdbAngToS(MathUtil::PI() / 4, 0, 4, str);
// 返回:45.0000,0都省略了
acutPrintf(采用T("\n%s"),str);
// 1弧度转角度
ret = acdbAngToS(MathUtil::PI()/4, 1, 4, str);
// 返回:45d0'0"
acutPrintf(采用T("\n%s"), str);
// 2弧度转工程
ret =acdbAngToS(MathUtil::PI() / 4, 2, 4, str);
// 返回:50g
acutPrintf(采用T("\n%s"), str);
// 3弧度(ads采用real)转弧度(字符串)(带r标识)
ret =acdbAngToS(MathUtil::PI() / 4, 3, 4, str);
// 返回:0.7854r
acutPrintf(采用T("\n%s"), str);
角 转 浮点数
// 函数acdbAngToF参数:字符串(弧度/角度值)、控制符、浮点数
// 转换正常ret为RTNORM,否则见第3.1节
ads采用real rel;
// 0:百分角度 转弧度
int ret = acdbAngToF(采用T("45"), 0, &rel);
acutPrintf(采用T("\n%.4f"),rel);
// 1:度分秒角度 转弧度
ret = acdbAngToF(采用T("45d0'0\""), 1, &rel);
acutPrintf(采用T("\n%.4f"), rel);
// 2:工程 转弧度
ret = acdbAngToF(采用T("50g"), 2, &rel);
acutPrintf(采用T("\n%.4f"), rel);
// 3:弧度(带r标识) 转弧度(不含r标识)
ret = acdbAngToF(采用T("0.7854r"), 3, &rel);
acutPrintf(采用T("\n%.4f"), rel);
关系:acdbAngTo与acdbAngToS为互补函数
2.2 结果缓冲区
功能:CAD中数据种类多样,需要有一个进行数据临时交换与存储的媒介
2.2.1 定义
源文件声明
// 结果缓冲区节点为结构体
struct resbuf {
// 用于构造单链表,未设置则为NULL
struct resbuf *rbnext;
// 用于定义ads采用u采用val 的类型
short restype;
// 联合体:用于存储具体值
union ads采用u采用val resval;
};
// 联合体ads采用u采用val的定义
union ads采用u采用val {
// 浮点型:常用
ads采用real rreal;
// 点:常用
ads采用real rpoint;
// 短整型:常用
short rint;
// 字符串:常用
ACHAR *rstring;
// 剩下不常用略,可以转到结果缓冲区查看
};
2.2.2 结果类型码
类型码列表
#define RTNONE 5000 /* 无结果 */
#define RTREAL 5001 /* 浮点型 */
#define RTPOINT 5002 /* 2D点 */
#define RTSHORT 5003 /* 短整型 */
#define RTANG 5004 /* 角度 */
#define RTSTR 5005 /* 字符串 */
#define RTENAME 5006 /* 实体名 */
#define RTPICKS 5007 /* 选择集 */
#define RTORINT 5008 /* 方向*/
#define RT3DPOINT 5009 /* 3D点 */
#define RTLONG 5010 /* 长整型 */
#define RTVOID 5014 /* 空白符号 */
#define RTLB 5016 /* 列表开始 */
#define RTLE 5017 /* 列表结束 */
#define RTDOTE 5018 /* 点对 */
#define RTNIL 5019 /* 零*/
#define RTDXF0 5020 /* DXF码,仅供ads采用buildlist使用 */
#define RTRESBUF5023 /* 结果缓冲区 */
用于指定结果缓冲区节点的值类型
组码:特殊的类型码,≤1071的类型码有特殊含义,传送门
2.2.3 简单使用
结果缓冲区链表
voidtest()
{ // 自制结果缓冲区的迭代器,提取链表每个节点
resbuf* rb采用iter;
resbuf* cmdlist;
ads采用point pt1 = { 1,1,1 };
int num = 3;
// 函数:构建结果缓冲区链表
cmdlist = acutBuildList(RTSTR, 采用T("test"),
RTPOINT,pt1,
RTSHORT,num,
RTNONE);
// 拷贝 链表 首节点 的 指针 给 迭代器
rb采用iter = cmdlist;
// rb采用iter的指针不为空
while (rb采用iter != NULL)
{
acutPrintf(采用T("结果类型码:%d\n"), rb采用iter->restype);
switch (rb采用iter->restype)
{
case RTSTR:
acutPrintf(采用T("值为:%s\n"), rb采用iter->resval.rstring);
break;
case RTPOINT:
acutPrintf(采用T("值为:%f\n"), rb采用iter->resval.rpoint);
break;
case RTSHORT:
acutPrintf(采用T("值为:%d\n"), rb采用iter->resval.rint);
break;
}
rb采用iter = rb采用iter->rbnext;
}
acutPrintf(采用T("执行完毕\n"));
// 手动释放结果缓冲区
acutRelRb(rb采用iter);
acutRelRb(cmdlist);
}
2.2.4 链表命令
函数用法
// 必须包含头文件
#include "acedCmdNF.h"
// 模拟人工输入命令:隐式构建结果缓冲区链表
acedCommandS(RTSTR, 采用T("circle"),
RTSTR, 采用T("0,0"),
RTSTR, 采用T("300"),
RTNONE);
三、用户交互
3.1 函数返回码
功能:用于标识函数执行情况
常用返回码列表(重要)
#define RTNORM 5100 /* 正常 */
#define RTERROR (-5001) // 其他错误
#define RTCAN (-5002) // 用户按Ctl-C或ECS
#define RTREJ (-5003) // AutoCAD拒绝的请求--无效
#define RTFAIL (-5004) // 连接失败 -- Lisp脚本可能崩溃了
#define RTKWORD (-5005) // 来自 getxxx() 的关键字
#define RTINPUTTRUNCATED (-5008) // 输入不完全适合缓冲区
3.2 常用
弹出警告框:acedAlert(采用T("弹出警告框"));
命令行打印:acutPrintf(采用T("跟C语言printf函数一样\n"));
捕捉离光标最近的中点、端点、中心点(最好关掉对象捕捉)
acedOsnap(pt, 采用T("midp,endp,center"), pt1);,pt是传入的点,pt1是返回的点
遍历全图实体(包括隐藏实体)
ads采用name en0, en1;
// 遍历全图:首参数为null,则获取第一个元素的ads采用name
if (acdbEntNext(NULL, en0) != RTNORM)
return;
// acdbEntNext遍历链表,以首参数为参照,获取第二个参数ads采用name
do
{ // 从ads采用name获取对象id
AcDbObjectId id;
acdbGetObjectId(id, en0);
// ld 长整型
acutPrintf(采用T("\n对象id为:%ld"), id);
// acedUsrBrk()用于判断用户是否按下esc键
if (acedUsrBrk())
return;
// 将en0深拷贝给en1
ads采用name采用set(en0, en1);
// en1变为参考点,en0值被覆盖,从而获取下一个链表节点的ads采用name
} while (acdbEntNext(en1, en0) == RTNORM);
3.3 acedGetXXX函数
3.3.1 常规
获取整型:acedGetInt
// 获取整型:提示字符串、变量地址(看函数头文件)
int num;
if (acedGetInt(采用T("\n请输入整数:"), &num) == RTNORM)
acutPrintf(采用T("\n整数为:%d"),num);
获取浮点数:acedGetReal
// 获取浮点数:提示字符串、变量地址
ads采用real num采用real;
if (acedGetReal(采用T("\n请输入浮点数:"), &num采用real) == RTNORM)
acutPrintf(采用T("\n浮点数为:%0.3f"), num采用real);
获取字符串:acedGetString
// 获得字符串:是否允许空格(1允许)、提示字符串、字符串指针、字符串变量长度(包括结尾\0)
// 如果超出长度ret返回RTINPUTTRUNCATED,超出的字符串丢弃,正常返回RTNORM
ACHAR str;
int ret = acedGetString(0, 采用T("\n请输入字符串:"), str, 6);
if ( ret == RTNORM)
acutPrintf(采用T("\n字符串为:%s"), str);
else
{
acutPrintf(采用T("\n结果返回码为:%d"), ret);
}
// 字符串正则匹配函数:待校验字符串指针、匹配规则
if (acutWcMatch(str, 采用T("ro*b"))==RTNORM) {
acedAlert(采用T("此字符串匹配了定义的正则表达式"));
}
获取点坐标:acedGetPoint
// 获取点坐标:是否允许空格(1允许)、提示字符串、点变量
ads采用point pt;
if (acedGetPoint(0, 采用T("\n请选取点:"), pt) == RTNORM)
acutPrintf(采用T("\n点为:%f,%f"), pt,pt);
// 极坐标法获得点坐标:基点ads采用point、弧度ads采用real,极半径ads采用real,返回点ads采用point
acutPolar(pt,ang, 100.0, pt3);
获取夹角弧度:acedGetAngle
// 获取与三点钟方向夹角弧度:基准点(若为NULL则在屏幕上点)、提示字符串、接收弧度值
ads采用point pt采用ang = { 0,0,0 };
ads采用real ang;
if (acedGetAngle(pt采用ang, 采用T("\n请角度点:"), &ang) == RTNORM)
acutPrintf(采用T("\n角弧度为:%f"), ang);
// 方法2:直接计算pt与pt1线段与x轴正向夹角弧度
ads采用real ang = acutAngle(pt, pt1);
方框内角度:非弧度,会跟着十字光标动态变化
获取两点间距离:acedGetDist
// 返回屏幕上两点间距离:基准点(若为NULL则在屏幕上点)、提示字符串,
ads采用real distance;
if (acedGetDist(NULL, 采用T("\n请选择点:"), &distance) == RTNORM)
acutPrintf(采用T("\n距离为:%f"), distance);
3.3.2 acedInitGet
功能一:循环检测用户非法输入
关键字代码:
// 过滤用户非法输入,输入符合要求才能通过,可esc退出
acedInitGet(RSG采用NONEG + RSG采用NOZERO + RSG采用NONULL, NULL);
int num;
if (acedGetInt(采用T("\n请输入整数:"), &num) == RTNORM)
acutPrintf(采用T("\n整数为:%d"),num);
控制位开关:
非负:RSG采用NONEG ,非零 RSG采用NOZERO,非空RSG采用NONULL
开启橡皮筋或虚矩形追踪RSG采用DASH
去掉Z坐标:RSG采用2D,仅用于acedGetDist
特点:仅对紧跟着的那个acedGetXXX函数起效
功能二:关键字选项控制
// 禁止输入空,并明确关键字为以下四个(空格分隔)
acedInitGet(RSG采用NONULL, 采用T("1 2 3 4"));
ACHAR kw;
// 这是控制关键字显示:见下面效果图
acedGetKword(采用T("\n选择一个关键字:"), kw);
switch (tc)
{
case RTCAN:
acutPrintf(采用T("\n你取消了输入"));
break;
case RTNORM:
if (采用tcscmp(kw, 采用T("1")) == 0)
{ // 可以通过关键字跳转其他程序处理后续
acutPrintf(采用T("\n你选择了1"));
break;
}
else if (采用tcscmp(kw, 采用T("2")) == 0)
{
acutPrintf(采用T("\n你选择了2"));
break;
}
else if (采用tcscmp(kw, 采用T("3")) == 0)
{
acutPrintf(采用T("\n你选择了3"));
break;
}
default:
break;
}
acutPrintf(采用T("\n程序结束"));
3.3.3 选择实体
功能:获取实体ads采用name和选择点
代码示例
// 获取与三点钟方向夹角弧度:基准点(若为NULL则在屏幕上点)、提示字符串、接收弧度值
ads采用point pt;
ads采用name en;
if (acedEntSel(NULL, en, pt) == RTNORM)
acutPrintf(采用T("点选处为:%f,%f"), pt, pt);
常用函数
ads采用name en1, en2;
ads采用point pt1, pt2;
acedEntSel(NULL, en1, pt1);
acedEntSel(NULL, en2, pt2);
// 判断ads采用name是否相等
if (acdbNameEqual(en1, en2))
acutPrintf(采用T("\n选择了同一个实体"));
else
acutPrintf(采用T("\n选择了两个实体"));
// 清空ads采用name值
acdbNameClear(en2);
// 判断ads采用name是否为空,为空则为true
if (acdbNameNil(en2))
acutPrintf(采用T("\n清除成功"));
// 用en2给en1赋值
acdbNameSet(en1,en2);
if (acdbNameEqual(en1, en2))
acutPrintf(采用T("\n赋值成功"));
3.4 选择集
定义:实体的有名集合
特性:
非互斥性:一个实体可以包含在不同选择集中
唯一性:多次选择一个实体,选择集中只包含一次
易用性:可空,可手动框选添加实体进选择集
3.4.1 常用函数
代码示例
// 图上框选创建选择集
ads采用nameen1, en2, ss1;
acedSSGet(NULL, NULL, NULL, NULL, ss1);
// 获得选择集长度
int len;
acedSSLength(ss1, &len);
acutPrintf(采用T("\n初始选择集实体个数为%d"), len);
// 获取 选择集 首元素 的ads采用name赋值en:一般用在for循环里
acedSSName(ss1,0,en1);
// 判断实体是否在选择集里
if(acedSSMemb(en1, ss1))
acutPrintf(采用T("\n实体在选择集中"));
// 获取实体en2
acedEntSel(NULL, en2, NULL);
// 将实体添加进现有选择集:第2、3参数均为选择集
acedSSAdd(en2,ss1,ss1);
acedSSLength(ss1, &len);
acutPrintf(采用T("\n新增后选择集实体个数为%d"), len);
// 从选择集中删除实体,实体还在图中
acedSSDel(en1, ss1);
acedSSLength(ss1, &len);
acutPrintf(采用T("\n删除后选择集实体个数为%d"), len);
// 释放选择集:选择集数量有上限,及时释放
acedSSFree(ss1);
acutPrintf(采用T("\n程序结束"));
效果
3.4.2 acedSSGet函数详解
常用
写法 注释
acedSSGet(采用T("A"), NULL, NULL, NULL, ss1); 选择全部实体
acedSSGet(采用T("W"), pt1, pt2, NULL, ss1); 矩形框选window:包住的、跟边线重合的实体
acedSSGet(采用T("C"), pt1, pt2, NULL, ss1); 矩形叉选crossing:包住的、跟边线重合、相交的实体
围区点列表
点列表框选:acedSSGet(采用T("WP"), pointlist, NULL, NULL, ss1);
点列表叉选:acedSSGet(采用T("CP"), pointlist, NULL, NULL, ss1);
1
2
// 图上框选创建选择集
ads采用namess1;
ads采用point pt1 = { 0,0,0 },
pt2 = { 100,100,0 },
pt3 = { 100,0,0 },
pt4 = { 0,100,0 };
// 点列表构建
resbuf * pointlist;
pointlist = acutBuildList(RT3DPOINT, pt1,
RT3DPOINT, pt3,
RT3DPOINT, pt2,
RT3DPOINT, pt4,
RTNONE); // 必须有这个,否则cad崩溃
// CP可以换成WP或F(栏选:仅选择跟边线交叉的实体),
// 点列首尾自动闭合,P为Polygon
acedSSGet(采用T("CP"), pointlist, NULL, NULL, ss1);
// 显示选择集内实体个数
int len;
acedSSLength(ss1, &len);
acutPrintf(采用T("\n选择集内实体个数为%d"), len);
// 释放选择集、释放结果缓冲区
acedSSFree(ss1);
acutRelRb(pointlist);
acutPrintf(采用T("程序结束"));
过滤选择集
常规过滤
ads采用namess1;
resbuf * filter;
// 构建筛选器:RTDXF0为实体类型组码、8为图层组码、结尾要有RTNONE
filter = acutBuildList(RTDXF0, 采用T("CIRCLE"), 8, 采用T("0"), RTNONE);
// X 开启筛选器,filter为筛选器缓冲区指针
acedSSGet(采用T("X"), NULL, NULL, filter, ss1);
// 打印选择集内实体数
int len;
acedSSLength(ss1, &len);
acutPrintf(采用T("\n选择集内实体个数为%d"), len);
acedSSFree(ss1);
acutRelRb(filter);
acutPrintf(采用T("程序结束"));
关系过滤 filter写法
// -4:条件运算符,40:圆半径组码(必须是100.0有小数)
filter = acutBuildList(RTDXF0, 采用T("CIRCLE"),
-4, 采用T(">="),
40, 100.0,
RTNONE);
条件过滤 filter写法
// 为了好读,加了缩进:选取所有0层上的直线和所有半径为100的圆
filter = acutBuildList(
// or内为或关系:内部有一个就选择
-4, 采用T("<OR"),
// and内为与关系,一个整体
-4, 采用T("<AND"),
RTDXF0, 采用T("LINE"), 8, 采用T("0"),
-4, 采用T("AND>"),
// and内为与关系,一个整体
-4, 采用T("<AND"),
RTDXF0, 采用T("CIRCLE"), 40, 100.0,
-4, 采用T("AND>"),
-4, 采用T("OR>"),
RTNONE);
四、系统变量
浮点型
// 对结果缓冲区 浮点型 操作
resbuf rb, rb1;
// 获取系统变量:圆角半径
acedGetVar(采用T("FILLETRAD"), &rb);
acutPrintf(采用T("系统变量值为:%.3f"), rb.resval.rreal);
// 给自定义结果缓冲区变量赋值,rb1.next默认为null
rb1.restype = RTREAL;
rb1.resval.rreal = 1.0;
// 提取并操作系统变量值
if (rb.resval.rreal < 1.0)
// 设置系统变量值:传入自定义结果缓冲区变量
if (acedSetVar(采用T("FILLETRAD"), &rb1) != RTNORM)
return;
整型
// 对结果缓冲区 整型 操作
resbuf rb2, rb3;
acedGetVar(采用T("CMDECHO"), &rb2);
acutPrintf(采用T("\n当前的CMECHO变量的值为%d."), rb2.resval.rint);
// 给自定义结果缓冲区变量赋值,rb1.next默认为null
rb3.restype = RTSHORT;
rb3.resval.rint = 0;
if (acedSetVar(采用T("CMDECHO"), &rb3) == RTNORM)
{
acutPrintf(采用T("\n系统变量值CMDECHO,已修改,现在的值为%d"), rb3.resval.rint);
}
else
acutPrintf(采用T("\n设置系统变量值失败!"));
字符串型
// 对结果缓冲区 字符串 操作
resbuf rb4, rb5;
// 获取系统变量:字体样式
acedGetVar(采用T("TEXTSTYLE"), &rb4);
if (rb4.resval.rstring != NULL)
{ // 打印当前字体样式、随后释放结果缓冲区
acutPrintf(采用T("\n当前的文字样式是%s"), rb4.resval.rstring);
acdbFree(rb4.resval.rstring);
// 自定义结果缓冲区rb5,类型
rb5.restype = RTSTR;
// C语言的分配内存空间,判断分配成功
// 指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
// mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用
if ((rb5.resval.rstring = (ACHAR *)malloc(20)) != NULL)
{ // 给结果缓冲区赋值
采用tcscpy(rb5.resval.rstring, 采用T("STANDARD"));
// 用自定义的设置结果缓冲区
acedSetVar(采用T("TEXTSTYLE"), &rb5);
acutPrintf(采用T("\n新修改的文字样式是:%s"), rb5.resval.rstring);
acdbFree(rb5.resval.rstring);
}
else
acedAlert(采用T("内存不足!"));
}
点坐标
// 对结果缓冲区点 坐标 操作
resbuf rb6, rb7;
ads采用real lx, ly;
// 获取系统变量:当前图形最大点、最小点
acedGetVar(采用T("EXTMAX"), &rb6);
acedGetVar(采用T("EXTMIN"), &rb7);
// 结果缓冲区点提取
lx = rb6.resval.rpoint - rb7.resval.rpoint;
ly = rb6.resval.rpoint - rb7.resval.rpoint;
acutPrintf(采用T("\n当前图形的水平长度和垂直长度分别为<%.3f , %.3f>"), lx, ly);
页:
[1]