Как правильно вызывать регенерацию Workspace?

Автор Тема: Как правильно вызывать регенерацию Workspace?  (Прочитано 20686 раз)

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
AutoCAD 2009-2011 x64 Enu

Программно подгружаю Partial CUI\CUIx (в зависимости от версии AutoCAD) файл меню. Однако текущее Workspace не удаётся обновить так, чтобы сразу после загрузки отображались мои Toolbar и Ribbon Tab, определённые в подгруженном файле. Если через команду _CUI открываю окно "Customize user interface", то вижу, что меню успешно подгружено и в составе текущего Workspace мои элементы так же присутствуют.

В более новых версиях AutoCAD проблемы нет, т.к. решение оформлено в виде BUNDLE-пакета, согласно настройкам которого автозагрузчик AutoCAD сам подгружает менюшки и обновляет содержимое текущего Workspace.

Если в обозначенном выше диалоговом окне произвольно что-то обновлю вручную, например в свойстве Description текущего Workspace поставлю точку и нажму кнопку Apply, то содержимое Workspace обновляется и мои менюшки появляются. Т.е. регенерация Workspace приводит к отображению моих менюшек. Значит эту регенерацию нужно вызвать принудительно...

Безуспешно пробовал воспользоваться недокументированными методами CustomizationSection.addToolbarsMenusAndPanelsToWorkspace() и CustomizationSection.UpdateWorkspaceComplete().

