ObjectARX中对象句柄、ID和指针的关系

一、AcDbObject对象对象的访问方式

在ObjectARX中,每个AcDbObject对象可以通过三种方式进行访问:

  • 通过其句柄
  • 通过其ID
  • 通过其C++实例指针

当AutoCAD没有运行,图纸保存在文件系统中时,可以通过句柄来标识DWG文件中的对象;当图纸打开以后,图纸信息可通过AcDbDatabase对象进行访问。每一个数据库中的对象拥有一个ID,其生存期持续于AcDbDatabase对象创建和删除之间的时期。打开函数(例如acdbOpenObject()函数)根据对象的ID打开对象,并返回对象的指针。当对象关闭后,这个指针随即失效。
上述关系如下图所示。
在这里插入图片描述

二、ID→句柄的转换

法1:AcDbDatabase::getAcDbObjectId(),根据对象ID值获取其句柄。

Acad::ErrorStatus getAcDbObjectId(
	AcDbObjectId& retId, 
	bool createIfNotFound, 
    const AcDbHandle& objHandle, 
    Adesk::UInt32 xRefId = 0
);

法2:打开一个对象后通过getAcDbHandle()方法获取句柄

AcDbObject* pObject;
AcDbHandle handle;
pObject->getAcDbHandle(handle);

请注意:打开对象以后,请尽快关闭。可以使用AcDbObject::close() 函数去关闭一个数据库对象。

三、对象ads_name→对象ID→对象指针

ads_name和AcDbObjectId是等价的。AcDb库提供了两个标准函数来实现AcDbObjectId和ads_name的转换。

// Returns an ads_name for a given object ID.
// 根据指定ID返回其ads_name
acdbGetAdsName(ads_name& objName, AcDbObjectId objId); 

// Returns an object ID for a given ads_name.
// 根据指定ads_name返回其ID
acdbGetObjectId(AcDbObjectId& objId, ads_name objName); 

通常,你是通过选择集获取对象,而选择集返回的是对象的ads_name。此时,你需要将ads_name转换为ID值,然后利用acdbOpenObject 全局函数打开对象。
以下函数描述了这个过程

AcDbEntity*
selectEntity(AcDbObjectId& eId, AcDb::OpenMode openMode)
{
 ads_name en;
 ads_point pt;
 acedEntSel("\nSelect an entity: ", en, pt);

 // Exchange the ads_name for an object ID.
 // 更换ads_name为ID值
 acdbGetObjectId(eId, en);

 AcDbEntity * pEnt;
 acdbOpenObject(pEnt, eId, openMode);

 return pEnt;
}

四、对象打开模式说明

acdbOpenObject可以三种模式打开对象,分别为:

  • kForRead:如果对象没有用kForWrite或者kForNotify方式打开,该模式可以被打开为读模式,且最多可以被256个读者读取。
  • kForWrite:如果对象没有被打开,则该模式可将对象打开为写模式。
  • kForNotify:当对象关闭、打开为读模式、打开为写模式时,该模式均可以打开为通知模式。程序中极少需要将一个对象打开为通知模式。

以下表格描述了当对象打开后,再次以不同模式打开时返回的错误代码。

已经打开为再次打开为再次打开为再次打开为
kForReadkForWritekForNotify
openedForReadeAtMaxReaders (if readCount = 256; otherwise succeeds)eWasOpenForRead(Succeeds)
openedForWriteeWasOpenForWriteeWasOpenForWrite(Succeeds)
openedForNotifyeWasOpenForNotifyeWasOpenForNotifyeWasOpenForNotify
wasNotifying(Succeeds)eWasNotifyingeWasNotifying
UndoeWasOpenForUndoeWasOpenForUndo(Succeeds)

当你试图用写模式打开一个对象时,函数返回错误提示“eWasOpenForRead”,你可以用upgradeOpen() 升级原对象的读模式为写模式(如果对象只有一个读取者)。当写完对象以后,调用downgradeOpen()函数将对象打开模式降级为读模式。相似的,如果对象已经以通知模式打开,但你想升级为写模式,可以调用函数upgradeFromNotify()进行升级;当使用完毕后,调用downgradeToNotify()去降级为通知模式。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Santiago

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值