Тема: fromAcDbTextStyle

Нужно получить информацию о стиле по ID или хотябы по имени стиля.
Хелп говорит: "используй fromAcDbTextStyle". Я так и делаю.
AcGiTextStyle textStyle;
fromAcDbTextStyle(textStyle, "Standard");
при вызове fromAcDbTextStyle
вылетает ошибка: Debug Assertion Failed ... File dbgheap.c...
Expression: _CrtIsValidHeapPointer(pUserData) ....
Видимо я чтото не так делаю? Или ARX глючит?
Пишу под win 2000, ARX 2000.
Я знаю что ARX 2000 под win 2000 не всегда работает стабильно.
Может это именно тот случай?
М.б. ктоньть сталкивался с подобной проблемой?
Вобщем мне нужно получить имя стиля по его ObjectID. Может есть какой-то другой способ?
Я добирался до нужной мне записи в textStyleTable, но я не нашел у textStyleTableRecord метода возвращающего имя, по крайней мере
метод Name возвращал мне какие-то каракули.
Хелп энибоди.

Re: fromAcDbTextStyle

У AcDbTextStyleTableRecord есть метод getName, который возвращает имя тестового стиля. Он работает. Ищи у себя ошибку.

Re: fromAcDbTextStyle

Сори за неточность, когда я говорил "по крайней мере
метод Name..." я имел ввиду getName, но она возвращает строку с символами, кодовая таблица которых явно не из нашей галактики. Я конечно поищу ошибку, но что-то попахивает глюками при работе со стилями, м.б. поэтому fromAcDbTextStyle не работает?
Наверно стоит переходить на более свежие версии ARX.
Александр спасибо за ответ.

Re: fromAcDbTextStyle

Попробуй этот тест. Если он у тебя не сработает, значит проблемы в твоем сочетании AutoCAD и ObjectARX SDK:

  char *GetTextStyleName(AcDbObjectId tid)
  {
    Acad::ErrorStatus es;
    char *name = NULL;
    AcDbTextStyleTableRecord *pTSTR = NULL;
    if ((es = acdbOpenAcDbObject((AcDbObject *&)pTSTR,tid,AcDb::kForRead)) == Acad::eOk) {
      pTSTR->getName(name);
      pTSTR->close();
    } else {
      acutPrintf("\nОшибка записи таблицы текстовых стилей стилей: %s",
        acadErrorStatusText(es));
    }
    return name;
  }
  void PrintAllStyleName(void)
  {
    Acad::ErrorStatus es;
    AcDbTextStyleTable *pTbl;
    es = acdbCurDwg()->getTextStyleTable(pTbl, AcDb::kForRead);
    if (es != Acad::eOk || !pTbl) {
      acutPrintf("\nОшибка открытия таблицы текстовых стилей!");
      return;
    }
    AcDbTextStyleTableIterator *pIterator;
    es = pTbl->newIterator(pIterator);
    if (es != Acad::eOk || !pIterator) {
      acutPrintf("\nОшибка создания итератора таблицы текстовых стилей!");
      pTbl->close();
      return;
    }
    pTbl->close();
    AcDbObjectId tid;
    for(pIterator->start(); !pIterator->done(); pIterator->step()) {
      if (Acad::eOk == (es = pIterator->getRecordId(tid))) {
        char *pName = GetTextStyleName(tid);
        if (pName) {
          acutPrintf("\nText style: %s",pName);
          free(pName);
        }
      } else {
        acutPrintf("\nОшибка pIterator->getRecordId(tid): %s",
          acadErrorStatusText(es));
      }
    }
    delete pIterator;
  }

Re: fromAcDbTextStyle

Работает!!!
Александр,если встречу с меня пиво.
но ведь и без acdbOpenAcDbObject должно было работать.
Спасибо большое.

Re: fromAcDbTextStyle

Александр,если встречу с меня пиво.

Увы, пиво не пью... Предпочитаю хорошее вино. :)

но ведь и без acdbOpenAcDbObject должно было работать.

Это как? (чешу репу). Если объект не открыт, то как можно прочитать из него информацию? wink

Re: fromAcDbTextStyle

А кто сказал что он не открыт?
Кроме acdbOpenAcDbObject есть другие способы.
Например у итератора по textStyleTable есть метод
getRecord, который открывает объект.
Но так у меня не работало, а с помощью
acdbOpenAcDbObject заработало почемуто.
Вино так вино, уговорил =)

Re: fromAcDbTextStyle

> lap
У меня работает и метод с getRecord(). Я специально для тебя переделал, чтобы показать как по AcDbObjectId получить имя текстового стиля. А исходный вариант выглядел приблизительно так:

void GetStyleName(void)
{
  Acad::ErrorStatus es;
  AcDbTextStyleTable *pTbl;
  es = acdbCurDwg()->getTextStyleTable(pTbl, AcDb::kForRead);
  if (es != Acad::eOk || !pTbl) {
    acutPrintf("\nОшибка открытия таблицы текстовых стилей!");
    return;
  }
  AcDbTextStyleTableIterator *pIterator;
  es = pTbl->newIterator(pIterator);
  if (es != Acad::eOk || !pIterator) {
    acutPrintf("\nОшибка создания итератора таблицы текстовых стилей!");
    pTbl->close();
    return;
  }
  pTbl->close();
  AcDbTextStyleTableRecord *pTR = NULL;
  for(pIterator->start(); !pIterator->done(); pIterator->step()) {
    if ((es = pIterator->getRecord(pTR,AcDb::kForRead)) == Acad::eOk) {
      char *pName = NULL;
      if ((es = pTR->getName(pName)) == Acad::eOk) {
        if (pName) {
          acutPrintf("\nText style: %s",pName);
          free(pName);
        }
      } else {
        acutPrintf("\nОшибка pIterator->getRecord(pTR,AcDb::kForRead): %s",
          acadErrorStatusText(es));
      }
      pTR->close();
    } else {
      acutPrintf("\nОшибка pIterator->getRecord(pTR): %s",
        acadErrorStatusText(es));
    }
  }
  delete pIterator;
}

Проверь из спортивного интереса. :)

Re: fromAcDbTextStyle

Проверил - не работает так.
Причем ни дома у меня ни на работе. На работе 2000 винда, а дома XP. Так что, наличае глюка это факт (я так считаю).

Re: fromAcDbTextStyle

Очень странно. Аналогичный сценарий (с getRecord) у меня работает во всех версиях AutoCAD с R14 по 2006 четко и без сбоев. Более того getRecord() полностью эквивалентно getRecordId() + acdbOpenAcDbObject(). Поэтому, совершенно не понятно где здесь может быть глюк. Походе, что это глюк именно твоего AutoCAD или ты не один в один запустил мой пример. В нем есть нюансы с порядком выполнения close() и типом открытия (на чтение или на запись).

Re: fromAcDbTextStyle

В твоем примере я заменил только acdbCurDwg() на
acdbHostApplicationServices()->workingDatabase()
и всё, больше ничё не трогал (могу скриншот показать).
А что скажеш про fromAcDbTextStyle? кстати ошибка таже вылетает, что и при getRecord.

Re: fromAcDbTextStyle

> lap
Я тебе отослал arx-файл. Проверь.

Re: fromAcDbTextStyle

> lap
Это по поводу fromAcDbTextStyle:

void GetStyleInfo()
{
  Acad::ErrorStatus es;
  char stylename[256]="";
  if (acedGetString(0,"\nУкажите имя текстового стиля: ",stylename) == RTNORM) {
    AcGiTextStyle style;
    if ((es = fromAcDbTextStyle(style, stylename)) == Acad::eOk) {
      acutPrintf("\nStyle Name: %s\nFile Name: %s\nText size=%g",
        style.styleName(),
        style.fileName(),
        style.textSize()
      );
    } else {
      acutPrintf("\nОшибка fromAcDbTextStyle(style, stylename): %s",
        acadErrorStatusText(es));
    }
  }
}

У меня все работает. Возможно у тебя линковка происходит не с теми библиотеками, или нарушен порядок линковки (например, rxapi.lib должна быть первой из библиотек ObjectARX).

Re: fromAcDbTextStyle

То что ты мне прислал действительно работает.
Про глюки беру свои слова обратно, но что я сделал нетак
вот строка либ из моего проекта:
rxapi.lib acrx15.lib acutil15.lib acdb15.lib acge15.lib achapi15.lib acISMobj15.lib acad.lib acsiobj.lib acgiapi.lib acedapi.lib

Re: fromAcDbTextStyle

Загрузи мой проект и сравни опции компилятора и линкера.
Судя по сообщению Debug Assertion Failed у тебя что-то откомпилировано в Debug mode (возможно каша из Debug и Release). Попробуй все в Release mode. Кроме того если стоит Link incrementally, то убери его. И вообще я надеюсь, что ты используешь VC++ 6 - с другими могут быть аналогичные проблемы?
Если пришлешь свой проект, попробую разобраться.

Re: fromAcDbTextStyle

Я использую VC++ 6. Что-то нетак с моим проектом. Буду  разбираться. О результатах сообщу. Александр спасибо, я пришлю проект, если не смогу разобраться - мне бы хотелось самому понять причину.

Re: fromAcDbTextStyle

> lap
Еще один совет. Убедись, что для всех cpp-файлов одинаковые опции компилятора. Я сталкивался с ситуацией, когда у одного из файлов были другие опции компилятора и получалась неработающий (или глючно работающий) arx-файл. Чтобы избавится от этого выбираешь в File View все cpp-файлы, правую кнопку мыши, Settings... и на вкладке C/C++ выставляешь общие опции. После этого делаешь Rebuil All.

Re: fromAcDbTextStyle

Извиняюсь что долго не пишу, щас я другим занят. Я пока сильно не разбирался с этой проблемой. Но хочу сказать про один нюанс: при создании своего проекта я не использовал ObjectARX Wizard и видимо что-то не так подключил, с использованием визорда всё работает ништяк. Но вряд ли дело в порядке линковки (копировал «строку либ» из правильного проекта в свой – не помогло) , короче чуть позже обещаю разобраться.