Код - C# [Выбрать]
  1. // Since of AutoCAD 2010 it is CUIX files (menu) are used instead of CUI.
  2. static readonly System.Version acad_2010_version = new System.Version(18, 0);
  3.  
  4. static readonly string menuFilesExtension = cad.Version <
  5.     acad_2010_version ? ".cui" : ".cuix";
  6.  
  7. static readonly string extensionMenuDir = Path.Combine(
  8.     Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
  9.     @"..\Resources\");
  10.  
  11. static readonly string extensionMenuFileName = (
  12.     cad.Version < acad_2010_version ? "Proxy_Tools_2009" : "Proxy_Tools_2010")
  13.     + menuFilesExtension;
  14.  
  15. static readonly string extensionMenuFullName = Path.GetFullPath(
  16.     Path.Combine(extensionMenuDir, extensionMenuFileName));
  17.  
  18. const string menuGroupName = "PROXY_TOOLS";
  19.  
  20. // Since AutoCAD 2011 the `CustomizationSection.RemovePartialMenu()`
  21. // method has other signature.
  22. // Also, the BUNDLE-package autoloader have appeared since AutoCAD 2012.
  23. static readonly System.Version acad_2011_version = new System.Version(18, 1);
  24.  
  25. void LoadMenu()
  26. {
  27.     string mainCuiFile = string.Format("{0}{1}",
  28.     (string)cad.GetSystemVariable("MENUNAME"), menuFilesExtension);
  29.  
  30.     try
  31.     {
  32.         CustomizationSection csMain = new CustomizationSection(mainCuiFile);
  33.  
  34.         if (!csMain.PartialCuiFiles.Contains(extensionMenuFullName))
  35.         {
  36.             Type csType = typeof(CustomizationSection);
  37.             bool menuloadingResult = false;
  38.  
  39.             if (cad.Version < acad_2011_version)
  40.             {
  41.                 CustomizationSection csExtension = new CustomizationSection(
  42.             extensionMenuFullName);
  43.                 menuloadingResult = (bool)csType.InvokeMember("AddPartialMenu",
  44.                     BindingFlags.Public | BindingFlags.InvokeMethod |
  45.                     BindingFlags.Instance, null, csMain, new object[] {
  46.                 csExtension });
  47.             }
  48.             else
  49.             {
  50.                 menuloadingResult = (bool)csType.InvokeMember("AddPartialMenu",
  51.                     BindingFlags.Public | BindingFlags.InvokeMethod |
  52.                 BindingFlags.Instance, null, csMain, new object[] {
  53.                     extensionMenuFullName });
  54.             }
  55.  
  56.             if (csMain.IsModified == true)
  57.             {
  58.                 // Display our menu
  59.                 // TODO: The problem is here. My Partial CUI\CUIX menu loaded and exists
  60.                 // in the current Workspace (I see it in the "Customize user interface" dialog),
  61.                 // but it is not displayed until I do any change in the "Customize user interface"
  62.                 // dialog (for example edit the `Description` property of the current Workspace) and
  63.                 // press "Apply" key.
  64.                 CustomizationSection csExtension = new CustomizationSection(
  65.             extensionMenuFullName);
  66.  
  67.                 // TODO: I don't see any info about these functions in the AutoCAD 2016 SDK
  68.                 // documentations, but I had a hope that they can help me...
  69.                 // But they didn't help me.
  70.                 csMain.addToolbarsMenusAndPanelsToWorkspace(csExtension);
  71.                 csMain.UpdateWorkspaceComplete();
  72.  
  73.                 // Save all changes
  74.                 csMain.Save();
  75.             }
  76.         }
  77.     }
  78.     catch (System.Exception ex)
  79.     {
  80.         Document doc = cad.DocumentManager.MdiActiveDocument;
  81.         if (null == doc)
  82.         {
  83.             cad.ShowAlertDialog(ex.Message);
  84.         }
  85.         else
  86.         {
  87.             doc.Editor.WriteMessage("\nAttempt of `{0}` file loading...\nERROR: {0}\n",
  88.                 extensionMenuFullName, ex.Message);
  89.         }
  90.     }
  91. }

Как заставить Workspace перерисовать свой контент, чтобы мои элементы появились?

С др. стороны, если каждое расширение будет вызывать регенерацию Workspace, то это будут большие тормоза... Может можно как-то вызвать регенерацию не всего Workspace, а только той его части, которая относится к моему контенту?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Программно подгружаю Partial CUI\CUIx (в зависимости от версии AutoCAD) файл меню.
Судя по коду ты его в AutoCAD не загружаешь. Полная аналогия с тем, что ты правил lisp-файл, но забыл загрузить его в AutoCAD и поэтому выполняется предыдущая версия. Чтобы подгрузить cui/cuix нужно выгрузить и загрузить повторно меню (выполнить команды _CUIUNLOAD и_CUILOAD). Подробнее смотри пример samples\dotNet\CuiSamp в ObjectARX SDK 2007.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В последних версиях AutoCAD .NET API есть методы Application.LoadPartialMenu  и Application.UnloadPartialMenu. Но в 2009 и 2010 их еще небыло. Но вроде бы в них это можно сделать через COM/ActiveX:
1) MenuGroup имеет метод Unload для выгрузки меню
2) MenuGroups имеет метод Load для загрузки меню
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Я для себя пришел к выводу и отказался с плясками с CUI(x). Все менюшки я создаю и заполняю программно, при загрузке dll в IExtensionApplication.Initialize  (гораздо удобней включать/отключать кнопки в зависимости от "уровня доступа" и как следствия загруженных команд). Единственную проверку я делаю - это нет ли готового Toolbars с соотв. именем - уже созданного пользователем через CUI - то есть если нет - его "нарисует" пользователю на экране, если уже есть - то в установленном месте появится необходимые кнопки.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Судя по коду ты его в AutoCAD не загружаешь. Полная аналогия с тем, что ты правил lisp-файл, но забыл загрузить его в AutoCAD и поэтому выполняется предыдущая версия.
Похоже, что вы невнимательно смотрели мой код. Ещё раз гляньте на строки 41-53. Или же вы хотите сказать, что метод AddPartialMenu не выполняет загрузку меню и её появление (после выполнения обозначенного кода) в перечне подгруженных CUI\CUIX, а так же появление в текущем Workspace ничего не означает? Никакая "предыдущая" версия выполняться не может по той простой причине, что её попросту нет. Кроме того, прежде чем запускать код на исполнение я проверял отсутствие загрузки моего файла в списке подгруженных Partial CUI\CUIX.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Никакая "предыдущая" версия выполняться не может по той простой причине, что её попросту нет.
Есть. В данном случае это файл acad.cui (или acad.cuix). Ты не понял самого главного - CustomizationSection (да и все связанные с ним классы) работает с файлом меню, но никак не влияет на загруженное в AutoCAD меню. Точно так же как редактор для lisp-файлов (например, Notepad) не занимается загрузкой lisp-файлов в AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Или же вы хотите сказать, что метод AddPartialMenu не выполняет загрузку меню и её появление (после выполнения обозначенного кода) в перечне подгруженных CUI\CUIX, а так же появление в текущем Workspace ничего не означает?
Именно это я и хочу сказать. Команда _CUI работает с файлом меню и производит его загрузку/перезагрузку только по кнопке Apply или OK.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Вон оно как... Я думал, что правка выполняется как раз текущего, загруженного меню, с сохранением изменений в файл через вызов Save().

