Сделать текущим лист при работе в фоновом режиме

Автор Тема: Сделать текущим лист при работе в фоновом режиме  (Прочитано 14645 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Добрый день. Работаю с файлом в фоновом режиме (т.е. загружаю файл в Database без открытия документа в Автокаде). В процессе работы создаётся вкладка листа, в пространстве листа выводятся некоторые объекты, затем документ сохраняется.
Вопрос 1: как сделать, что бы нужный лист стал активным? LayoutManager в данном случае не доступен, а свойство layout.TabSelected = true выделяет лист, но не делает его активным. Свойство Database.CurrentSpaceId закрыто для изменения.
Вопрос 2: как сделать адекватным отображение листа? При открытии вышеописанного сохранённого документа в Автокаде и выборе листа (хотя он должен быть уже активным, см. вопрос 1), отображается только его небольшая часть (левый нижний угол), и масштабирование вращением колёсика мышки не позволяет увидеть лист целиком, только двойной щелчок колёсиком мыши спасает.
« Последнее редактирование: 06-10-2014, 14:17:27 от JohnJ »

Оффлайн bargool

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Сразу вопрос в тему: а удается ли в фоне настроить лист? Формат там, плоттер и проч.? У меня в свое время не получилось..
Алексей

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
да, это удаётся. У меня есть заранее заготовленный PlotSettings, который я потом указываю листу:
Код - C# [Выбрать]
  1. using (var layout = tr.GetObject(paper_space.LayoutId, OpenMode.ForWrite) as Layout) {
  2. layout.CopyFrom(ps);
  3. }

Оффлайн bargool

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Я про вот эту тему: http://forum.dwg.ru/showthread.php?t=83750, там же есть ссылка на гитхаб с кодом
У меня там тоже есть работа с заранее подготовленными PlotSettings
Я тоже пробовал сделать layout.CopyFrom без захода на лист с помощью LayoutManager, но проблема была такова, что некоторые настройки в итоге сбрасывались при заходе на лист пользователем. Сбрасывались в некое значение "по-умолчанию". Насколько я помню, это касалось области печати, и может чего ещё.
Причём мне казалось, что всё работает, но просто у меня желаемые настройки совпадали с этими самыми "по-умолчанию"... обнаружилось только при экспериментах. Если у вас всё в порядке с этим, отпишитесь, пожалуйста, я тогда ещё поковыряю, где я там накосячил.
Алексей

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Интересно, что некоторое время назад я тоже написал схожую программу - из модели в листы. Но там я использовал LayoutManager. В разрабатываемой сейчас программе он не используется, и я пока не знаю - возможно тоже будут схожие с вашими проблемы. Посмотрим. Было бы лучше, если бы вы конкретно указали, какое свойство на что меняется. Я бы смог проверить тогда сразу.

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Второй вопрос разрешился, благодаря тому, что полазал в исходниках программы Bargool. Там есть такие строки
Код - C# [Выбрать]
  1. int vpCount = layout.GetViewports().Count;
  2.                         if (vpCount == 0)
  3.                         {
  4.                                 throw new System.Exception(String.Format("Layout {0} не инициализирован", layout.LayoutName));
  5.                         }
И действительно, я ведь в данном случае не создавал лист, а использовал один из двух существующих, которые создавались сами при создании БД (а в предыстории к вопросам описал совсем другую ситуацию, виноват). И лист был просто не проинициализирован, видимо. Вызов layout.Initialize() разрешил эту проблему.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Вопрос 1: как сделать, что бы нужный лист стал активным? LayoutManager в данном случае не доступен, а свойство layout.TabSelected = true выделяет лист, но не делает его активным. Свойство Database.CurrentSpaceId закрыто для изменения.
Насколько мне известно этого сделать нельзя. Но так как на 100% не уверен - отправлю этот вопрос в ADN DevHelp.
Вопрос 2: как сделать адекватным отображение листа? При открытии вышеописанного сохранённого документа в Автокаде и выборе листа (хотя он должен быть уже активным, см. вопрос 1), отображается только его небольшая часть (левый нижний угол), и масштабирование вращением колёсика мышки не позволяет увидеть лист целиком, только двойной щелчок колёсиком мыши спасает.
Ну вообще-то для этой цели нужно вид настроить. У текущего Layout получаешь Layout.GetViewports и настраиваешь первый из полученных Viewport
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Насколько мне известно этого сделать нельзя. Но так как на 100% не уверен - отправлю этот вопрос в ADN DevHelp.
Спасибо! Есть надежда, что возможно через подключение какой-либо dll, как в случае с экспортом листа в модель: там подключается AcExportLayout.dll
По подсказке KEAN WALMSLEY удалось частично решить вопрос: Database.TileMode установил в false. В текущей задаче этого достаточно, меня устраивает. Но как указать конкретный layout - желание знать остаётся.

Ну вообще-то для этой цели нужно вид настроить. У текущего Layout получаешь Layout.GetViewports и настраиваешь первый из полученных Viewport
У того layout метод GetViewports возвращал 0, пока я не вызвал layout.Initialize(). Но после вызова метода инициализации основной видовой экран листа настраивать и не пришлось - он стал нормально отображаться сам.
« Последнее редактирование: 07-10-2014, 05:24:03 от JohnJ »

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Но как указать конкретный layout - желание знать остаётся.
Ждем ответ от ADN DevHelp. Хотя я подозреваю, что он будет отрицательный. Точно помню, что где-то в открытых источниках это уже было, но где именно сейчас не нашел. Тут еще есть такой нюанс, что в ObjectARX есть значительно больше возможностей у LayoutManager, чем в .NET (например, метод AcDbLayoutManager::setCurrentLayoutId устанавливает активный Layout по его ObjectId) и возможно именно этой функциональности не хватает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
в ObjectARX есть значительно больше возможностей у LayoutManager

Это, опять же, LayoutManager...

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Это, опять же, LayoutManager...
В ObjectARX с ним всё хитрее. Во всяком случае в документации на метод setCurrentLayoutId говорится, что он переключает текущий Layout для активной базы данных. А активная в данном случае в ObjectARX может быть переключена. Я на досуге поэкспериментирую с тем работает ли это в ObjectARX или нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
хмм. Спасибо, интересно!

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
хмм. Спасибо, интересно!
Ну что же. Моя интуиция не подвела. Этот код на ObjectARX работает (т.е. правильно устанавливает активный Layout в чертеже, который не загружен в редактор AutoCAD). Во всяком случае в AutoCAD 2012, на котором я проверял.
Код - C++ [Выбрать]
  1. static Acad::ErrorStatus SetCurLayout(ACHAR *fileName, ACHAR *layoutName)
  2. {
  3.   Acad::ErrorStatus es = Acad::eOk;
  4.   AcApDocManager *pDocMan = acDocManagerPtr();
  5.   AcDbDatabase *db = new AcDbDatabase(false,false);
  6.   if ((es = db->readDwgFile(fileName)) != Acad::eOk) {
  7.     acutPrintf(_T("\nОшибка открытия файла! %s"),acadErrorStatusText(es));
  8.     delete db; return es;
  9.   }
  10.   if ((es = db->closeInput(true)) != Acad::eOk) {
  11.     acutPrintf(_T("\nОшибка closeInput! %s"), acadErrorStatusText(es));
  12.     delete db; return es;
  13.   }
  14.   AcApDocument *pDoc = pDocMan->document(db);
  15.   if (!pDoc) {
  16.     acutPrintf(_T("\nНе найден документ!"));
  17.     delete db; return es;
  18.   }
  19.   AcDbObjectId idLayout;
  20.   {
  21.     AcDbDictionaryPointer pDict(db->layoutDictionaryId(),AcDb::kForRead);
  22.     if (pDict.openStatus() == Acad::eOk) {
  23.       es = pDict->getAt(layoutName, idLayout);
  24.       if (es != Acad::eOk) {
  25.         acutPrintf(_T("\nНе найден лист \'%s\'!"), layoutName);
  26.         delete db; return es;
  27.       }
  28.     }
  29.   }
  30.   if (!idLayout.isNull()) {
  31.     AcApDocument *pOldDoc = pDocMan->curDocument();
  32.     if ((es = pDocMan->setCurDocument(pDoc)) != Acad::eOk) {
  33.         acutPrintf(_T("\nОшибка pDocMan->setCurDocument(pDoc)! %s"),acadErrorStatusText(es));
  34.         delete db; return es;        
  35.     }
  36.     AcDbHostApplicationServices *pHost = acdbHostApplicationServices();
  37.     AcDbLayoutManager *pLayMan = pHost->layoutManager();
  38.     es = pLayMan->setCurrentLayoutId(idLayout);
  39.     es = pDocMan->setCurDocument(pOldDoc);
  40.     es = db->saveAs(layoutName);
  41.     delete db;
  42.   } else {
  43.     delete db;
  44.   }
  45.   return es;
  46. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Получил ответ от ADN DevHelp. В текущей реализации AutoCAD .NET API переключение листа в неактивной базе невозможно. Запросили изменение функциональности у разработчиков. Но это будет в лучшем случае в следующей версии AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Спасибо! Благо, что хоть TileMode есть :)