- UID
- 1
- 积分
- 15891
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
发表于 2004-3-22 14:01:31
|
显示全部楼层
Re: [求助]:图块清理(Purge)的问题
最初由 LQH 发布
[B]通常CAD图形中的图块,如果未被引用,可以被purge清理掉,以节省磁盘空间,但有某些块虽未被引用,我仍然需要保留在图形,不让其被清理,可何做到! [/B]
你可以使用反应器:
- AcEditorReactor::commandWillStart Function virtual void
- commandWillStart(
- const char* cmdStr);
- cmdStr Passed in string of the command being executed
- This callback function indicates that the command cmdStr is about to
- begin execution.
- cmdStr may be up to 257 characters (including the string terminator).
来判断是否执行了purge 命令,然后你保存你需要的“未被引用”的BLOCK,等AcEditorReactor::commandEnded 时候,你再恢复那些BLOCK到数据库。
具体可以看联机帮助和ARX目录下面的SAMPLE目录下的例子。
下面摘自联机帮助,介绍AcEditorReactor::commandEnded
- AcEditorReactor::commandEnded Function virtual void
- commandEnded(
- const char* cmdStr);
- cmdStr Passed in string of the command being executed
- This callback function indicates that the command cmdStr has completed.
- cmdStr may be up to 257 characters (including the string terminator).
- With commands involving sets of entities, and when
- AcEditorReactor::comandEnded() notification is sent, the last entity
- operated upon is still open for read even though AutoCAD is no longer
- looking at it. This prevents that entity from being opened for write via
- acdbOpenObject() within the notification callback.
- There are two ways to get around this limitation:
- 1 The preferred method is to use a transaction to manipulate the entities
- within your implementation of the commandEnded(). This bypasses any
- problems opening objects that are still open.
- Warning When using this method, you must be sure to end or terminate
- the transaction before you return from the commandEnded() function.
- Following is a simple example of this method:
- void
- AsdkEdReactor::commandEnded(const char *pCommand)
- {
- // If AutoCAD is shutting down, then do nothing.
- //
- if (!acdbHostApplicationServices()->working Database())
- return;
- // get entities just operated on
- //
- ads_name sset;
- int err = acedSSGet("p", NULL, NULL, NULL, sset);
- if (err != RTNORM) {
- acutPrintf("\nError acquiring previous selection set");
- return;
- }
- actrTransactionManager->startTransaction();
- long length;
- acedSSLength(sset, &length);
- ads_name en;
- AcDbObjectId eId;
- AcDbEntity *pEnt;
- for (long i=0; i < length; i++) {
- acedSSName(sset, i, en);
- Acad::ErrorStatus es = acdbGetObjectId(eId, en);
- if (es != Acad::eOk) {
- acutPrintf("\nacdbGetObjectId failed: "
- "Entity name < %lx,%lx >, error %s.", en[0], en[1],
- acadErrorStatusText(es));
- acedSSFree(sset);
- return;
- }
- es = actrTransactionManager->getObject((AcDbObject*&)pEnt,
- eId, AcDb::kForWrite);
- if (es == Acad::eOk) {
- pEnt->setColorIndex(1);
- pEnt->close();
- } else {
- acutPrintf("\ngetObject failed with error %s.",
- acadErrorStatusText(es));
- actrTransactionManager->abortTransaction();
- acedSSFree(sset);
- return;
- }
- }
- actrTransactionManager->endTransaction();
- acedSSFree(sset);
- }
- 2 Within the commandEnded() implementation, you can open the entity
- for read and then repeatedly call its close() method until its isReallyClosing
- () method returns Acad::kTrue, indicating that there is now only one
- reader, and then use the entity's upgradeOpen() method to upgrade the
- open to AcDb::kForWrite.
- Now the entity is in a normal open AcDb::kForWrite state, so do whatever
- operations you want, followed by a call to the entity's close() or cancel()
- .
- Following is a simple example of this method:
- void
- AsdkEdReactor::commandEnded(const char *pCommand)
- {
- // If AutoCAD is shutting down, then do nothing.
- //
- if (!acdbHostApplicationServices()->working Database())
- return;
-
- // get entities just operated on
- //
- ads_name sset;
- int err = acedSSGet("p", NULL, NULL, NULL, sset);
- if (err != RTNORM) {
- acutPrintf("\nError acquiring previous selection set");
- return;
- }
- long length;
- acedSSLength(sset, &length);
- ads_name en;
- AcDbObjectId eId;
- AcDbEntity *pEnt;
- for (long i=0; i < length; i++) {
- acedSSName(sset, i, en);
- Acad::ErrorStatus es = acdbGetObjectId(eId, en);
- if (es != Acad::eOk) {
- acutPrintf("\nacdbGetObjectId failed: "
- "Entity name < %lx,%lx >, error %s.", en[0], en[1],
- acadErrorStatusText(es));
- acedSSFree(sset);
- return;
- }
- es = acdbOpenObject(pEnt, eId, AcDb::kForWrite);
- if (es == Acad::eOk) {
- pEnt->setColorIndex(cindex);
- pEnt->close();
- } else if (es == Acad::eWasOpenForRead) {
- // open it for read again to get a pointer to the
- // entity and then close it repeatedly until it's
- // down to one open for read.
- //
- acdbOpenObject(pEnt, eId, AcDb::kForRead);
- do
- pEnt->close();
- while (!pEnt->isReallyClosing());
- // Now that we're down to one open for read, upgrade
- // the open to kForWrite.
- //
- pEnt->upgradeOpen();
- // do what we want and then close
- //
- pEnt->setColorIndex(1);
- pEnt->close();
- } else {
- acutPrintf("\nacdbOpenObject failed with error %s.",
- acadErrorStatusText(es));
- acedSSFree(sset);
- return;
- }
- }
- acedSSFree(sset);
- }
|
|