Здравствуйте.
В программе есть функция перерасчета размеров всех объектов чертежа под текущий масштаб отображения.
В ней содержится цикл перебора всех объектов чертежа, открытие каждого на запись, установление размера, и закрытие.
Потом вызывается ads_regen(), и команда завершается.
Между несколькими вызовами команд производится изменение масштаба отображения колесом мышки. Больше ничего.
AutoCAD 2010 sp3.
Проблема в том, что начиная c некоторого раза, один из объектов, а именно AcDbMText,
являющийся annotation object для AcDbLeader, без моего открытия становится уже открытым перед циклом.
Соответственно, с ним никакие операции не удается произвести.
Он становится зависшим объектом. С карты не удаляется.
В поисках решения поставил где мог проверки состояния открытости объектов после закрытия.
Лог не показывает, что закрытие объектов не отрабатывает, повторное закрытие не вызывается.
Вопрос, можно ли принудительно закрыть уже открытый объект по известному AcDbObjectId?
Что с ним вообще можно сделать? удалить?
Известно ли, почему эта ситуация возникает?
Вызовы pLeader->evaluateLeader() и pMText->close() пробовались в той и другой последовательности, проблему это не решило.
Подозреваю, что AcDbMText открывается внутри evaluateLeader(), что в рамках документации метода и объясняет непостоянный характер проявления ошибки,
причем открывается так, что isReadEnabled() и isWriteEnabled() этого не отображают.
Приведу код открытия, масштабирования, и закрытия объектов в цикле
Открытие:
AcDbEntity *pEnt;
AcDbObjectId objId;
Acad::ErrorStatus es;
es = acdbOpenAcDbEntity(pEnt, objId, AcDb::kForWrite);
if (!pEnt || es!=Acad::eOk)
{
LgE(L"Ошибка открытия примитива. Код " + AS(es) + L". Пропущен.");
continue;
}
// Здесь, начиная с какого-то вызова команды, возникает ошибка 82, иногда 83.
Установка размера надписи, проверка закрытия объекта:
AcDbMText *pMText;
Acad::ErrorStatus es = acdbOpenAcDbEntity( (AcDbEntity*&)pMText, pLeader->annotationObjId(), AcDb::kForWrite );
if (es == Acad::eOk)
{
pMText->setTextHeight( scaler );
pLeader->evaluateLeader();
pMText->close();
bool bRead = pMText->isReadEnabled();
bool bWrite = pMText->isWriteEnabled();
if (bRead || bWrite)
{
Acad::ErrorStatus escl = pMText->close();
LgFAp( L", MText reclosed, with es: " + AS(int(escl)) + L", Read/Write: " + AS(int(bRead)) + L"/" + AS(int(bWrite)) + L" " );
}
}
else
{
LgE( L"AcDbLeader anno " + AS(int(pLeader->annotationObjId().asOldId())) + L" open failure, es: " + AS(int(es)) + L"." );
}
Закрытие объекта и проверка закрытия:
bool bMText = pEnt->isKindOf(mtxtDesc);
pEnt->close();
LgFAp( L", closed.");
if (bMText)
{
LgFAp( L", reclose" );
bool bRead = pEnt->isReadEnabled();
bool bWrite = pEnt->isWriteEnabled();
if (bRead || bWrite)
{
Acad::ErrorStatus escl = pEnt->close();
LgFAp( L" ended with es: " + AS(int(escl)) + L", Read/Write: " + AS(int(bRead)) + L"/" + AS(int(bWrite)) + L" " );
}
}
В логе картина отсутствия проблем с закрытием.
На предыдущей итерации:
... Объект 8 типа AcDbLeader acadId -4207152. Открыт. ... Processed, closed.
... Объект 9 типа AcDbMText acadId -4207168. Открыт. ... Processed, closed., reclose
На следующей итерации:
... Объект 8 типа AcDbLeader acadId -4207152. ....
AcDbLeader anno -4207168 open failure, es: 82. Processed, closed.
... Объект 9 типа AcDbMText acadId -4207168.
Ошибка открытия примитива. Код 82. Пропущен.
Спасибо.