Спасибо!

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Все менюшки я создаю и заполняю программно, при загрузке dll в IExtensionApplication.Initialize
Иконки при таком подходе хранишь в виде набора отдельных файлов? Ведь ресурсный DLL сопоставляется с существующим CUI\CUIX.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вон оно как... Я думал, что правка выполняется как раз текущего, загруженного меню, с сохранением изменений в файл через вызов Save().
Фактически это только обертка над xml. Более того, насколько я помню AcCui.dll единственная из AutoCAD'овских .NET-сборок, которая может использоваться не только в dll-приложении для AutoCAD, но и в любых внешних приложениях. Во всяком случае так было раньше. В последних версиях я не проверял.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Но вроде бы в них это можно сделать через COM/ActiveX:
1) MenuGroup имеет метод Unload для выгрузки меню
2) MenuGroups имеет метод Load для загрузки меню
В ObjectARX SDK не вижу информации об этих методах. Каковы сигнатуры их вызова для AutoCAD 2009-2011? Попробую выполнить загрузку через позднее связывание. Приводит ли такая загрузка к автоматическому внесению правок и в сам файл CUI\CUIX или же изменения применятся только к текущей сессии?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В ObjectARX SDK не вижу информации об этих методах.
COM/ActiveX не входят в состав ObjectARX. Документация к ним отдельная. Например, эта: http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-5D302758-ED3F-4062-A254-FB57BAB01C44
Сигнатуры можешь глянуть в Autodesk.AutoCAD.Interop.dll
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Приводит ли такая загрузка к автоматическому внесению правок и в сам файл CUI\CUIX или же изменения применятся только к текущей сессии?
Ты правишь CUI\CUIX через CustomizationSection (и иже с ним), а загружаешь через COM/ActiveX
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
2) MenuGroups имеет метод Load для загрузки меню
Load успешно загружает меню и отображает Toolbars (т.е. с этим всё в порядке). Но для того, чтобы отобразились Ribbons приходится вручную переключиться на др. Workspace и обратно. Как этот момент обойти?

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

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Переключиться программно. Системная переменная WSCURRENT.
Я как раз и не хочу выполнять регенерацию риббонов этим способом, т.к. мелькание перед юзером переключающегося воркспейса - это плохой способ регенерации.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Возможно я ошибся и Load загружает только Toolbars но не Ribbons:

