|
[code]步骤
(1)创建一个新的ObjectARX项目(本例为ArxConfig);
(2)创建新类:CCreateLine并包含头文件
#include "StdAfx.h"
(stdafx.h在C++中起到的作用是头文件预编译,即把C++工程中使用的MFC头文件预先编译,以后该工程编译时,直接使用预编译的结果,以加快编译速度)
(3)在CreateLine.h中添加两个成员函数:
//创建直线(起点,结束点)
static AcDbObjectId CreateLine(AcGePoint3d ptStart, AcGePoint3d ptEnd);
//将实体添加到图形数据库的模型空间
static AcDbObjectId PostToModelSpace(AcDbEntity* pLine);
C++中AcDbObjectId类的典型用法代码示例:
C++ AcDbObjectId类代码示例 - 纯净天空 (vimsky.com)
(当一个对象或实体第一次被增加至数据库中,一个新的stub对象被创建且设为指向被增加至数据库的对象和实体。这个stub在内存中的地址作为增加至数据库中的对象或实体的ads_name和AcDbObjectId使用)
((笑谈AcDb0bjectld)什么是ID(身份、标识),看过周星驰的《唐伯虎点秋香》吧?由于下人太多,名字不好记,每个人都被编了一个号码(唐伯虎自然就是9527),管理者通过这个编号来管理。图形数据库也一样,作为管理者,只能通过编号(AcDbObjectld)来管理每一个实体。)
(4) 在CreateLine.cpp中实现上述两个成员函数:
AcDbObjectId CCreateLine::CreateLine(AcGePoint3d ptStart, AcGePoint3d ptEnd) //函数实现
{
AcDbLine *pLine = new AcDbLine(ptStart, ptEnd);
/*注意,基于AutoCAD内部的实现机制,必须在堆上创建对象,而不能用下面的语句创建直线的对象:
AcDbLine line(ptStart, ptEnd);
此时,直线对象仅被在内存上创建,并没有添加到图形数据库中,因此不可能会显示在图形窗口中。*/
//将实体添加到图形数据库
AcDbObjectId lineId;
//此时,直线对象仅被在内存上创建,并没有添加到图形数据库中,因此不可能会显示在图形窗口中。
lineId = CCreateEnt::PostToModelSpace(pLine);
return lineId;
}
// 将实体添加到图形数据库的模型空间
AcDbObjectId CCreateLine::PostToModelSpace(AcDbEntity* pLine)
{
// 获得指向块表的指针
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
/*
acdbHostApplicationServices()->workingDatabase()能够获得一个指向当前活动的图形数据库的指针,这在后面还要经常遇到。getBlockTable 是 AcDbDatabase 类的一个成员函数,用于获得指向图形数据库的块表的指针,其定义为:
inline Acad::ErrorStatus getBlockTable(
AcDbBlockTable*& pTable,
AcDb::OpenMode mode);
该函数的返回值 Acad::ErrorStatus 是 ObjectARX 中定义的一个枚举类型,主要用于判断函数的返回状态,如果函数成功执行会返回 Acad::eOk。
第一个参数 pTable 返回指向块表的指针;
第二个参数同样是一个枚举类型的变量,其类型 AcDb::OpenMode 包含了AcDb::kForRead、AcDb::kForWrite 和 AcDb::kForNotify 三个可取的值,创建直线的时候不需要更改块表,因此这里打开的模式为 AcDb::kForRead
*/
// 获得指向特定的块表记录(模型空间)的指针
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForWrite);
/*
getAt 函数是 AcDbBlockTable 类的一个成员函数,用于获得块表中特定的记录,其定义为:
Acad::ErrorStatus getAt(
const char* entryName,
AcDbBlockTableRecord*& pRec,
AcDb::OpenMode openMode,
bool openErasedRec = false) const;
第一个参数用于指定块表记录的名称,ACDB_MODEL_SPACE 是 ObjectARX 中定义的一个常量,其内容是“*Model_Space”;
第二个参数用于返回指向块表记录的指针;
第三个参数指定了块表记录打开的模式,下一步要向块表记录中添加实体,所以就用写的模式(AcDb::kForWrite)打开;
第四个参数指定是否查找已经被删除的记录,
*/
// 将AcDbLine类的对象添加到块表记录中
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);
/*appendAcDbEntity是 AcDbBlockTableRecord类的成员函数,用于将pEntity
指向的实体添加到块表记录和图形数据库中,其定义为:
Acad::ErrorStatus appendAcDbEntity(
AcDbObjectld& pOutputld,
AcDbEntity* pEntity);
第一个参数返回图形数据库为添加的实体分配的ID号;
第二个参数指定了所要添加的实体。
*/
// 关闭图形数据库的各种对象
pBlockTable->close();
pBlockTableRecord->close();
pLine->close();
return entId;
/*在操作图形数据库的各种对象时,必须遵守AutoCAD的打开和关闭对象的协议。
该协议确保当对象被访问时在物理内存中,而未被访问时可以被分页存储在磁盘中。
创建和打开数据库的对象之后,必须在不用的时候关闭它。*/
}
(5) 在acrxEntryPoint.cpp中添加#include "CreateLine.h"头文件后添加注册命令
//当前项目中注册一个命令 AddLine
static void MidasMyGroupMyDrawLine()
{
AcGePoint3d ptStart(0, 0, 0);
AcGePoint3d ptEnd(10, 10, 0);
AcDbObjectId lineId;
lineId = CCreateLine::CreateLine(ptStart, ptEnd);
}
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyDrawLine, MyDrawLine, ACRX_CMD_MODAL, NULL) //画直线
注: static void MidasMyGroupMyDrawLine() 中成员函数名MidasMyGroupMyDrawLine由ACED_ARXCOMMAND_ENTRY_AUTO中第二和第三个参数组合,第四个参数为AutoCAD中命令.
(6) 调试生成在AutoCAD中加载后,输入命令MyDrawLine,实现效果
原文链接:https://blog.csdn.net/qq_42981953/article/details/121786941[/code] |
|