Автозапуск кода в каждом новом документе nanoCAD
На форуме nanocad возник вопрос: "А как запустить lsp внутри каждого документа?"
В ACAD-то все просто: код будет грузиться в каждый документ (как эта загрузка обеспечивается - вопрос отдельный). А если в коде добавить самовызов, то он и сработает нормально.
Но в nanoCAD такого счастья уже нет. Хотя бы потому, что коды - даже lsp - грузятся в приложение, а не в документ. Понятие реакторов* в nanoCAD 23 (ну, по крайней мере на момент написания статьи) не реализованы. Складываем это вместе - и получается, что код ни разу не в курсе, в каком документе он выполняется. И отследить момент перехода в другой документ шансов практически нет.
Уточнение: на лиспе. Если делать через NET, то все становится достаточно простым.
Много кода
Общая идея: подписаться на несколько событий:
- DocumentActivated
- DocumentCreateStarted
- DocumentBecameCurrent
- DocumentCreated
- DocumentDestroyed
И посмотреть, что получится в результате. Ну и за компанию – на событие начала и окончания команды:
- CommandWillStart
- CommandEnded
Чтобы особо не заморачиваться, результаты буду выводить в текстовый лог:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| internal static class LogService
{
public static void LogMessage (string DocumentName, [CallerMemberName ] string Message = null)
{
if (!Directory .Exists(Path .GetDirectoryName(_logFileName )))
{
Directory .CreateDirectory(Path .GetDirectoryName(_logFileName ));
}
try
{
using (StreamWriter writer = new StreamWriter (_logFileName, true, Encoding .UTF8))
{
writer .WriteLine(DateTime .Now.ToString("yyyy.MM.dd HH:mm:ss.fff")
+ (DocumentName == null ? "Без имени документа" : DocumentName )
+ "\t:\t"
+ (Message == null ? "Нет сообщения" : Message ));
}
}
catch (Exception ex )
{
MessageBox .Show(ex .ToString());
}
}
private static string _logFileName =
Path .Combine(Environment .GetEnvironmentVariable("appdata"), @"KpblcNCadEvents\KpblcNCadEvents.Log");
} |
Ну и сама подписка на события:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| public class ExtensionApplication : IExtensionApplication
{
public void Initialize()
{
Application.DocumentManager.DocumentActivated += OnDocumentActivated;
Application.DocumentManager.DocumentCreateStarted += OnDocumentStarted;
Application.DocumentManager.DocumentBecameCurrent += OnDocumentBecameCurrent;
Application.DocumentManager.DocumentCreated += OnDocumentCreated;
Application.DocumentManager.DocumentDestroyed += OnDocumentDestroyed;
Application.DocumentManager.CurrentDocument.CommandWillStart += OnCommandStart;
Application.DocumentManager.CurrentDocument.CommandEnded += OnCommandEnd;
}
private void OnCommandEnd(object sender, CommandEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnCommandStart(object sender, CommandEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentDestroyed(object sender, DocumentDestroyedEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentCreated(object sender, DocumentCollectionEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentBecameCurrent(object sender, DocumentCollectionEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentStarted(object sender, DocumentCollectionEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentActivationChanged(object sender, DocumentActivationChangedEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
private void OnDocumentActivated(object sender, DocumentCollectionEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
LogService.LogMessage(doc == null ? null : doc.Name);
}
public void Terminate() { }
} |
Заодно создаю ярлык вызова nanoCAD с принудительной загрузкой скомпилированной сборки:
1
| "C:\Program Files\Nanosoft\nanoCAD x64 23.0\nCad.exe" -g "C:\Users\kpblc\Source\Repos\KpblcNCadEvents\KpblcNCadEvents\bin\Debug\net6.0-windows\KpblcNCadEvents.dll" |
При старте nanoCAD в логе получаю:
1 2 3 4 5 6 7
| 2023.05.22 20:21:23.828Без имени0 : OnCommandEnd
2023.05.22 20:21:23.833Без имени0 : OnCommandStart
2023.05.22 20:21:23.842Без имени0 : OnCommandEnd
2023.05.22 20:21:23.981Без имени0 : OnCommandStart
2023.05.22 20:21:29.730Без имени0 : OnCommandEnd
2023.05.22 20:21:29.818Без имени0 : OnCommandStart
2023.05.22 20:21:29.820Без имени0 : OnCommandEnd |
Полагаю, что сначала создается документ, потом обрабатываются ключи вызова, а потом уже стандартные команды типа _new, _toolpalettes etc.
Жму Ctrl+N:
1 2 3 4 5 6
| 2023.05.22 20:23:58.732Без имени0 : OnCommandStart
2023.05.22 20:23:58.812Без имени0 : OnDocumentStarted
2023.05.22 20:23:59.403Без имени1 : OnDocumentCreated
2023.05.22 20:23:59.515Без имени1 : OnDocumentActivated
2023.05.22 20:23:59.517Без имени1 : OnDocumentBecameCurrent
2023.05.22 20:23:59.658Без имени1 : OnCommandEnd |
Получается, что команда начинается в одном документе, а заканчивается в другом Прикол аднака
Но вот тут уже срабатывают привязки к событиям документов.
Получается, что если надо выполнять какой-то код в каждом документе при открытии этого документа, то этот код надо вызывать и в инициализаторе аддона, и в событиях обработки документов.
Если я ошибаюсь - милости прошу, поправляйте
P.S. Исходный код, ориентированный на nanoCAD23, болтается на гитхабе.
---
* имеются в виду командные реакторы
Похожее