Код - C# [Выбрать]
  1. CustomizationSection csMain = new CustomizationSection(mainCuiFile);
  2.  
  3. if (!csMain.PartialCuiFiles.Contains(extensionMenuFullName))
  4. {
  5.         var mg = cad.MenuGroups.GetType().InvokeMember("Load",
  6.                         BindingFlags.Public | BindingFlags.InvokeMethod |
  7.                         BindingFlags.Instance, null, cad.MenuGroups, new object[] { extensionMenuFullName });
  8.                        
  9. #if AUTOCAD_2009
  10.         Autodesk.Windows.RibbonControl rc = RibbonServices.RibbonPaletteSet.RibbonControl;
  11.         RibbonTab tab = rc.FindTab("PROXY_TOOLS.UIDU_0003");
  12.         // tab is null
  13.         if (tab != null) tab.IsVisible = !tab.IsVisible;
  14.        
  15.         StringBuilder sb = new StringBuilder();
  16.         sb.AppendLine();
  17.  
  18.         // My ribbon tab is not exist here.
  19.         foreach (var item in rc.Tabs)
  20.         {
  21.                 sb.AppendLine(item.Name);
  22.         }
  23.         cad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(sb.ToString());
  24. #endif
  25. ...

Хотя тогда непонятно, почему переключение Workspace приводит к появлению моих риббонов.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В общем случае для AutoCAD 2009-2011 загрузка и отображение Toolbars и Ribbons из файлов CUI\CUIX может быть выполнена так:
Код - C# [Выбрать]
  1. // Menu loading displays Toolbars
  2. var mg = cad.MenuGroups.GetType().InvokeMember("Load",
  3.         BindingFlags.Public | BindingFlags.InvokeMethod |
  4.         BindingFlags.Instance, null, cad.MenuGroups, new object[] { extensionMenuFullName });
  5.  
  6. // Workspace switching displays ribbons
  7. string ws = (string)cad.GetSystemVariable("WSCURRENT");
  8. cad.SetSystemVariable("WSCURRENT", ws);
Мне не нравится, что приходится переключать рабочее пространство, дабы риббоны появились. Если так будет поступать каждое расширение, то тормоза неизбежны...

В более новых версиях акада все эти танцы с бубном берёт на себя загрузчик пакетов.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Фактически это только обертка над xml. Более того, насколько я помню AcCui.dll единственная из AutoCAD'овских .NET-сборок, которая может использоваться не только в dll-приложении для AutoCAD, но и в любых внешних приложениях. Во всяком случае так было раньше. В последних версиях я не проверял.
Полезная информация!

На данный момент времени я в методе Terminate() произвожу выгрузку своих меню, дабы в случае деинсталляции (через установку\удаление программ Windows) расширения не оставалось "хвостов". Однако если есть возможность пользоваться AcCui.dll из внешних приложений, то можно выгрузку перенести из Terminate() в процесс деинсталляции самого MSI-пакета (WiX), посредством AcCui.dll произведя выгрузку (если она требуется)...

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

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

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Иконки при таком подходе хранишь в виде набора отдельных файлов? Ведь ресурсный DLL сопоставляется с существующим CUI\CUIX.
Нет иконки храню в ресурсах, которые разворачиваю в %TEMP% и загружаю через COM SetBitmaps.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Дима_
А как хранишь местоположение, количество строк, Docking/Floating-состояние? Используешь ли Ленту?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Ленту не использую (точнее проектный отдел не использует - и мне соотв. не надо). Про состояние я уже писал - вначале проверяю есть ли такой  toolbars - если он есть (а соответственно есть и где он лежит,как виден и пр.) - то просто добавляю кнопки на него, если нету создаю свой новый.
з.ы. У меня все, включая исполнятемые dll хранится в СУБД, автокад при старте только запускает "загрузчик" из нее. Соответственно все кнопки, команды в соотв. с уровнем доступа выдаются при старте, наверно для "статичных" приложений такой подход избыточный.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Про состояние я уже писал - вначале проверяю есть ли такой  toolbars - если он есть (а соответственно есть и где он лежит,как виден и пр.) - то просто добавляю кнопки на него, если нету создаю свой новый.
Вот тут то собака и зарыта. Если добавляешь свои кнопки в один из стандартных toolbar AutoCAD, то за свойствами этого toolbar следит AutoCAD и сохраняет его между сеансами работы. А вот если тебе приходится создавать на лету свой toolbar, то всё становится крайне неприятным. Если ты не будешь запоминать положение этого toolbar, то пользователя это будет раздражать. Ему придётся при каждом запуске его куда-то перетаскивать или вообще закрывать toolbar, если он не нужен. cui(x) берут это на себя запоминание положений toolbar'ов.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Если добавляешь свои кнопки в один из стандартных toolbar AutoCAD, то за свойствами этого toolbar следит AutoCAD и сохраняет его между сеансами работы. А вот если тебе приходится создавать на лету свой toolbar, то всё становится крайне неприятным. Если ты не будешь запоминать положение этого toolbar, то пользователя это будет раздражать. Ему придётся при каждом запуске его куда-то перетаскивать или вообще закрывать toolbar, если он не нужен. cui(x) берут это на себя запоминание положений toolbar'ов.
Это основная причина по которой я всегда был и есть против программного создания менюшек в акаде.

Если ты не будешь запоминать положение этого toolbar, то пользователя это будет раздражать. Ему придётся при каждом запуске его куда-то перетаскивать или вообще закрывать toolbar, если он не нужен. cui(x) берут это на себя запоминание положений toolbar'ов.
Неоднократно присутствовал при таких ситуациях (у некоторых юзеров понакачено из инета). Преимущественно от пользователя в этот мометн слышался мат и недоумение о том, почему "оно" не может запомнить "своё" место.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Вот тут то собака и зарыта. Если добавляешь свои кнопки в один из стандартных toolbar AutoCAD, то за свойствами этого toolbar следит AutoCAD и сохраняет его между сеансами работы. А вот если тебе приходится создавать на лету свой toolbar...
Еще раз - он создается если с таким именем его нет. Если пользователю надо чтоб он оставался там где ему надо - он создает свой пустой и ставит куда нужно.  Настолько "одаренных" юзеров которые не могут по фразе команда "_cui" во вкладке панели -> добавить панель - не могут этого сделать - у нас не держат ибо основная их работа требует более интеллектуальных навыков.
Создание нового - требуется если в доступе или в функционале юзера, что-то изменилось и у него появилась новая панель со своими кнопками.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Настолько "одаренных" юзеров которые не могут по фразе команда "_cui" во вкладке панели -> добавить панель - не могут этого сделать - у нас не держат ибо основная их работа требует более интеллектуальных навыков.
Значит тебе очень повезло.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Значит тебе очень повезло.
Тут вообще отдельная тема - не имеющая никакого отношения к программированию, но тем не менее крайне важная для "нашего брата" - уверяю что нет такого пользователя автокада, который в нем должен работать и не может разобраться (хотя-бы под запись) в чем-то типа добавления в меню. Есть либо упертые, либо зазнавшиеся или очень важные персоны - которые считают, что это им кто-то все должен. Ему можно просто отключить кнопки - и дать список команд. У меня к последней "системе" вообще никто "насильно" подключен не был - не хочешь "руби руками" пока не дозреешь до коллег, которые пол дня кофе пьют и в теннис играют - но больше (и лучше) тебя работы делают - если есть обоснованные претензии (пожелания) к функционалу - всегда рассматриваем вопрос как их реализовать - всем все равно не угодить - частично по этому и допуск разный.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если пользователю надо чтоб он оставался там где ему надо - он создает свой пустой и ставит куда нужно.
Для этой цели пользователь как минимум должен знать имя этого toolbar. Т.е. имя должно быть зарезервировано. В противном случае даже если ты добавишь к какому-то toolbar'у свою кнопку, то как об этом догадается пользователь если у него этих toolbar'ов пару десятков на экране? Это (описать как следует назвать toolbar'ы для твоих приложений) можно сделать в своей организации, но для коммерческого продукта - это плохой стиль (IMHO).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Если пользователю надо чтоб он оставался там где ему надо - он создает свой пустой и ставит куда нужно.
ИМХО - это лишнее телодвижение для пользователя, которое можно было бы легко избежать в случае использования CUI\CUIX.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если пользователю надо чтоб он оставался там где ему надо - он создает свой пустой и ставит куда нужно.
ИМХО - это лишнее телодвижение для пользователя, которое можно было бы легко избежать в случае использования CUI\CUIX.
Кстати, что-то в Диминой идее мне кажется есть. Но вот если совместить его идею и CUI\CUIX с пустыми toolbar'ами, которые он наполняет, то возможно получится неплохой вариант...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Кстати, что-то в Диминой идее мне кажется есть. Но вот если совместить его идею и CUI\CUIX с пустыми toolbar'ами, которые он наполняет, то возможно получится неплохой вариант...
Мне в этой идее не нравится такой момент, что юзер, имеющий опыт работы с  CUI\CUIX, может быть сбит с толку таким поведением, не понимая, почему в различных условиях состав одного и того же Toolbar может отличаться. Он ведь не в курсе программной обработки менюшек. Ну, либо это должно быть документировано в справке расширения.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Он ведь не в курсе программной обработки менюшек.
Зато можно реализовать что-то наподобие "контекстных toolbar". Например, выбраны полилинии - одни кнопки по работе с ними, выбраны сплайны - другие кнопки... Может быть даже весело. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Зато можно реализовать что-то наподобие "контекстных toolbar". Например, выбраны полилинии - одни кнопки по работе с ними, выбраны сплайны - другие кнопки... Может быть даже весело. :)
http://bushman-andrey.blogspot.ru/2012/10/autocad.html

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Более того, насколько я помню AcCui.dll единственная из AutoCAD'овских .NET-сборок, которая может использоваться не только в dll-приложении для AutoCAD, но и в любых внешних приложениях. Во всяком случае так было раньше. В последних версиях я не проверял.

Консольный проект, .NET 4.6.1, AnyCPU.
Подключена AcCUI.dll (Copy Local = False).

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Customization;
  2. ...
  3. static void Main(string[] args) {
  4.     try {
  5.         string acCUIX = Environment.ExpandEnvironmentVariables(
  6.             @"%AppData%\Autodesk\AutoCAD 2016\R20.1\enu\Support\acad.CUIX");
  7.  
  8.         CustomizationSection csMain = new CustomizationSection(acCUIX);
  9.  
  10.         if (!File.Exists(acCUIX)) {
  11.             throw new FileNotFoundException(acCUIX);
  12.         }
  13.  
  14.         string extCUIX = Environment.ExpandEnvironmentVariables(
  15.             @"%ProgramFiles%\Autodesk\ApplicationPlugins\Bushman.ProxyTools.bundle" +
  16.             @"\Contents\Resources\Proxy_Tools_2010.cuix");
  17.  
  18.         if (!File.Exists(acCUIX)) {
  19.             throw new FileNotFoundException(extCUIX);
  20.         }
  21.  
  22.         csMain.AddPartialMenu(extCUIX);
  23.  
  24.         if (csMain.IsModified == true) {
  25.             // Save CUI\CUIX file all changes
  26.             csMain.Save();
  27.         }
  28.     }
  29.     catch (Exception ex) {
  30.         Console.WriteLine(ex.Message);
  31.     }
  32.     Console.WriteLine("Press any key for exit...");
  33.     Console.ReadKey();
  34. }

Полученный EXE закидываю в каталог %ProgramFiles%\Autodesk\AutoCAD 2016\.

Цитата: Консольный вывод
Не удалось загрузить файл или сборку "Acdbmgd, Version=20.1.0.0, Culture=neutral, PublicKeyToken=null" либо одну из их зависимостей. Была сделана попытка загрузить программу, имеющую неверный формат.
Press any key for exit...

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
А вот для AcCUI.dll от AutoCAD 2009 модифицированный вариант кода, во внешнем консольном приложении, отработал успешно:

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Customization;
  2. ...
  3. static void Main(string[] args) {
  4.     try {
  5.         string acCUI = Environment.ExpandEnvironmentVariables(
  6.             @"%AppData%\Autodesk\AutoCAD 2009\R17.2\enu\Support\acad.CUI");
  7.         CustomizationSection csMain = new CustomizationSection(acCUI);
  8.         if (!File.Exists(acCUI)) {
  9.             throw new FileNotFoundException(acCUI);
  10.         }
  11.  
  12.         string extCUI = Environment.ExpandEnvironmentVariables(
  13.             @"%ProgramFiles%\Autodesk\ApplicationPlugins\Bushman.ProxyTools.bundle" +
  14.             @"\Contents\Resources\Proxy_Tools_2009.cui");
  15.         if (!File.Exists(acCUI)) {
  16.             throw new FileNotFoundException(extCUI);
  17.         }
  18.         CustomizationSection csExt = new CustomizationSection(extCUI);
  19.         csMain.AddPartialMenu(csExt);
  20.  
  21.         if (csMain.IsModified == true) {
  22.             // Save CUI file all changes
  23.             csMain.Save();
  24.         }
  25.     }
  26.     catch (Exception ex) {
  27.         Console.WriteLine(ex.Message);
  28.     }
  29.     Console.WriteLine("Press any key for exit...");
  30.     Console.ReadKey();
  31. }

Но это было для CUI (не для CUIX). Попробую в 2010-м то же самое для CUIX провернуть.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Работает в 2009-2016. В первый раз я, видимо, с референсами накосячил.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Была когда-то тонкость (или в 2006-ом или в 2007-ом) и мне о ней рассказал Tony Tanzillo, что для того чтобы эта сборка работала приложение должно находится в каталоге с acad.exe. Судя по твоему эксперименту это уже не актуально.
P.S.: Нашёл это обсуждение: https://forums.autodesk.com/t5/net/install-toolbar-cui-net-api/td-p/1748176
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Была когда-то тонкость (или в 2006-ом или в 2007-ом) и мне о ней рассказал Tony Tanzillo, что для того чтобы эта сборка работала приложение должно находится в каталоге с acad.exe. Судя по твоему эксперименту это уже не актуально.
P.S.: Нашёл это обсуждение: https://forums.autodesk.com/t5/net/install-toolbar-cui-net-api/td-p/1748176
Я тестировал оба варианта: сначала с размещением моего exe в каталоге акада, потом - с размещением в произвольном каталоге.

Во втором случае для разрешения конфликтов ссылок я воспользовался событием AppDomain.AssemblyResolve. Это позволило не размещать мои сборки в каталоге акада для использования AcCUI.dll.

Код - C# [Выбрать]
  1. static void Main(string[] args) {
  2.     try {
  3.         AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
  4.         // CUI\XUIX file edition are to be in the separate method.
  5.         EditCUI();
  6.     }
  7.     catch (Exception ex) {
  8.         Console.WriteLine(ex.Message);
  9.     }
  10.     Console.WriteLine("Press any key for exit...");
  11.     Console.ReadKey();
  12. }
  13.  
  14. static string acadRootDir = @"C:\Program Files\Autodesk\AutoCAD 2016";
  15.  
  16. static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
  17.     string path = Path.Combine(acadRootDir, args.Name.Split(',').First() + ".dll");
  18.     if (File.Exists(path)) {
  19.         Assembly asm = Assembly.LoadFile(path);
  20.         return asm;
  21.     }
  22.     else {
  23.         return null;
  24.     }
  25. }
