Как заменить стандартную команду своей?

Автор Тема: Как заменить стандартную команду своей?  (Прочитано 11613 раз)

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Здравствуйте!
Вроде довольно простой, казалось бы, вопрос. Есть даже специальная команда "_Undefine". И в LISP есть такая возможность, насколько я помню. А вот в .NET что-то я не нашёл сходу этой возможности! Гугл выдал такой результат: http://through-the-interface.typepad.com/through_the_interface/2007/03/replacing_the_o.html. Но это же просто использование команды! Неужели нет в NET.API встроенных средств для этого?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Многое зависит от того, что это за команда. Пример:

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5.  
  6. [assembly: ExtensionApplication(typeof(Rivilis.RefEditSubst))]
  7. [assembly: CommandClass(typeof(Rivilis.RefEditSubst))]
  8.  
  9. namespace Rivilis
  10. {
  11.     public class RefEditSubst : IExtensionApplication
  12.     {
  13.         void IExtensionApplication.Initialize()
  14.         {
  15.             // Preloading AutoCAD RefEdit command arx-file
  16.             SystemObjects.DynamicLinker.LoadModule("AcRefEd.arx", false, false);
  17.         }
  18.  
  19.         void IExtensionApplication.Terminate()
  20.         {
  21.             // Do plug-in application clean up here
  22.         }
  23.  
  24.         //------------------------------------------------
  25.         //     Command group MUST be "ACAD_MAIN"
  26.         //------------------------------------------------
  27.  
  28.         [CommandMethod("ACAD_MAIN", "RefEdit", CommandFlags.UsePickSet)]
  29.         public void RefEdit() // This method can have any name
  30.         {
  31.             Document doc = Application.DocumentManager.MdiActiveDocument;
  32.             Editor ed = doc.Editor;
  33.             ed.WriteMessage("MyRefEdit..");
  34.             if (doc.Name.Contains("Test"))
  35.             {
  36.                 ed.WriteMessage("selected ref..");
  37.             }
  38.             else
  39.             {
  40.                 doc.SendStringToExecute("_ACAD_REFEDIT.REFEDIT ", true, false, false);
  41.             }
  42.         }
  43.     }
  44. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Т.е., я правильно понял, что достаточно просто своей команде дать имя стандартной и она её заменит?
Многое зависит от того, что это за команда.
Да всё та же: AECOBJECTVIEWER

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Т.е., я правильно понял, что достаточно просто своей команде дать имя стандартной и она её заменит?
Нужна пара условий:
1. Соответствующий arx/dll-файл, стандартной команды должен быть загружен до определения своей команды (т.е. в методе Initialize)
2. Группа твоей команды должна совпадать с группой стандартной команды. Я проверял в C3D 2016:
Код - INI [Выбрать]
  1. Команда: ARX
  2. Задайте параметр [Файлы/Группы/Команды/кЛассы/Службы/Загрузить/Выгрузить]: К
  3. Какие команды вывести <*>: aecobj*
  4. Команды, зарегистрированные модулями ARX:
  5. Группа команд 'AecUtilities70'
  6.     AECOBJECTDISPLAY, OBJECTDISPLAY
  7.     AECOBJECTVIEWER, OBJECTVIEWER
Т.е. группа: AecUtilities70
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Вот это подарок! Спасибо большое!

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Пока не получается:
Не удалось загрузить сборку. Сведения об ошибке: Autodesk.AutoCAD.Runtime.Exception: eDuplicateKey
   в Autodesk.AutoCAD.Runtime.CommandClass.AddCommand(ICommandLineCallable ca, MethodInfo mi)
   в Autodesk.AutoCAD.ApplicationServices.AutoCADApplicationHolder.Initialize(Assembly assembly)
   в Autodesk.AutoCAD.ApplicationServices.ExtensionLoader.ProcessAssembly(Assembly assembly)
Пробую вот так:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Runtime;
  4.  
  5. namespace Rivilis
  6. {
  7.     public class RefEditSubst : IExtensionApplication
  8.     {
  9.         void IExtensionApplication.Initialize()
  10.         {
  11.             SystemObjects.DynamicLinker.LoadModule("AecUtilities.arx", false, false);
  12.         }
  13.  
  14.         void IExtensionApplication.Terminate()
  15.         {
  16.             // Do plug-in application clean up here
  17.         }
  18.        
  19.         [CommandMethod("AECUTILITIES70", "AECOBJECTVIEWER", CommandFlags.UsePickSet)]
  20.         public void RunCmd() // This method can have any name
  21.         {
  22.             Document doc = Application.DocumentManager.MdiActiveDocument;
  23.             Editor ed = doc.Editor;
  24.             Application.ShowAlertDialog("It's my command!");          
  25.         }
  26.     }
  27. }
Здесь используется имя "AECOBJECTVIEWER", я пробовал и просто "OBJECTVIEWER" - результат тот же.

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Отладка не ловит эту ошибку. Initialize отрабатывает без ошибок. Я так понимаю, что DLL пытается зарегистрировать команду, а Civil не даёт это сделать.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
С добавлением своей команды можно еще поиграться. Есть метод для динамического определения своей команды:
Код - C# [Выбрать]
  1. // Autodesk.AutoCAD.Internal.Utils
  2. public unsafe static void AddCommand(string cmdGroupName, string cmdGlobalName, string cmdLocalName, CommandFlags cmdFlags, CommandCallback func);
А так можно удалить зарегистрированную команду:
Код - C# [Выбрать]
  1. // Autodesk.AutoCAD.Internal.Utils
  2. public unsafe static void RemoveCommand(string cmdGroupName, string cmdGlobalName);
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да, это то что нужно!  :) Вот так работает:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.Runtime;
  3.  
  4. namespace Rivilis
  5. {
  6.     public class RefEditSubst : IExtensionApplication
  7.     {
  8.         void IExtensionApplication.Initialize()
  9.         {
  10.             SystemObjects.DynamicLinker.LoadModule("AecUtilities.arx", false, false);
  11.             Autodesk.AutoCAD.Internal.Utils.RemoveCommand("AECUTILITIES70", "AECOBJECTVIEWER");
  12.         }
  13.  
  14.         void IExtensionApplication.Terminate()
  15.         {          
  16.         }
  17.        
  18.         [CommandMethod("OBJECTVIEWER", CommandFlags.UsePickSet)]
  19.         public void RunCmd()
  20.         {
  21.             Application.ShowAlertDialog("It's my command!");          
  22.         }
  23.     }
  24. }



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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Я хочу использовать стандартную, но перед этим мне надо передать свой набор объектов. С событиями никак не получается стабильной работы - то вылезает извечная проблема "Выполняется команда Enter прервать или Повтор", то сбрасывается предвыбор, то ещё какая-то беда. Вот придумал сделать свою команду, которая будет формировать набор, а потом запускать стандартную команду.

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
М-да... Я думал, что этот метод действует аналогично Undefined, и я смогу вызвать стандартную команду с помощью подчёркивания и точки. Но нет, удаляет команду полностью. Хороший метод. И, в общем-то, задачу, озвученную в вопросе выполняет. Но работает не так как мне надо...