Jump to content

Выполнить lisp при открытии файла, как


Recommended Posts

Подскажите пожалуйста, куда прописать lisp, чтобы он выполнялся при открытии каждого файла чертежа?

А то от этого геомаркера и сетки уже кровь из глаз

Link to comment
Share on other sites

Ну ты же на NET пишешь, правильно? Проще всего будет подписаться на событие DocumentCreated и там уже вызывать все что надо.

Link to comment
Share on other sites

Похоже, можно только через обработку события

Спойлер

image.png.aa53e2159c4e2aa35ec52c198f64091e.png

или где-то рядом. 

 

Более предпочтительным выглядит событие "EndOpen"

Edited by EdwardSt
Link to comment
Share on other sites

13 минут назад, kpblc сказал:

Ну ты же на NET пишешь, правильно?

пишешь это громко сказано)))

блин... , чтоб поменять несколько переменных целый комбайн NET  заводить

10 минут назад, EdwardSt сказал:

Похоже, можно только через обработку события

Спойлер

image.png.f2831a248d2b75cbf83044f7fa3f4b5d.png

должно жэж быть элементарно....

в АК даже не задумывался об этом

Link to comment
Share on other sites

Только что, doctorraz сказал:

должно жэж быть элементарно...

Ты же сам в курсе, что ncad.lsp грузится только в начале сеанса, в отличии от АС, где возможна загрузка acad.lsp с каждым документом.

 

Даю наводку: напиши свой стартер типа "drz_ncad.lsp",  в который будешь вписывать свои экспериментальные лисп-вызовы.

А для него создай универсальный стартер на NET (или подобном), натравленный на подходящее событие и вызывающий этот скрипт при наступлении оного.

Link to comment
Share on other sites

Так в ACAD у тебя лисп грузится в пространство документа, а не приложения. А реакторов в NC, насколько я помню, нет в классическом виде.

Link to comment
Share on other sites

1 минуту назад, EdwardSt сказал:

Даю наводку: напиши свой стартер типа "drz_ncad.lsp",  в который будешь вписывать свои экспериментальные лисп-вызовы.

уже)))

1 минуту назад, EdwardSt сказал:

А для него создай универсальный стартер на NET (или подобном), натравленный на подходящее событие и вызывающий этот скрипт при наступлении оного