Это означает, что в процессе деинсталляции можно программно проверять наличие установленных версий AutoCAD, и для обнаруженных версий выгружать файл Partial CUI\CUIX деинсталлируемого приложения, если оно было подгружено в основной CUI\CUIX (посредством использования AcCUI.dll соответствующей версии AutoCAD).

Кроме того, в процессе инсталляции для AutoCAD 2009-2011 (т.е. где нет обновлённого загрузчика пакетов) можно для обнаруженных версий AutoCAD 2009-2011 программно править основной CUI\CUIX, прописывая в нём подгрузку Partial CUI\CUIX инсталлируемого приложения и добавляя регистрацию в реестре на автозагрузку.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Во втором случае для разрешения конфликтов ссылок я воспользовался событием AppDomain.AssemblyResolve. Это позволило не размещать мои сборки в каталоге акада для использования AcCUI.dll.
Ага. Т.е. проблема с разрешением ссылок для AcCui.dll сохранилась и в более новых версиях.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Т.е. проблема с разрешением ссылок для AcCui.dll сохранилась и в более новых версиях.
Это не проблема и соответствует поведению, по поиску ресурсов, свойственному любому .NET приложению. AppDomain.AssemblyResolve как раз и существует в качестве вспомогательного инструмента уже много лет. Использование обозначенного метода я демонстрировал ещё в 2011-м году, например, в этой песочнице.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
AppDomain.AssemblyResolve как раз и существует в качестве вспомогательного инструмента уже много лет. Использование обозначенного метода я демонстрировал ещё в 2011-м году, например, в этой песочнице.
2011-ой это не 2007-ой, но ты прав. Я посмотрел, что это событие было даже в .NET 1.1 и соотвественно могло использоваться даже в AutoCAD 2006: https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve%28v=vs.71%29.aspx
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В принципе, для того, чтобы подправить CUI\CUIX (добавить\удалить) запись об Partial CUI\CUIX, можно вполне обойтись и без AcCUI.dll (причём без каких-либо сложностей), но если уж возможность её использовать вне акада (но при обязательном установленном акаде - это ограничение), то выбор пути решения - это на усмотрение разработчика. Вообще, я не сторонник дополнительных зависимостей...

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Пытаюсь программно обойти баг, ранее обозначенный мною здесь. У меня имеется DLL, позволяющая выполнять конфигурирование AutoCAD извне (т.е. эта DLL предназначена для использования внешними по отношению к AutoCAD приложениями). В этой же DLL, помимо прочего, реализован функционал по подключению\отключению файлов частичной адаптации в CUI\CUIX (динамически подгружает в отдельный домен нужную версию AcCui.dll и использует её API, после чего домен выгружается).

