Обращение к "родным" командам автокада из кода

Автор Тема: Обращение к "родным" командам автокада из кода  (Прочитано 6819 раз)

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

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

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Здравствуйте!
Есть ли возможность использовать стандартные команды автокада в своем коде и если да то как это организовать?
Например, есть обычная команда полилиния, со своим стандартным поведением, которую вызывает пользователь через обычную кнопку интерфейса в автокаде. Ее функционал меня устраивает, также устраивает отображение ее построения в реальном времени и т.д. Но нужно добавить к ней свой самодельный функционал. Писать полный аналог встроенной команды с небольшими доп функциями вроде не очень правильный путь, а как организовать использование уже имеющейся команды не знаю.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Editor.Command позволяет запустить команду с заданными параметрами. Перед запуском её подписываешься на событие Document.CommandEnded и в нём делаешь с полученной полилинией то, что тебе нужно. Один из вариантов.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Editor.Command позволяет запустить команду с заданными параметрами.

Если я правильно понял, это сработает только при указании заранее известных параметров. Но проблема в том, что я этих параметров не знаю заранее - пользователь строит линию совершенно непредсказуемо выбирая точки на экране. И еще пару раз откатит несколько точек в процессе построения и построит их заново. Вот в чем подвох.

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

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

Отмечено как Решение Atomohod 15-12-2018, 17:41:17

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А можно и вот так:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. [assembly: CommandClass(typeof(Rivilis.MyPline))]
  7.  
  8. namespace Rivilis
  9. {
  10.   public class MyPline
  11.   {
  12.     ObjectId idPline; // ObjectId полилинии
  13.     [CommandMethod("MyPline")]
  14.     public async void MyPlineHandler()
  15.     {
  16.       Document doc = Application.DocumentManager.MdiActiveDocument;
  17.       if (doc == null) return;
  18.       Editor ed = doc.Editor;
  19.       Database db = doc.Database;
  20.       db.ObjectAppended += Db_ObjectAppended;
  21.       db.ObjectErased += Db_ObjectErased;
  22.       // Запускаем команду
  23.       try
  24.       {
  25.         await ed.CommandAsync("_.PLINE", Editor.PauseToken);
  26.         while (doc.CommandInProgress.ToUpper() == "PLINE")
  27.         {
  28.           await ed.CommandAsync(Editor.PauseToken); // Продолжаем команду
  29.         }
  30.       }
  31.       catch { }
  32.       // Здесь команда уже завершена
  33.       db.ObjectAppended -= Db_ObjectAppended;
  34.       db.ObjectErased -= Db_ObjectErased;
  35.       ed.WriteMessage("\nPline завершилась. ObjectId = {0}", idPline);
  36.       // Здесь уже можно обрабатывать полилинию.
  37.     }
  38.  
  39.     private void Db_ObjectAppended(object sender, ObjectEventArgs e)
  40.     {
  41.       if (e.DBObject is Polyline)
  42.         idPline = e.DBObject.ObjectId;
  43.     }
  44.     private void Db_ObjectErased(object sender, ObjectErasedEventArgs e)
  45.     {
  46.       if (e.DBObject.ObjectId == idPline)
  47.         idPline = ObjectId.Null;
  48.     }
  49.   }
  50. }

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

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Писать полный аналог встроенной команды с небольшими доп функциями вроде не очень правильный путь
Аналог команды _Pline уже давно написан и в сети лежит: Jigging an AutoCAD polyline with arc segments using .NET

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Владимир Шу,
Будем считать, что я отвечал не на вопрос о конкретной команде _PLINE. К сожалению есть множество команд, про которые неизвестно что у них "под капотом".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 453
  • Карма: 1
Благодарю!
Все сработало.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Недавно копался в недокументированном пространстве имён AutoCAD.Internal. И нашёл аналоги лисповых функций Entlast и Entnext: Autodesk.AutoCAD.Internal.Utils.EntLast и Autodesk.AutoCAD.Internal.Utils.EntNext. Так что, можно воспользоваться лисповым подходом: до запуска команды запомнить последний примитив (Entlast), после выполнения команды получить новые объекты (Entnext в цикле). Это как альтернатива использованию событий.