ObjectARX(VC++)-ADSRX和用户交互-acedCommand函数和结果缓冲区

创建一个ObjectARX工程,名称为Resbuf。

一、注册一个新命令AddCircle1

(1)

———————

 (2)代码实现:

	static void AAAMyGroupAddCircle1() {
		// Put your command code here

		//声明ADS变量
		ads_point ptCenter = { 0, 0, 0 };//圆心
		ads_real radius = 10; //半径

		//调用acedCommand函数创建圆
		acedCommandS(RTSTR, TEXT("Circle"),
			RTPOINT, ptCenter,
			RTREAL, radius,
			RTNONE);
	}

(3)注意:

ObjectARX已经将acedCommand函数升级为acedCommandS函数,使用该函数需要添加头文件”acedCmdNF.h”。

否则会报错:

“MustSwitchTo_acedCommandC_or_acedCommandS”: 未声明的标识符

(4)   acedCommandS函数:

  与语法兼容的acedCommand替换,用于“完整命令”,而不是部分命令。这个命令从它自己的私有命令行处理器开始,在“命令:”提示符初始化。这些命令以与acedCommand相同的方式执行,除了当提供的输入全部被执行时,私有命令行处理器被删除,并且以前的命令行处理器与调用时没有变化。模式和透明的“内置”命令可能不会被嵌套。

(5)效果

使用Ctrl+F2调出文本窗口,可看到包含了创建圆的AutoCAD命令提示语句 

 

二、注册一个新命令AddCircle2

(1)代码的实现:

	static void AAAMyGroupAddCircle2() {
		// Put your command code here
		struct resbuf *rb;//结果款冲区
		int rc = RTNORM;//返回值

		//创建结果缓冲区链表
		ads_point ptCenter = { 30,0,0 };
		ads_real radius = 10;
		rb = acutBuildList(RTSTR, TEXT("Circle"),
			RTPOINT, ptCenter,
			RTREAL, radius,
			RTNONE);

		//创建圆
		if (rb != NULL)
		{
			rc = acedCmdS(rb);
		}

		//检验返回值
		if (rc != RTNORM)
		{
			acutPrintf(TEXT("\\n创建圆失败!"));
		}

		acutRelRb(rb);
		//进行缩放
		acedCommandS(RTSTR, TEXT("Zoom"), RTSTR, TEXT("E"), RTNONE);
	}

(2)注意:

acedCmd()应该改为acedCmdS(),同样它的头文件为”acedCmdNF.h”,

若使用acedCmd()函数,则会报错:

error C2065: “MustSwitchTo_acedCmdC_or_acedCmdS”: 未声明的标识符

(3)acedCmd函数:

acedCmdS()函数等价于acedcommand(),但是以结果缓冲区列表的形式将值传递给AutoCAD。这在复杂的逻辑涉及到构造一个AutoCAD命令列表时非常有用。acutBuildList()函数对于构造命令列表非常有用。

acedCmdS()函数还有一个优点,即可以在运行时修改命令列表,而不是在编译时修复。它的缺点是执行起来要稍微长一点。

下面的示例代码片段导致AutoCAD在当前的图形屏幕(或viewport)上执行重绘。

struct resbuf *cmdlist;
cmdlist = acutBuildList(RTSTR, "redraw", 0);
if (cmdlist == NULL) {
acdbFail("Couldn't create list\\n");
return BAD;
}
acedCmdS(cmdlist);
acutRelRb(cmdlist)

 (4)acutBuildList( )函数

通过分配结果缓冲区,从单个数据项中建立一个链表的结果缓冲区列表,分配由acutBuildList()参数指定的值,并将缓冲区链接在一起。

(5)acutRelRb( )函数

释放分配给指定的结果缓冲区的内存,到它的链表中跟随它的所有结果缓冲区,以及分配给这些结果缓冲区中的字符串值的任何内存。

acutRelRb()函数是acutNewRb()的补充,但是你的应用程序应该调用acutRelRb()来释放由其他几个ARX库函数自动分配的内存,包括acutBuildList()

(6)效果

打开文本窗口查看提示:

 

 三、注册一个新命令EntInfo,用于提示用户选择一个实体,在命令窗口显示该实体的参数

(1)代码的实现

static void AAAMyGroupEntInfo() {
		// Put your command code here

		//提示用户选择实体
		ads_name entName;
		ads_point pt;
		if (acedEntSel(TEXT("\\n选择实体:"), entName, pt) != RTNORM)
			return;

		struct resbuf *rbEnt; //保存实体数据的结果缓冲区
		struct resbuf *rb;   //用于遍历rbEnt的结果缓冲区

		//从entName获得保存实体数据的结果缓冲区
		rbEnt = acdbEntGet(entName);
		rb = rbEnt;

		while (rb != NULL)
		{
			switch (rb->restype)
			{
			case -1:  //图元名
				acutPrintf(TEXT("\\n图元名:%x"), rb->resval.rstring);
				break;
			case 0:
				acutPrintf(TEXT("\\n图元类型:%s"), rb->resval.rstring);
			case 8:
				acutPrintf(TEXT("\\n图层:%s"), rb->resval.rstring);
				break;
			case 10:
				acutPrintf(TEXT("\\n圆心:(%.2f,%.2f,%.2f)"),
					rb->resval.rpoint[X],
					rb->resval.rpoint[Y],
					rb->resval.rpoint[Z]);
				break;
			case 40:  //半径
				acutPrintf(TEXT("\\n半径:%.4f"), rb->resval.rreal);
				break;
			case 210:  //圆所在平面的法向矢量
				acutPrintf(TEXT("\\n平面的法向矢量:(%.2f,%.2f,%.2f)"),
					rb->resval.rpoint[X],
					rb->resval.rpoint[Y],
					rb->resval.rpoint[Z]);
				break;
			default:
				break;

			}

			rb = rb->rbnext;  //切换到下一个节点
		}

		if (rbEnt != NULL)
		{
			acutRelRb(rbEnt);
		}
	}

(2)acedEntSel()函数:

提示用户通过指定一个点来选择一个实体。

(3)acdbEntGet()函数:

从绘图数据库中检索指定的实体,并将其定义数据作为结果缓冲器的链表返回。

(4)效果

在AutoCAD中创建一个实体-圆,然后执行命令EntInfo

 

 

 

 

参考资料:

 《AutoCAD ObjectARX(VC)开发基础与实例教程》

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片