Если после этого я запускаю AutoCAD, то в редакторе CUI вижу, что в состав частичных файлов основного файла меню был успешно подключен тот, который мне нужен (подключение выполнила указанная выше DLL). Однако в AutoCAD риббоны и туллбары подключенного файла не отображаются. В виду того, что библиотека не является плагином AutoCAD, то варианты с MenuGroups.Load() и _CUILOAD не подходят, т.к. код работает вне автокада.

 Какие изменения мне нужно выполнить (в реестре либо в файлах), чтобы при очередном старте AutoCAD корректно загрузил в т.ч. и файл частичного меню, который я программно указал в качестве подключенного в основном файле меню (например в acad.cuix)?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Какие изменения мне нужно выполнить (в реестре либо в файлах), чтобы при очередном старте AutoCAD корректно загрузил в т.ч. и файл частичного меню, который я программно указал в качестве подключенного в основном файле меню (например в acad.cuix)?
Ну наверное тебе нужно поработать еще и с Workspace в acad.cuix через AcCui.dll
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Ну наверное тебе нужно поработать еще и с Workspace в acad.cuix через AcCui.dll
Да, похоже на то...

Если после указанных мною выше изменений я удаляю соответствующие mnl-файлы, то при запуске AutoCAD обычные туллбары из подгруженного мною частичного меню появляются, но риббоны - нет. В редакторе интерфейса вижу, что риббоны не подгружены в текущий воркспейс. Собственно это и не новость, т.к. я уже указывал это поведение в начале топика.

На мой взгляд, более логичным было бы одинаковое поведение в данной ситуации как для туллбаров, так и для риббонов (например, чтобы оба отсутствовали в текущем воркспейсе).