创建一个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)开发基础与实例教程》
暂无评论内容