Интересный пример с пользовательскими объектами для изучения

Автор Тема: Интересный пример с пользовательскими объектами для изучения  (Прочитано 38852 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но функция dwgOutFields у меня вроде исправно работает например при перемещении объекта.
Если под перемещением объекта ты имеешь в виду команду _MOVE, то dwgOutFields там вообще не работает, а работает метод transfomBy.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Если подключится к процессу, установить точки останова, то при команде MOVE программа будет проходить через конструкторы, деструкторы, dwgOutFields, dwgInFields, subTransformBy.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но это всё (кроме subTransformBy) будет относится не к оригинальному примитиву, а к его копиям, которые создаются после указания Базовой точки и до указания Второй точки. И только после указания второй точки будет вызван subTransformBy для оригинального примитива.
Кстати, если ты установишь DRAGMODE в 0, то у тебя должен вызываться только метод subTransformBy для оригинального примитива - копии при этом значении DRAGMODE не создаются.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Нашел конкретную проблему:
в dwgInFields не срабатывет почему то при открытии файла автокада:

      ACHAR* str;
      pFiler->readString(&str); // на этой строке происходит сбой

после того как закомментировал в dwgIn dwgOut все что касается этой строки
все заработало. Файл сохраняется и открывается.
В чем у меня может быть ошибка? Мне в будующем нужно записывать в файл строковые данные.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
      ACHAR* str;
      pFiler->readString(&str); // на этой строке происходит сбой
Какой сбой? Что происходит?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Когда открываю файл и программа доходит в считывания строки
es=pFiler->readString(&str);
появляется ругательство что то про повреждение кучи.

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
не знаю, всё работатет (правда не этот пример)
TCHAR *buffer = NULL;
pFiler->readItem(&buffer);
m_string = buffer; //m_string приватная переменная класса. тип CString
acdbFree(buffer);
кстати, кажись важен порядок чтения записи в InFields и OutFields.
возможно пишутся данные не в том порядке, в котором читаются.

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Причем при drag все работает корректно.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Выложи последние исходники.
P.S.: AuPolyline::undoFiler - это у тебя явно лишнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Вот папка "без строки" где закомментировал все, что касается строки и теперь работает,
и папка "со строкой" где не работает.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Смотрим твой пример "со строкой", который не работает и что мы видим:
Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- AcDbObject protocols
  3. //- Dwg Filing protocol
  4. Acad::ErrorStatus AuPolyline::dwgOutFields (AcDbDwgFiler *pFiler) const {
  5.         assertReadEnabled () ;
  6.         //----- Save parent class information first.
  7.         Acad::ErrorStatus es =AcDbPolyline::dwgOutFields (pFiler) ;
  8.         if ( es != Acad::eOk )
  9.                 return (es) ;
  10.         //----- Object version number needs to be saved first
  11.         if ( (es =pFiler->writeUInt32 (AuPolyline::kCurrentVersionNumber)) != Acad::eOk )
  12.                 return (es) ;
  13.         //----- Output params
  14.         //.....
  15.         //m_Hatch.dwgOutFields(pFiler);
  16.         UInt32 n=m_Array.size();
  17.         es=pFiler->writeUInt32(n);
  18.         if ( es != Acad::eOk )
  19.                 return (es) ;
  20.         objArray::const_iterator it;
  21.         for (it=m_Array.begin();it!=m_Array.end();it++)
  22.         {
  23.                 SOSTAV s=(*it).first;
  24.                 Adesk::UInt32 s1=s;
  25.                 es=pFiler->writeUInt32(s1);
  26.                 if ( es != Acad::eOk )
  27.                         return (es) ;
  28.                 //const ACHAR* str = (*it).second->isA()->name();
  29.                 //es=pFiler->writeString(str);
  30.                 //if ( es != Acad::eOk )
  31.                 //      return (es) ;
  32.                 es=(*it).second->dwgOutFields(pFiler);
  33.                 if ( es != Acad::eOk )
  34.                         return (es) ;
  35.         }
  36.         es=pFiler->filerStatus ();
  37.         return (pFiler->filerStatus ()) ;
  38. }
  39.  
  40. Acad::ErrorStatus AuPolyline::dwgInFields (AcDbDwgFiler *pFiler) {
  41.         assertWriteEnabled () ;
  42.         //----- Read parent class information first.
  43.         Acad::ErrorStatus es =AcDbPolyline::dwgInFields (pFiler) ;
  44.         if ( es != Acad::eOk )
  45.                 return (es) ;
  46.         //----- Object version number needs to be read first
  47.         Adesk::UInt32 version =0 ;
  48.         es =pFiler->readUInt32 (&version);
  49.         if  (es != Acad::eOk )
  50.                 return (es) ;
  51.         if ( version > AuPolyline::kCurrentVersionNumber )
  52.                 return (Acad::eMakeMeProxy);
  53.         //- Uncomment the 2 following lines if your current object implementation cannot
  54.         //- support previous version of that object.
  55.         //if ( version < AuPolyline::kCurrentVersionNumber )
  56.         //      return (Acad::eMakeMeProxy) ;
  57.         //----- Read params
  58.         //.....
  59.  
  60.         Adesk::UInt32 n;
  61.         es=pFiler->readUInt32(&n);
  62.         if  (es != Acad::eOk )
  63.                 return (es) ;
  64.         for(int i=0;i<n;i++)
  65.         {
  66.                 //using namespace AuPolyline::AcDbEntity;
  67.                 SOSTAV s;
  68.                 Adesk::UInt32 s1;
  69.                 es=pFiler->readUInt32(&s1);
  70.                 if  (es != Acad::eOk )
  71.                         return (es) ;
  72.                 s=static_cast<SOSTAV>(s1);
  73.  
  74.                 ACHAR* str;
  75.                 es=pFiler->readString(&str);
  76.                 if  (es != Acad::eOk )
  77.                         return (es) ;
  78.                 std::wstring ws=str;
  79.                 if(ws==std::wstring(_T("MyHatch")))
  80.                 {
  81.                         MyHatch* pH=new MyHatch;
  82.                         es=pH->dwgInFields(pFiler);
  83.                         if  (es != Acad::eOk )
  84.                                 return (es) ;
  85.                         m_Array.insert(std::make_pair(s,pH));
  86.                 }      
  87.                 else
  88.                 {
  89.                         acutPrintf(_T("неизвестный тип данных\n"));
  90.                         return Acad::eNotOpenForRead;
  91.                 }      
  92.         }
  93.         es=pFiler->filerStatus ();
  94.         return (pFiler->filerStatus ()) ;
  95. }
В AuPolyline::dwgOutFields закомментирована строка es=pFiler->writeString(str); и соотвественно строка в файл не пишется. При этом ты пытаешься в AuPolyline::dwgInFields её читать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ЭдАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Виноват, забыл разкомментировать в dwgOutFields.
Это строки 28-31.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Нормально работает:
1) Загружаю dbx и arx-файлы
2) Запускаю команду MyCommand1.
3) Сохраняю файл.
4) Закрываю файл.
5) Открываю сохраненный файл - всё в порядке. Никаких ошибок.
Сделал небольшие правки, но они не должны были влиять:
Код - C++ [Выбрать]
  1. Acad::ErrorStatus AuPolyline::dwgInFields (AcDbDwgFiler *pFiler) {
  2.         assertWriteEnabled () ;
  3.         //----- Read parent class information first.
  4.         Acad::ErrorStatus es =AcDbPolyline::dwgInFields (pFiler) ;
  5.         if ( es != Acad::eOk )
  6.                 return (es) ;
  7.         //----- Object version number needs to be read first
  8.         Adesk::UInt32 version =0 ;
  9.         es =pFiler->readUInt32 (&version);
  10.         if  (es != Acad::eOk )
  11.                 return (es) ;
  12.         if ( version > AuPolyline::kCurrentVersionNumber )
  13.                 return (Acad::eMakeMeProxy);
  14.         //- Uncomment the 2 following lines if your current object implementation cannot
  15.         //- support previous version of that object.
  16.         //if ( version < AuPolyline::kCurrentVersionNumber )
  17.         //      return (Acad::eMakeMeProxy) ;
  18.         //----- Read params
  19.         //.....
  20.  
  21.         Adesk::UInt32 n;
  22.         es=pFiler->readUInt32(&n);
  23.         if  (es != Acad::eOk )
  24.                 return (es) ;
  25.         for(int i=0;i<n;i++)
  26.         {
  27.                 //using namespace AuPolyline::AcDbEntity;
  28.                 SOSTAV s;
  29.                 Adesk::UInt32 s1;
  30.                 es=pFiler->readUInt32(&s1);
  31.                 if  (es != Acad::eOk )
  32.                         return (es) ;
  33.                 s=static_cast<SOSTAV>(s1);
  34.  
  35.                 ACHAR* str = NULL;
  36.                 es=pFiler->readString(&str);
  37.                 if  (es != Acad::eOk )
  38.                         return (es) ;
  39.                 std::wstring ws=str;
  40.     if(ws==std::wstring(MyHatch::desc()->name()))
  41.                 {
  42.                         MyHatch* pH=new MyHatch();
  43.                         es=pH->dwgInFields(pFiler);
  44.                         if  (es != Acad::eOk )
  45.                                 return (es) ;
  46.                         m_Array.insert(std::make_pair(s,pH));
  47.                 }      
  48.                 else
  49.                 {
  50.                         acutPrintf(_T("неизвестный тип данных\n"));
  51.                         return Acad::eNotOpenForRead;
  52.                 }      
  53.         }
  54.         es=pFiler->filerStatus ();
  55.         return (pFiler->filerStatus ()) ;
  56. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот так у меня и Undo/Redo корректно работает:
Код - C++ [Выбрать]
  1. Acad::ErrorStatus AuPolyline::dwgInFields (AcDbDwgFiler *pFiler) {
  2.         assertWriteEnabled () ;
  3.         //----- Read parent class information first.
  4.         Acad::ErrorStatus es =AcDbPolyline::dwgInFields (pFiler) ;
  5.         if ( es != Acad::eOk )
  6.                 return (es) ;
  7.         //----- Object version number needs to be read first
  8.         Adesk::UInt32 version =0 ;
  9.         es =pFiler->readUInt32 (&version);
  10.         if  (es != Acad::eOk )
  11.                 return (es) ;
  12.         if ( version > AuPolyline::kCurrentVersionNumber )
  13.                 return (Acad::eMakeMeProxy);
  14.         //- Uncomment the 2 following lines if your current object implementation cannot
  15.         //- support previous version of that object.
  16.         //if ( version < AuPolyline::kCurrentVersionNumber )
  17.         //      return (Acad::eMakeMeProxy) ;
  18.         //----- Read params
  19.         //.....
  20.  
  21.         Adesk::UInt32 n;
  22.         es=pFiler->readUInt32(&n);
  23.         if  (es != Acad::eOk )
  24.                 return (es) ;
  25.         for(int i=0;i<n;i++)
  26.         {
  27.                 //using namespace AuPolyline::AcDbEntity;
  28.                 SOSTAV s;
  29.                 Adesk::UInt32 s1;
  30.                 es=pFiler->readUInt32(&s1);
  31.                 if  (es != Acad::eOk )
  32.                         return (es) ;
  33.                 s=static_cast<SOSTAV>(s1);
  34.  
  35.                 ACHAR* str = NULL;
  36.                 es=pFiler->readString(&str);
  37.                 if  (es != Acad::eOk )
  38.                         return (es) ;
  39.                 std::wstring ws=str;
  40.     if(ws==std::wstring(MyHatch::desc()->name()))
  41.                 {
  42.                         MyHatch* pH=new MyHatch();
  43.                         es=pH->dwgInFields(pFiler);
  44.                         if  (es != Acad::eOk )
  45.                                 return (es) ;
  46.                         m_Array.insert(std::make_pair(s,pH));
  47.                 }      
  48.                 else
  49.                 {
  50.                         acutPrintf(_T("неизвестный тип данных\n"));
  51.                         return Acad::eNotOpenForRead;
  52.                 }      
  53.         }
  54.         es=pFiler->filerStatus ();
  55.   if (es == Acad::eOk) SetupEntitys();
  56.         return (pFiler->filerStatus ()) ;
  57. }
Вся тонкость в строке   if (es == Acad::eOk) SetupEntitys();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Александр, а освободить str? :):):)
а то ж так можно через 3 часа работы и вылететь из акада без объяснений. читаете то через ACHAR* а не AcString.
кстати вопросик в догонку, может знаете. если читать строку через readItem, то там только ACHAR**, если через readString, то там два варианта: AcString, который не нужно подчищать за собой и ACHAR**, который удалять нужно, но пишут, что когда-то в очередной новой версии уберут вообще.
а вот вопросик такой, убрать то не сложно, только как тогда будет работать readItem? ведь по логике то внутри readItem должен стоять вызов readString (ну я б так сделал, чтоб не городить кучу лишнего кода). но информации о том, что поменяется входной парамерт для readItem не нашел.