| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Не могу корректно сменить основной файл меню

LISP. Не могу корректно сменить основной файл меню

Ответ
Поиск в этой теме
Непрочитано 27.06.2016, 22:45 #1
LISP. Не могу корректно сменить основной файл меню
Кулик Алексей aka kpblc
Moderator
 
LISP, C# (ACAD 200[9,12,13,14])
 
С.-Петербург
Регистрация: 25.08.2003
Сообщений: 39,844

В силу разных причин приходится для разных версий и профилей AutoCAD иметь разные по расположению файлы основного меню. Смену основного файла меню выполняю при старте AutoCAD, только один раз. Код выдран с мясом из рабочей копии:
Код:
[Выделить все]
 (vl-load-com)

(setq *kpblc-acad* (vlax-get-acad-object)
      *kpblc-adoc* (vla-get-activedocument (vlax-get-acad-object))
      ) ;_ end of setq

(defun test (/ main_menu_file path)
  (setq path           (vl-string-right-trim
                         "\\"
                         (_kpblc-dir-create
                           (strcat (vl-string-right-trim "\\" (getenv "AppData"))
                                   "\\kpblc\\AutoCAD\\"
                                   (_kpblc-acad-version-with-bit-and-loc)
                                   "\\"
                                   (_kpblc-get-profile-name)
                                   ) ;_ end of strcat
                           ) ;_ end of _kpblc-dir-create
                         ) ;_ end of vl-string-right-trim
        main_menu_file (cond ((vl-directory-files
                                (vl-filename-directory (vla-get-menufile (vla-get-files (vla-get-preferences *kpblc-acad*))))
                                (strcat (vl-filename-base (vla-get-menufile (vla-get-files (vla-get-preferences *kpblc-acad*))))
                                        ".*"
                                        ) ;_ end of strcat
                                ) ;_ end of vl-directory-files
                              (vl-filename-base (vla-get-menufile (vla-get-files (vla-get-preferences *kpblc-acad*))))
                              )
                             ((setq main_menu_file
                                     (findfile
                                       (strcat (vl-filename-base (vla-get-menufile (vla-get-files (vla-get-preferences *kpblc-acad*))))
                                               (if (< (_kpblc-acad-version) 18.)
                                                 ".cui"
                                                 ".cuix"
                                                 ) ;_ end of if
                                               ) ;_ end of strcat
                                       ) ;_ end of findfile
                                    ) ;_ end of setq
                              (_kpblc-cmd-silence (list "_.menu" main_menu_file))
                              (vl-filename-base (vla-get-menufile (vla-get-files (vla-get-preferences *kpblc-acad*))))
                              )
                             ) ;_ end of cond
        main_menu_file (car
                         (vl-remove-if-not
                           (function (lambda (x)
                                       (= (strcase (vl-filename-base (cdr (assoc "menufilename" x)))) (strcase main_menu_file))
                                       ) ;_ end of lambda
                                     ) ;_ end of function
                           (mapcar (function (lambda (x)
                                               (mapcar (function (lambda (pr) (cons (strcase pr t) (vlax-get-property x pr))))
                                                       '("name" "menufilename")
                                                       ) ;_ end of mapcar
                                               ) ;_ end of lambda
                                             ) ;_ end of function
                                   (_kpblc-conv-vla-to-list (vla-get-menugroups *kpblc-acad*))
                                   ) ;_ end of mapcar
                           ) ;_ end of vl-remove-if-not
                         ) ;_ end of car
        ) ;_ end of setq
  (if (/= (strcase
            (vl-string-right-trim "\\" (vl-filename-directory (cdr (assoc "menufilename" main_menu_file))))
            ) ;_ end of strcase
          (strcase (vl-string-right-trim "\\" path))
          ) ;_ end of /=
    (progn ;; Здесь код упростил, тупо выполняю копирование файла основного меню
           (foreach file (vl-directory-files
                           path
                           (strcat (vl-filename-base (cdr (assoc "menufilename" main_menu_file))) ".*")
                           ) ;_ end of vl-directory-files
             (vl-file-delete (strcat (_kpblc-dir-path-and-splash (_kpblc-get-path-local "menu")) file))
             ) ;_ end of foreach
           (foreach file (vl-remove-if
                           (function
                             (lambda (x)
                               (or (wcmatch (strcase x t) "*.bak.*,*._*") (not (wcmatch (strcase x t) "*.cui*,*.mnl,*.dll")))
                               ) ;_ end of lambda
                             ) ;_ end of function
                           (vl-directory-files
                             (vl-filename-directory (cdr (assoc "menufilename" main_menu_file)))
                             (strcat (vl-filename-base (cdr (assoc "menufilename" main_menu_file))) ".*")
                             1
                             ) ;_ end of vl-directory-files
                           ) ;_ end of vl-remove-if
             (vl-file-copy
               (strcat (vl-string-right-trim "\\" (vl-filename-directory (cdr (assoc "menufilename" main_menu_file))))
                       "\\"
                       file
                       ) ;_ end of strcat
               (strcat path "\\" file)
               ) ;_ end of vl-file-copy
             ) ;_ end of foreach
           ;; И теперь выполняем установку нового файла меню.
           ;; Вариант 1: выполнение прекращается с фатальной ошибкой
           ;|
           (vla-put-menufile
             (vla-get-preferences *kpblc-acad*)
             (strcat path "\\" (vl-filename-base (cdr (assoc "menufilename" main_menu_file))))
             ) ;_ end of vla-put-menufile
             |;
           ;; Вариант 2: выполнение приводит к ошибке ядра (0x000000c5, кажется)
           (vl-cmdf "_.menu"
                    (strcat path
                            "\\"
                            (vl-filename-base (cdr (assoc "menufilename" main_menu_file)))
                            (if (< (atof (getvar "acadver")) 18.)
                              ".cui"
                              ".cuix"
                              ) ;_ end of if
                            ) ;_ end of strcat
                    ) ;_ end of vl-cmdf
           ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of defun
(defun _kpblc-acad-version-with-bit ()
  (strcat (itoa (atoi (vl-string-trim "VISUALP " (strcase (ver)))))
          "x"
          (if (and (getvar "platform") (wcmatch (strcase (getvar "platform")) "*X64*"))
            "64"
            "32"
            ) ;_ end of if
          ) ;_ end of strcat
  ) ;_ end of defun
(defun _kpblc-acad-version-with-bit-and-loc ()
  (strcat (_kpblc-acad-version-with-bit)
          "-"
          (vl-registry-read (strcat "HKEY_LOCAL_MACHINE\\" (vlax-product-key)) "LocaleID")
          ) ;_ end of strcat
  ) ;_ end of defun
(defun _kpblc-conv-vla-to-list (value / res)
  (cond ((listp value) (mapcar (function _kpblc-conv-vla-to-list) value))
        ((= (type value) 'variant) (_kpblc-conv-vla-to-list (vlax-variant-value value)))
        ((= (type value) 'safearray)
         (if (>= (vlax-safearray-get-u-bound value 1) 0)
           (_kpblc-conv-vla-to-list (vlax-safearray->list value))
           ) ;_ end of if
         )
        ((and (member (type value) (list 'ename 'str 'vla-object))
              (= (type (_kpblc-conv-ent-to-vla value)) 'vla-object)
              (vlax-property-available-p (_kpblc-conv-ent-to-vla value) 'count)
              ) ;_ end of and
         (vlax-for sub (_kpblc-conv-ent-to-vla value) (setq res (cons sub res)))
         )
        (t value)
        ) ;_ end of cond
  ) ;_ end of defun
(defun _kpblc-conv-ent-to-ename (ent_value / _lst)
  (cond ((= (type ent_value) 'vla-object) (vlax-vla-object->ename ent_value))
        ((= (type ent_value) 'ename) ent_value)
        ((and (= (type ent_value) 'str) (handent ent_value) (entget (handent ent_value)))
         (handent ent_value)
         )
        ((and (= (type ent_value) 'str) (handent ent_value) (tblobjname "style" ent_value))
         (tblobjname "style" ent_value)
         )
        ((and (= (type ent_value) 'str) (handent ent_value) (tblobjname "dimstyle" ent_value))
         (tblobjname "dimstyle" ent_value)
         )
        ((and (= (type ent_value) 'str) (handent ent_value) (tblobjname "block" ent_value))
         (tblobjname "block" ent_value)
         )
        ((and (= (type ent_value) 'list) (cdr (assoc -1 ent_value))) (cdr (assoc -1 ent_value)))
        (t nil)
        ) ;_ end of cond
  ) ;_ end of defun
(defun _kpblc-conv-ent-to-vla (ent_value / res)
  (cond ((= (type ent_value) 'vla-object) ent_value)
        ((= (type ent_value) 'ename) (vlax-ename->vla-object ent_value))
        ((setq res (_kpblc-conv-ent-to-ename ent_value)) (vlax-ename->vla-object res))
        ) ;_ end of cond
  ) ;_ end of defun
(defun _kpblc-get-profile-name ()
  (vl-list->string
    (vl-remove-if-not
      (function
        (lambda (x) (or (<= 48 x 57) (<= 65 x 90) (<= 97 x 122) (= x 32) (<= 224 x 255) (<= 192 x 223)))
        ) ;_ end of function
      (vl-string->list (getvar "cprofile"))
      ) ;_ end of vl-remove-if
    ) ;_ end of VL-LIST->STRING
  ) ;_ end of defun
(defun _kpblc-dir-create (path / tmp)
  (cond ((vl-file-directory-p path) path)
        ((setq tmp (_kpblc-dir-create (vl-filename-directory path)))
         (vl-mkdir (strcat tmp
                           "\\"
                           (vl-filename-base path)
                           (cond ((vl-filename-extension path))
                                 (t "")
                                 ) ;_ end of cond
                           ) ;_ end of strcat
                   ) ;_ end of vl-mkdir
         (if (vl-file-directory-p path)
           path
           ) ;_ end of if
         )
        ) ;_ end of cond
  ) ;_ end of defun
Частичные меню можно (на данный момент) игнорировать. Пути поиска устанавливаются в другом месте и гарантированно содержат новый путь к основному меню. Проблемные места выделены в функции test, в комментариях со словами "Вариант ".
Если вручную выполнить команду _,menu, то все срабатывает корректно, ошибка не появляется. Проблему необходимо решить для AutoCAD 2009 и 2013, а также вертикалок (Map3D, Civil), независимо от локализации и разрядности. Собственно вопрос: где и что я не учел? Что можно сделать, чтобы смена основного файла меню не приводила ни к фатальным ошибкам, ни (в идеале) не требовала перезапуска AutoCAD?
Спасибо.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Просмотров: 2144
 
Непрочитано 28.06.2016, 09:19
#2
P_S


 
Регистрация: 09.10.2006
Санкт-Петербург
Сообщений: 99


Навскидку: по первому варианту, наверное, надо
Код:
[Выделить все]
 (vla-put-menufile(vla-get-files(vla-get-preferences *kpblc-acad*)... и т. д.
Будет время, буду дальше думать.
P_S вне форума  
 
Автор темы   Непрочитано 28.06.2016, 09:36
#3
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,844


Не срабатывало, вываливало ошибку. Александр Ривилис подсказал пару других путей, как попробую - расскажу о результатах.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 28.06.2016, 12:41
#4
P_S


 
Регистрация: 09.10.2006
Санкт-Петербург
Сообщений: 99


По ходу дела думал, и решил, что конфликт возникает за счет того, что в коллекции MenuGroups может быть только одна группа меню типа acBaseMenuGroup. Вероятно, при работе через интерфейс программы, за кадром, для этой группы выполняются методы Unload и Load, а в лисповской программе этого не происходит. Значит, надо принудительно (и Load с опцией BaseMenu).
P_S вне форума  
 
Автор темы   Непрочитано 30.06.2016, 17:16
#5
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,844


Если коротко, выяснилось следующее:
Прежде всего не забыть поменять пути поиска AutoCAD (у меня-то это в реальной версии делается, здесь просто не приводил). Дальше, потребуется копирование не только cui/cuix, то и mnl и dll (если, конечно, они существуют). Конструкция типа (vla-load FllCuiName :vlax-true) срабатывает корректно. Но в некоторых случаях сразу после ее применения необходимо выполнить (princ), чтобы AutoCAD "подхватил" изменения. После установки основного файла меню почти гарантированно потребуется установить рабочее пространство.
Ошибка выполнения возникала в строке обращения к внедокументной переменной через vl-bb-set - вот уж чего не ожидал...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 02.07.2016, 14:04
#6
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Дальше, потребуется копирование не только cui/cuix, то и mnl и dll (если, конечно, они существуют).
Копирование куда?
gomer вне форума  
 
Автор темы   Непрочитано 03.07.2016, 18:09
#7
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,844


Туда же, куда и основное меню копируется - в тот самый "отдельный" каталог.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 03.07.2016, 22:38
#8
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
в тот самый "отдельный" каталог.
Отдельный каталог где? на рабочей станции, на сервере, в облаке?
gomer вне форума  
 
Автор темы   Непрочитано 04.07.2016, 08:51
#9
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,844


Ну, пока есть возможность, расскажу
Когда выполняется загрузка дополнительных (partial) меню, или меняется порядок их следования, то все эти изменения записываются в основной файл меню. Если надо в разных профилях AutoCAD иметь разные наборы частичных меню (а вместе с ними могут быть и разные mnl), то приходится извращаться, "разделяя" основной файл меню. Для каждого профиля AutoCAD в таком случае должен быть свой "основной" файл меню.
Например, есть частичные меню: test1.cui, test1.dll, test1.mnl и test2.cui, test2.mnl. Есть два разных профиля AutoCAD: "Test1 profile" и "Test2 profile". В первом должно быть подгружено только меню test1, во втором - только test2, независимо от текущего рабочего пространства. По-моему, сделать такой финт без того, чтобы каждому профилю назначить свой основной файл меню, невозможно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Не могу корректно сменить основной файл меню

Размещение рекламы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Civil 3D 2012. Как построить поверхность котлована для определения его объёма? vovkaf Вертикальные решения на базе AutoCAD 5 25.08.2014 07:39
не могу отредактировать файл Dronovigor AutoCAD 4 15.05.2012 18:38
Не могу отредактировать файл dwg. Создан в Autocad 2011+SPDS. Помогите пож-та... 9594999 AutoCAD 9 08.05.2012 18:33
Файл, созданный в учебной версии программы с программой на LISP divega AutoCAD 7 20.05.2010 14:12
Из сети не могу скопиравать файл! Vildar Разное 6 02.10.2008 13:52