newer 发表于 2021-1-8 12:39:57

API for draworder command



问题:
Is there an API available for the DRAWORDER command? How can my ARX application
do what DRAWORDER does without calling the DRAWORDER command with acedCommand?

解答:
The DRAWORDER command uses an undocumented class, AcDbSortentsTable. It is not
documented in the help files because the present mechanism is not in its intended
final form.

WARNING: If you use the code in this solution in your application, you run the
risk that you will need to change your application for future versions of AutoCAD.

Refer to the attached header file sorttab.h for the definition of the class
AcDbSortentsTable. This header needs to be copied and included in your projects.
The AcDbSortentsTable class object is stored under the key "ACAD_SORTENTS" in
the extension dictionary of a block table record.

The following code defines a command "SENDBACK" that sends a selected entity
into the background:




//
// Helpers for SENDBACK
//
AcDbSortentsTable*
get_sortents_table_of( AcDbEntity *pEnt )
{
    AcDbObjectId owner_id = pEnt->ownerId();
    if (AcDbObjectId::kNull == owner_id)
      return NULL;


    AcDbBlockTableRecord *pRec;
    if (Acad::eOk != acdbOpenObject( pRec, owner_id, AcDb::kForRead ))
      return NULL;


    AcDbObjectId ext_id = pRec->extensionDictionary();
    if (AcDbObjectId::kNull == ext_id)
    {
      if (Acad::eOk != pRec->upgradeOpen())
      {
            pRec->close();
            return NULL;
      }
      pRec->createExtensionDictionary();
      ext_id = pRec->extensionDictionary();
      if (AcDbObjectId::kNull == ext_id)
      {
            pRec->close();
            return NULL;
      }
    }


    AcDbDictionary *pExt;
    Acad::ErrorStatus es = acdbOpenObject( pExt, ext_id, AcDb::kForRead );


    pRec->close();
    if (Acad::eOk != es)
      return NULL;


    AcDbObject *pObj;
    if (Acad::eOk != pExt->getAt( "ACAD_SORTENTS", pObj, AcDb::kForWrite ))
    {
      if (Acad::eOk != pExt->upgradeOpen())
      {
            pExt->close();
            return NULL;
      }
      AcDbSortentsTable *pSt = new AcDbSortentsTable;
      if (NULL == pSt)
      {
            pExt->close();
            return NULL;
      }


      AcDbObjectId new_id;
      if (Acad::eOk != pExt->setAt( "ACAD_SORTENTS", pSt, new_id ))
      {
            delete pSt;
            pExt->close();
            return NULL;
      }
      pSt->setBlockId( owner_id );
      pObj = pSt;
    }


    pExt->close();


    if (!pObj->isKindOf( AcDbSortentsTable::desc() ))
    {
      pObj->close();
      return NULL;
    }


    return (AcDbSortentsTable*)pObj;
}



void
setSortentsBits( int bits )
{
    resbuf rb;
    rb.restype = RTSHORT;
    rb.resval.rint = bits;
    acedSetVar( "SORTENTS", &rb );
}



void
configureSortents()
{
    resbuf rb;
    const int nSortentsMask = (1 | 2 | 4 | 8 | 16 | 32 | 64);


    acedGetVar( "SORTENTS", &rb );


    if (nSortentsMask != (rb.resval.rint & nSortentsMask))
      setSortentsBits( rb.resval.rint | nSortentsMask );
}


void ads_regen(); // undocumented func



// This is command 'SENDBACK'
void MSSendBack()
{
    ads_name ent;
    ads_point pt;


    if (RTNORM != acedEntSel( "\nSelect Entity: ", ent , pt ))
      return;


    AcDbObjectId ent_id;
    if (Acad::eOk != acdbGetObjectId( ent_id, ent ))
      return;


    configureSortents();


    AcDbEntity *pEnt;
    if (Acad::eOk != acdbOpenObject( pEnt, ent_id, AcDb::kForRead ))
      return;


    AcDbSortentsTable *pSt = get_sortents_table_of( pEnt );


    pEnt->close();
    if (NULL == pSt)
      return;


    AcDbObjectIdArray entity_array;
    entity_array.append( ent_id );


    pSt->moveToBottom( entity_array );
    pSt->close();


    // Must do a full regen
   ads_regen();
}


头文件见附件


页: [1]
查看完整版本: API for draworder command