Словарь Расширения
Каждый объект может иметь словарь расширения{*продления*}, который может содержать произвольный набор объектов AcDbObject. При использовании этого механизма, несколько приложений могут прикреплять данные к тому же самому объекту. Словарь расширения{*продления*} требует более верхний чем xdata, но это также обеспечивает более гибкий механизм более высокой способностью{*вместимостью*} для добавляющихся данных.
Для примера использования словаря расширения{*продления*}, чтобы прикрепить произвольную строку к любому AcDbObject, см. программу edinvent в каталоге выборок.
Следующий пример показывает instantiating xrecord и добавление этого к словарю расширения{*продления*} в названном объектном словаре:
void
createXrecord()
{
AcDbXrecord *pXrec = new AcDbXrecord;
AcDbObject *pObj;
AcDbObjectId dictObjId, xrecObjId;
AcDbDictionary* pDict;
pObj = selectObject(AcDb::kForWrite);
if (pObj == NULL) {
return;
}
// Try to create an extension dictionary for this
// object. If the extension dictionary already exists,
// this will be a no-op.
//
pObj->createExtensionDictionary();
// Get the object ID of the extension dictionary for the
// selected object.
//
dictObjId = pObj->extensionDictionary();
pObj->close();
// Open the extension dictionary and add the new
// xrecord to it.
//
acdbOpenObject(pDict, dictObjId, AcDb::kForWrite);
pDict->setAt("ASDK_XREC1", pXrec, xrecObjId);
pDict->close();
// Create a resbuf list to add to the xrecord.
//
struct resbuf* head;
ads_point testpt = {1.0, 2.0, 0.0};
head = acutBuildList(AcDb::kDxfText,
"This is a test Xrecord list",
AcDb::kDxfXCoord, testpt,
AcDb::kDxfReal, 3.14159,
AcDb::kDxfAngle, 3.14159,
AcDb::kDxfColor, 1,
AcDb::kDxfInt16, 180,
0);
// Add the data list to the xrecord. Notice that this
// member function takes a reference to a resbuf NOT a
// pointer to a resbuf, so you must dereference the
// pointer before sending it.
//
pXrec->setFromRbChain(*head);
pXrec->close();
acutRelRb(head);
}
// The listXrecord() function gets the xrecord associated with the
// key "ASDK_XREC1" and lists out its contents by passing the resbuf
// list to the function printList().
//
void
listXrecord()
{
AcDbObject *pObj;
AcDbXrecord *pXrec;
AcDbObjectId dictObjId;
AcDbDictionary *pDict;
pObj = selectObject(AcDb::kForRead);
if (pObj == NULL) {
return;
}
// Get the object ID of the object’s extension dictionary.
//
dictObjId = pObj->extensionDictionary();
pObj->close();
// Open the extension dictionary and get the xrecord
// associated with the key ASDK_XREC1.
//
acdbOpenObject(pDict, dictObjId, AcDb::kForRead);
pDict->getAt("ASDK_XREC1", (AcDbObject*&)pXrec,
AcDb::kForRead);
pDict->close();
// Get the xrecord’s data list and then close the xrecord.
//
struct resbuf *pRbList;
pXrec->rbChain(&pRbList);
pXrec->close();
printList(pRbList);
acutRelRb(pRbList);
}
Глобальный Функциональный Пример
Следующий пример использует глобальные функции ObjectARX, чтобы создать xrecord и прибавлять это к словарю, связанному с клавишей ASDK_REC{*ключом*}.
int
createXrecord()
{
struct resbuf *pXrec, *pEnt, *pDict, *pTemp, *pTemp2;
ads_point dummy, testpt = {1.0, 2.0, 0.0};
ads_name xrecname, ename, extDict = {0L, 0L};
// Have the user select an entity. Then get its data.
//
if (acedEntSel("\nselect entity: ", ename, dummy) != RTNORM)
{
acutPrintf("\nNothing selected");
acedRetVoid();
return RTNORM;
}
pEnt = acdbEntGet(ename);
// Now check to see if the entity already has an
// extension dictionary.
//
for (pTemp = pEnt; pTemp->rbnext != NULL; pTemp = pTemp->rbnext)
{
if (pTemp->restype == 102) {
if (!strcmp("{ACAD_XDICTIONARY", pTemp->resval.rstring))
{
ads_name_set(pTemp->rbnext->resval.rlname, extDict);
break;
}
}
}
// If no extension dictionary exists, add one.
//
if (extDict[0] == 0L) {
pDict = acutBuildList(RTDXF0, "DICTIONARY", 100,
"AcDbDictionary", 0);
acdbEntMakeX(pDict, extDict);
acutRelRb(pDict);
pDict = acutBuildList(102, "{ACAD_XDICTIONARY", 360,
extDict, 102, "}", 0);
for (pTemp = pEnt; pTemp->rbnext->restype != 100; pTemp = pTemp->rbnext)
{ ; }
for (pTemp2 = pDict; pTemp2->rbnext != NULL; pTemp2 = pTemp2->rbnext)
{ ; }
pTemp2->rbnext = pTemp->rbnext;
pTemp->rbnext = pDict;
acdbEntMod(pEnt);
acutRelRb(pEnt);
}
// At this point the entity has an extension dictionary.
// Create a resbuf list of the xrecord’s entity information
// and data.
//
pXrec = acutBuildList(RTDXF0, "XRECORD",
100, "AcDbXrecord",
1, "This is a test Xrecord list", //AcDb::kDxfText
10, testpt, //AcDb::kDxfXCoord
40, 3.14159, //AcDb::kDxfReal
50, 3.14159, //AcDb::kDxfAngle
60, 1, //AcDb::kDxfColor
70, 180, //AcDb::kDxfInt16
0);
// Create the xrecord with no owner set. The xrecord’s
// new entity name will be placed into the xrecname
// argument.
//
acdbEntMakeX (pXrec, xrecname);
acutRelRb (pXrec);
// Set the xrecord’s owner to the extension dictionary
//
acdbDictAdd(extDict, "ASDK_XRECADS", xrecname);
acedRetVoid();
return RTNORM;
}
// Accesses the xrecord associated with the key ASDK_XRECADS in
// the extension dictionary of a user-selected entity. Then
// list out the contents of this xrecord using the printList
// function.
//
int
listXrecord()
{
struct resbuf *pXrec, *pEnt, *pTemp;
ads_point dummy;
ads_name ename, extDict = {0L, 0L};
// Have the user select an entity; then get its data.
//
if (acedEntSel("\nselect entity: ", ename, dummy) != RTNORM) {
acutPrintf("\nNothing selected");
acedRetVoid();
return RTNORM;
}
pEnt = acdbEntGet(ename);
// Get the entity name of the extension dictionary.
//
for (pTemp = pEnt;pTemp->rbnext != NULL;pTemp = pTemp->rbnext) {
if (pTemp->restype == 102) {
if (!strcmp("{ACAD_XDICTIONARY", pTemp->resval.rstring)){
ads_name_set(pTemp->rbnext->resval.rlname, extDict);
break;
}
}
}
if (extDict[0] == 0L) {
acutPrintf("\nNo extension dictionary present.");
return RTNORM;
}
pXrec = acdbDictSearch(extDict, "ASDK_XRECADS", 0);
if(pXrec) {
printList(pXrec);
acutRelRb(pXrec);
}
acedRetVoid();
return RTNORM;
}