возможно у меня фобия но стараюсь без крайней нужды не подписываться(((

3 минуты назад, EdwardSt сказал:

Ты же сам в курсе, что ncad.lsp грузится только в начале сеанса

 

2 минуты назад, kpblc сказал:

Так в ACAD у тебя лисп грузится в пространство документа, а не приложения

угу(((

================

выше картинку дал... нане можно задать действиЕ при открытии документа... другой вопрос, что возможно это традиционно гвоздями прибито в коде(((

Link to comment
Share on other sites

Да ну, там в подписке на готовые события ничего криминального нет:)

добавлено через 3 минут
    public class ExtensionInitialize : IExtensionApplication
    {
        public void Initialize()
        {
            Application.DocumentManager.DocumentCreated += OnDocumentCreatedEvent;
        }

        public void Terminate()
        {
            Application.DocumentManager.DocumentCreated -= OnDocumentCreatedEvent;
        }
        
        private void OnDocumentCreatedEvent(object senderObj, DocumentCollectionEventArgs docColDocActEvtArgs)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            if (doc != null)
            {
                doc.Editor.WriteMessage("\nBingo!!");
            }
        }
    }
}

Как-то так примерно

  • Like 2
Link to comment
Share on other sites

14 минут назад, kpblc сказал:

Как-то так примерно

только нужно удостовериться, что это событие наступает ПОСЛЕ открытия файла.

Возможно, сначала документ создается, а потом в него загружается что-то из файла.

Link to comment
Share on other sites

Да я вроде бы проверяю документ на null. А последовательность загрузки - та еще загадка. Чисто теоретически можно добавить вызов обработчика хоть из Initialize, кто мешает ;)

Link to comment
Share on other sites

17 минут назад, kpblc сказал:

Да я вроде бы проверяю документ на null.

Я немного про другое. Примерный алгоритм при открытии файла: "создание документа" (инициализация переменных, выделение памяти, создание БД рисунка и т.п.) - "открытие файла" (заполнение БД рисунка, считывание и переназначение некоторых переменных и т.д.).

Не исключено, что "OnDocumentCreatedEvent" наступает после создания, но до открытия файла.

И документ при этом уже может быть не null.

Необходимо проверять.

Link to comment
Share on other sites

Абсолютно согласен - лично я пока не знаю последовательности срабатывания событий, и тупо не до исследований: у меня с какого-то перепугу перестала срабатывать публикация dll.

Link to comment
Share on other sites

Posted (edited)
1 час назад, kpblc сказал:

Слегка заморочился

Блин всего лишь спросил как лиспом сделать))

Всежэж надеюсь, что ктонить из разработчиков принесет серебрянную пулю, ну или гильзу от нее..  латунную))

====

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

добавлено через 3 минут

Ну и если попытаться выполнить лисп без документа ... нана сложится, хотя вроде поправили

добавлено через 7 минут

Тут в порядке бреда подумал...

Если open переопределить..

Лиспом..

Т.е. после открытия еще ченить, чтоб нана сделал

upd фигня какая то получается, в ком строке имя файла просит(((

Edited by doctorraz
Link to comment
Share on other sites

42 минуты назад, doctorraz сказал:

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

Ни фига! Во-первых, ObjectDBX никуда не девается (по крайней мере в ACAD; в нане не проверял). Во-вторых, в нанокаде можно попробовать сделать фишку:

(command "_.rectangle" pause pause)
(command "_.open" file_name)
(command "_.circle" pause pause)

Вопрос на миллион: где будет выполнено построение окружности? В первом файле или в file_name? Я подозреваю, что именно во втором.

В ту же степь: в каком-то из кодов ты определяешь глобальную переменную (setq *adoc* (vla-get-activedocument (vlax-get-acad-object))). В ACAD эта переменная в каждом документе будет своя. В нане - необязательно.

50 минут назад, doctorraz сказал:

Если open переопределить..

Лиспом..

Не уверен что это хорошая идея. Команду undefine нанокад23 не знает. А если бы и знал, то, возможно, пришлось бы переопределять не только open, но и "открыть", и new, и "новый": https://autolisp.ru/2014/06/27/command-redefine/ Пупок развяжется все это прописывать. NET ИМХО более удобен будет.

47 минут назад, doctorraz сказал:

Всежэж надеюсь, что ктонить из разработчиков принесет серебрянную пулю, ну или гильзу от нее..  латунную))

Ну берешь аналог моего кода, определяешь там в любом месте нечто типа public void AutorunLispEveryDoc(), внутри которого через тот же SendStringToExecute вызываешь свой лисп. И внедряешь в инициализатор расширения и в событие DocumentCreated, делов-то :)

С другой стороны, если у тебя только назначение системных переменных - то и лисп особо не нужен будет ИМХО.

Link to comment
Share on other sites

image.thumb.png.59fdc6e80861c6df6ec73089a864bcc9.pngпоходу наносайт меня в спамеры записал)))

  • Haha 2
Link to comment
Share on other sites

Прикол... Ща и меня туды жа засунут :)

>> Естественно во втором

А каде ни фига не естественно. Выполнение лиспа просто прекратится при смене активного документа.

--

Я про то, что отловить лиспом момент смены активного документа невозможно. На NET это, как ты убедился - делается просто на раз.

Спойлер

Если честно, я от лиспа уже устал слеганца. NET, конечно, тоже преподносит сюрпризы, но там хоть информации кратно больше ))

 

Link to comment
Share on other sites

13 минут назад, kpblc сказал:

Выполнение лиспа просто прекратится при смене активного документа

И это естественно, в АК лисп живет в документе, в нано живет в приложении)))

14 минут назад, kpblc сказал:

но там хоть информации кратно больше ))

Эт точно, я слегка офигел, когда начал с шарпом разбираться.. от возможностей и изобилия примеров...

Ту же сортировку  с группировкой на  vba, извращался как...

А в net  linq  в четыре строчки..

Скорость вообще бомба, особенно если не открывать в редакторе... пол сотни файлов за пару сек, все нужное вытащил... перебором по примитивам базы чертежа!!!

добавлено через 7 минут
23 минуты назад, kpblc сказал:

Я про то, что отловить лиспом момент смены активного документа невозможно

А мне не надо смену отлавливать, мне надо открытие.. и нана это умеет делать для обновитьобъекты например..

