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

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

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

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

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

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

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