Определение загруженных DVB

На самом деле вопрос носит полуакадемический характер: "можно ли определить лиспом, какие dvb-проекты загружены?" Естественно, можно! :)

Будем получать полные имена файлов dvb. Правда, этот код не скажет, какие функции и процедуры загружены, ну да ладно...

Снимем дамп с объекта приложения ACAD:

1
2
3
4
5
6
7
8
9
10
_$ (vlax-dump-Object (vlax-get-acad-object))
; IAcadApplication: An instance of the AutoCAD application
; Property values:
<...>
;   Preferences (RO) = #<VLA-OBJECT IAcadPreferences 000000000ed63b48>
;   StatusId (RO) = ...Indexed contents not shown...
;   VBE (RO) = #<VLA-OBJECT VBE 000000002ef0cfa8>
;   Version (RO) = "17.2s (LMS Tech)"
;   Visible = -1
<...>

Есть тут одна интересная строка - VBE. Больно сильно напоминает Visual Basic Environment. Если продолжить ковыряться уже в этом свойстве, можно найти, что в нем хранятся записи обо всех загруженных dvb-приложениях. Следует помнить, что dvb загружаются не в пространство документа, а в пространство приложения AutoCAD.

Общая технология такова: получаем указатель на VBE, потом - на загруженные VBPorjects (проекты VBA), потом итерацией проходим по ним и для каждого элемента получаем его FileName:

1
2
3
4
5
6
7
8
9
10
11
12
(vl-load-com)

(defun get-dvb-loaded (/ lst res count)
  (if (setq lst (vlax-get (vla-get-vbe (vlax-get-acad-object)) "VBProjects"))
    (repeat (setq count (vla-get-count lst))
      (setq res   (cons (vla-get-filename (vla-item lst count)) res)
            count (1- count)
            ) ;_ end of setq
      ) ;_ end of repeat
    ) ;_ end of if
  (vl-sort res '<)
  ) ;_ end of defun

Есть тут одна немного странная особенность: похоже, что индексация элементов начинается не с 0, а с 1 (!). И касается это любого наследника VBE!
Все это хорошо работает, если мы запускаем код в AutoCAD вплоть до 2009 версии, где VBA был интегрирован. А что будет, если запустить его, например, в AutoCAD 2014, где VBA может быть и не установлен?

При попытке выполнить строку вида (vla-get-VBE (vlax-get-acad-object)) мы получим сообщенеи об ошибке. Поэтому код надо немного переделать:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(vl-load-com)

(defun get-dvb-loaded (/ lst res count)
  (if (not (vl-catch-all-error-p
             (setq lst (vl-catch-all-apply
                         (function
                           (lambda () (vlax-get (vla-get-vbe (vlax-get-acad-object)) "VBProjects"))
                           ) ;_ end of function
                         ) ;_ end of vl-catch-all-apply
                   ) ;_ end of setq
             ) ;_ end of vl-catch-all-error-p
           ) ;_ end of not
    (repeat (setq count (vla-get-count lst))
      (setq res   (cons (vla-get-filename (vla-item lst count)) res)
            count (1- count)
            ) ;_ end of setq
      ) ;_ end of repeat
    ) ;_ end of if
  (vl-sort res '<)
  ) ;_ end of defun

Вот, теперь уже больше похоже на правду :)

В принципе, можно у каждого модуля получать не только его FileName, но и VBComponents (есть там такое свойство). Пройдя дальше, можно добраться до имен загруженных модулей (VBProjects, Collection) и даже попытаться что-то получать напрямую из кода. Правда, документации на это дело я не обнаружил (с другой стороны, особо и не искал).
---
На основе материлов из jtbworld.com. Но переделок и дополнений тут вполне прилично :)

Размещено в AutoCAD, Код LISP, Новости, Функции LISP · Метки: ,



Комментарии

Есть 2 коммент. к “Определение загруженных DVB”
  1. Сергей пишет:

    Для примера в ACAD загрузил project.dvb (здесь сидит спецкалькулятор). Загрузил ваш лисп. В комстроке пишет:

    1
    2
    3
    4
    Команда:
    Команда: (LOAD "D:/Work/Детали для AutoCAD/App_lisp/Проверка.lsp") GET-DVB-LOADED
    Команда: (get-dvb-loaded)
    no function definition: VLA-GET-FILENAME

    Что пишу не так?

  2. Кулик Алексей aka kpblc пишет:

    Последние лет 5 (если не больше) я к VBA имею очень опосредованное отношение - ну не нравится он мне! :)
    Откуда взят dvb? Я специально взял первый попавшийся, тупо его загрузил и сразу выполнил код. Все сработало.
    Может, дело в версии ACAD?

Поделитесь своим мнением


Я не робот.