На самом деле не мне, а коллегам... уже задолбался отключать этот красный конус... кнопку сделаю

Link to comment
Share on other sites

Немного покопался в проблеме.

 

17 часов назад, kpblc сказал:

Я про то, что отловить лиспом момент смены активного документа невозможно.

Оказалось, это не совсем так.

В 22.05.2023 в 14:31, kpblc сказал:

А реакторов в NC, насколько я помню, нет в классическом виде.

Есть, но не все такие же, как в АС. Да и работает не очень-то понятно. Кстати, в АС реакторы - тоже зубодробительная тема.

 

В 22.05.2023 в 12:17, doctorraz сказал:

Подскажите пожалуйста, куда прописать lisp, чтобы он выполнялся при открытии каждого файла чертежа?

 

Предлагаю на рассмотрение фрагмент с использованием реактора

(vl-load-com)

;Функция создания блока безкомандным способом
(defun b_piket ( / h)
  (setq h 1.25)
  (entmakex '((0 . "BLOCK") (2 . "piket") (70 . 2) (10 0.0 0.0 0.0))) 
  (entmakex (list '(0 . "LINE") '(8 . "0") '(6 . "ByBlock") '(62 . 0) (list 10 0.0 (* h -0.5) 0.0) (list 11 0.0 (* h 0.5) 0.0)))
  (entmakex (list '(0 . "ATTDEF") '(8 . "0") '(62 . 0) (cons 40 h) '(1 . "") '(7 . "Standard") (list 10 0.0 0.0 0.0) '(3 . "Пикет") '(2 . "PICKET") '(70 . 8) '(280 . 0)))
  (entmakex '((0 . "ENDBLK")))
  )

 
;Тело реактора
(defun test-msg (reactor-object parameter-list / doc)
;  Эта часть почему-то выполняется несколько раз
  (setq doc (car parameter-list)) ; загруженный/созданный документ
  (vlax-dump-object doc ) ;вывод параметров документа
  (setvar "AUNITS" 1) ;попытка изменения переменной
  (if (not (tblsearch "Block" "piket")) 
    (progn 
      ;  Эта часть вызывается только 1 раз, т.к. проверка определения блока
      ;  Можно заменить  на другое уникальное условие.
      ; например, проверку переменной, которую хотим поменять в автозапуске
      (b_piket)
    ))
  (prin1)
  )

;натравливаем ректор на событие 
(setq MyReactor (vlr-docmanager-reactor nil 
    '((:vlr-documentCreated . test-msg))))
(prin1)

 

При открытии чертежа/создании нового чертежа выпадает список с параметрами VLA-документа, изменяется значение системной переменной и создается новое определение блока, если его не было.

 

Не смог разобраться, почему событие documentCreated возникает несколько раз при загрузке/создании файла. :stena:

Спойлер

image.png.432bde31661fcfbcd82a7f4b80584f28.png

Кривизна рук - это понятно. Непонятно, моих (вероятно) или разработчиков (а почему бы и нет!).

 

UPD. Требует проверки версия, что функции (command в реакторе не работают. Или работают криво.

Edited by EdwardSt
  • Like 1
Link to comment
Share on other sites

Вообще-то команды там работать не должны. А про docmanager-реакторы я как-то не подумал, каюсь. Привык к командным и реакторам на системные переменные...

Link to comment
Share on other sites

Вроде удалось купировать проблему с повторным вызовом реактора с помощью использования глобальной переменной

Спойлер
(vl-load-com)


;Тело реактора
(defun autorun_rector (reactor-object parameter-list / doc i)
  (setq doc (car parameter-list)) ; загруженный/созданный документ
  (if (not (member doc GLOBAL_DOCS)) ;Документ еще не обрабатывался после открытия
    (progn ;Обработка автозапуска файла
      (vlax-dump-object doc) ;вывод параметров документа
      (setvar "AUNITS" 1) ;попытка изменения переменной
      ;...
      ;другие допустимые в реакторе команды
      ;...
    ))
  ;Сохранение в глобальную переменную GLOBAL_DOCS 
  ;списка открытых (= 1 раз обработанных документов)
  ;для предотвращения повторной обработки
  (setq GLOBAL_DOCS nil i 0)
  (setq docs (vla-get-documents (vlax-get-acad-object)))  
  (repeat (vla-get-count docs)
    (setq GLOBAL_DOCS (cons (vla-get-item docs i) GLOBAL_DOCS))
    (setq i (1+ i)))    
  (prin1)
  )

;натравливаем реактор на событие 
(setq GLOBAL_DOCS nil MyReactor (vlr-docmanager-reactor nil 
    '((:vlr-documentCreated . autorun_rector))))
(prin1)

 

 

В секции progn можно вставлять собственные функции.

По сообщению @kpblc функции (command ... тут работать не будут.

Функции (printX... - , похоже, тоже.

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...
В 23.05.2023 в 17:51, EdwardSt сказал:

Вроде удалось купировать проблему с повторным вызовом реактора с помощью использования глобальной переменной

  Нужно вставить в автозагрузку (Скрыть контент)

(vl-load-com) ;Тело реактора (defun autorun_rector (reactor-object parameter-list / doc i) (setq doc (car parameter-list)) ; загруженный/созданный документ (if (not (member doc GLOBAL_DOCS)) ;Документ еще не обрабатывался после открытия (progn ;Обработка автозапуска файла (vlax-dump-object doc) ;вывод параметров документа (setvar "AUNITS" 1) ;попытка изменения переменной ;... ;другие допустимые в реакторе команды ;... )) ;Сохранение в глобальную переменную GLOBAL_DOCS ;списка открытых (= 1 раз обработанных документов) ;для предотвращения повторной обработки (setq GLOBAL_DOCS nil i 0) (setq docs (vla-get-documents (vlax-get-acad-object))) (repeat (vla-get-count docs) (setq GLOBAL_DOCS (cons (vla-get-item docs i) GLOBAL_DOCS)) (setq i (1+ i))) (prin1) ) ;натравливаем реактор на событие (setq GLOBAL_DOCS nil MyReactor (vlr-docmanager-reactor nil '((:vlr-documentCreated . autorun_rector)))) (prin1)

(vl-load-com)


;Тело реактора
(defun autorun_rector (reactor-object parameter-list / doc i)
  (setq doc (car parameter-list)) ; загруженный/созданный документ
  (if (not (member doc GLOBAL_DOCS)) ;Документ еще не обрабатывался после открытия
    (progn ;Обработка автозапуска файла
      (vlax-dump-object doc) ;вывод параметров документа
      (setvar "AUNITS" 1) ;попытка изменения переменной
      ;...
      ;другие допустимые в реакторе команды
      ;...
    ))
  ;Сохранение в глобальную переменную GLOBAL_DOCS 
  ;списка открытых (= 1 раз обработанных документов)
  ;для предотвращения повторной обработки
  (setq GLOBAL_DOCS nil i 0)
  (setq docs (vla-get-documents (vlax-get-acad-object)))  
  (repeat (vla-get-count docs)
    (setq GLOBAL_DOCS (cons (vla-get-item docs i) GLOBAL_DOCS))
    (setq i (1+ i)))    
  (prin1)
  )

;натравливаем реактор на событие 
(setq GLOBAL_DOCS nil MyReactor (vlr-docmanager-reactor nil 
    '((:vlr-documentCreated . autorun_rector))))
(prin1)

 

 

В секции progn можно вставлять собственные функции.

По сообщению @kpblc функции (command ... тут работать не будут.

Функции (printX... - , похоже, тоже.

А кто нибудь пробовал управлять - редактировать значения полученые по средствам 

(defun C:GetElement_XV ()
  (setq element (vlax-ename->vla-object (car (entsel "\nВыберите элемент: "))))
  (print (vlax-dump-object element T))

Наверно не совсем по теме, но увидел знакомые строчки 

Edited by Tod_2x2
Link to comment
Share on other sites

Ну да, совсем не по теме. И да, управлять можно.

добавлено через 0 минут

Кроме тех свойств, которые ReadOnly

  • Haha 1
Link to comment
Share on other sites

По-моему, механизм реакторов в лиспе и является контейнером для обработки событий COM (да и событий, как таковых, вообще).

Количество типов реакторов в нанокаде - 2 (в АС -6).

В данном случае удалось подобрать подходящий тип, а также добиться работоспособности.

Пока косяков не выявлено, можно считать предложенное решение вполне себе рабочим.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Tell a friend

    Love Официальный форум компании Нанософт Разработка? Tell a friend!
×
×
  • Create New...