Как задать межстрочный интервал у атрибута в блоке?

Автор Тема: Как задать межстрочный интервал у атрибута в блоке?  (Прочитано 9190 раз)

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

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

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

  • ADN Club
  • ****
  • Сообщений: 288
  • Карма: 10
  • AutoCAD Civil 3D
Добрый день
Подскажите пожалуйста, как задать межстрочный интервал у атрибута из нескольких строк в блоке, т.е. как называется это свойство в MTextAttribute?

Проблема состоит в том что изменяется значение атрибута в блоке и слетает заданные у текста межстрочный интервал, наверное надо сначала считать  кой был, изменить текст у атрибута и вернуть обратно значение межстрочного интервала, но не понимаю как это свойство называется и есть ли оно.

Как поставить галочку  - см. скрин
« Последнее редактирование: 25-09-2015, 23:35:39 от Doublefish »

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

  • ADN Club
  • ****
  • Сообщений: 288
  • Карма: 10
  • AutoCAD Civil 3D
Видимо тут надо пользоваться управляющими символами типа \\W0.6000;\\pxsm0.4; читая их их mt.Contents и возвращая их обратно после замены текста.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
как называется это свойство в MTextAttribute?
Такого свойства у многострочного атрибута нет. Это делается при помощи управляющих кодов внутри многострочного текста:



Описание кодов (не полное): http://exchange.autodesk.com/autocadmep/rus/online-help/BLDSYS/2012/RUS/pages/WS1a9193826455f5ffa23ce210c4a30acaf-63b9.htm
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 19-06-2017, 16:34:34

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ха. Оказалось, что я не прав. Можно и так:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. [assembly: CommandClass(typeof(MtextLineSpace.Utils))]
  9.  
  10. namespace MtextLineSpace
  11. {
  12.   public class Utils
  13.   {
  14.     [CommandMethod("MtextLS")]
  15.     public void MyCommand()
  16.     {
  17.       Document doc = Application.DocumentManager.MdiActiveDocument;
  18.       if (doc == null) return;
  19.       Editor ed = doc.Editor;
  20.       PromptNestedEntityOptions prEnt =
  21.         new PromptNestedEntityOptions("\nВыберите многострочный атрибут:");
  22.       PromptEntityResult rsEnt = ed.GetNestedEntity(prEnt);
  23.  
  24.       if (rsEnt.Status != PromptStatus.OK) return;
  25.       if (!rsEnt.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AttributeReference))))
  26.       {
  27.         ed.WriteMessage("\nЭто не атрибут блока!");
  28.         return;
  29.       }
  30.       using (AttributeReference att = rsEnt.ObjectId.Open(OpenMode.ForWrite) as AttributeReference)
  31.       {
  32.         if (!att.IsMTextAttribute)
  33.         {
  34.           ed.WriteMessage("\nЭто не многострочный атрибут!");
  35.           return;
  36.         }
  37.         MText mt = att.MTextAttribute;
  38.         double mtls = mt.LineSpaceDistance;
  39.         PromptDistanceOptions prDist =
  40.           new PromptDistanceOptions("\nУкажите межстрочный интервал");
  41.         prDist.AllowZero = false;
  42.         prDist.AllowNone = false;
  43.         prDist.DefaultValue = mtls;
  44.         PromptDoubleResult rsDist = ed.GetDistance(prDist);
  45.         if (rsDist.Status == PromptStatus.OK)
  46.         {
  47.           mt.LineSpaceDistance = rsDist.Value;
  48.           att.MTextAttribute = mt;
  49.           att.UpdateMTextAttribute();
  50.         }
  51.       }
  52.     }
  53.   }
  54. }



Это работает если не задан межстрочный интервал управляющими кодами внутри атрибута.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Код - C# [Выбрать]
  1. MText mt = att.MTextAttribute;
А не нужно ли в этом случае закрывать объект mt после его использования?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Код - C# [Выбрать]
  1. MText mt = att.MTextAttribute;
А не нужно ли в этом случае закрывать объект mt после его использования?
Нет. Это клон внутреннего объекта, который не вставлен отдельно в базу. Поэтому его не нужно закрывать. А вот вызвать для него Dispose() для освобождения памяти можно. Для unmanaged объекта описание из ObjectARX SDK:
Цитировать
When called on multi-line attributes, it retrieves a clone of the internal AcDbMText that's used for the representation of this multi-line attribute.

Callers must either delete the returned AcDbMText entity, or put it back under the control of the attribute by calling setMTextAttribute().

Returns a non-database-resistent clone of the internal AcDbMText that's used for the representation of this multi-line attribute. Returns NULL when called on a non-multi-line attribute.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
А вот вызвать для него Dispose() для освобождения памяти можно.
То есть, Вы считаете, что можно и не вызывать? :)
По крайней мере, в моем коде я не вызываю Dispose() для таких мтекстов и не задаю их обратно в атрибут. И при дебаге в Output не выводятся сообщения вида "Forgot to call Dispose?".

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
То есть, Вы считаете, что можно и не вызывать? :)
Ну тут следует последить за утечками памяти. Но если посмотреть исходник этого свойства, то оно никогда само не чистит память:
Код - C# [Выбрать]
  1. // Autodesk.AutoCAD.DatabaseServices.AttributeReference
  2. public MText MTextAttribute
  3. {
  4.         get
  5.         {
  6.                 IntPtr unmanagedObjPtr = new IntPtr(<Module>.AcDbAttribute.getMTextAttribute(this.GetImpObj()));
  7.                 return new MText(unmanagedObjPtr, false);
  8.         }
  9.         set
  10.         {
  11.                 int num = (int)<Module>.AcDbAttribute.setMTextAttribute(this.GetImpObj(), value.GetImpObj());
  12.                 if (num != 0)
  13.                 {
  14.                         throw new Autodesk.AutoCAD.Runtime.Exception((ErrorStatus)num);
  15.                 }
  16.         }
  17. }

Для создания MText в get используется конструктор MText(IntPtr unmanagedObjPtr, bool autoDelete)
Т.к. autoDelete == false, то AutoCAD сам не будет освобождать память.
« Последнее редактирование: 19-06-2017, 23:07:50 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Код - C# [Выбрать]
  1. MText mt = att.MTextAttribute;
А не нужно ли в этом случае закрывать объект mt после его использования?
Думаю что оптимальный вариант:
Код - C# [Выбрать]
  1. using (MText mt = att.MTextAttribute)
  2. {
  3.   // Здесь код использующий mt
  4. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Так и сделаю, спасибо!