Однотипные строки в цикл

Автор Тема: Однотипные строки в цикл  (Прочитано 15003 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #30 : 23-10-2019, 13:58:44 »
Причина, видимо, была где-то внутри того, что скрывается под "//тут инициализовал окно". Из лисп-функции нормально запускаются модальные диалоги.
Может быть. Тогда попробую реализовать окно через функции лиспа, когда буду переписывать окно для создания клемного ряда.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #31 : 23-10-2019, 14:35:28 »
Я думал о таком подходе, чтобы написать функцию лиспа на .net. Но когда вызываешь модальное окно с помощью функции лиспа, то AutoACD крашится.
То есть я делал конструкцию типа:
Код - vb.net [Выбрать]
  1. <LispFunction("Window")>
  2. //тут инициализовал окно
и AutoCAD вылетал.
Причина, видимо, была где-то внутри того, что скрывается под "//тут инициализовал окно". Из лисп-функции нормально запускаются модальные диалоги.
100% проблема в самой форме (создание, запуск, события кнопок...)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #32 : 23-10-2019, 14:38:05 »
Небольшая демонстрация того, как это работает.

Лисп:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.   data "Привет, .NET!"
  3.   res (run-custom-dialog data))
  4. (if res (setq data res))
  5. (alert data)
.NET:
Код - C# [Выбрать]
  1. [LispFunction("run-custom-dialog")]
  2. public string RunDia(ResultBuffer rb)
  3. {
  4.     string data = rb?
  5.         .AsArray()
  6.         .FirstOrDefault()
  7.         .Value.ToString()
  8.         ?? "*error*";
  9.  
  10.     CustomDialog customDialog = new CustomDialog();
  11.     customDialog.Data = data;
  12.     var res = Application.ShowModalDialog(customDialog);
  13.     if (res != System.Windows.Forms.DialogResult.Cancel)
  14.     {
  15.         return customDialog.Data;
  16.     }
  17.     else
  18.     {
  19.         return null;
  20.     }
  21. }
  22.  
Весь проект для VS2019 - в приложенном архиве.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #33 : 23-10-2019, 14:40:21 »
Дмитрий, спасибо

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #34 : 23-10-2019, 21:55:12 »
Небольшая демонстрация того, как это работает.

Лисп:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.   data "Привет, .NET!"
  3.   res (run-custom-dialog data))
  4. (if res (setq data res))
  5. (alert data)
.NET:
Код - C# [Выбрать]
  1. [LispFunction("run-custom-dialog")]
  2. public string RunDia(ResultBuffer rb)
  3. {
  4.     string data = rb?
  5.         .AsArray()
  6.         .FirstOrDefault()
  7.         .Value.ToString()
  8.         ?? "*error*";
  9.  
  10.     CustomDialog customDialog = new CustomDialog();
  11.     customDialog.Data = data;
  12.     var res = Application.ShowModalDialog(customDialog);
  13.     if (res != System.Windows.Forms.DialogResult.Cancel)
  14.     {
  15.         return customDialog.Data;
  16.     }
  17.     else
  18.     {
  19.         return null;
  20.     }
  21. }
  22.  
Весь проект для VS2019 - в приложенном архиве.

Дмитрий, изучил Ваш пример. Вы делаете на WinForm,а я делаю окна на WPF. Сейчас как не пытался, так и не вызывает окно. Исключения при отладке не возникает, AutoCAD не крашится, просто в логе AutoCAD выводится вот такое
Код - Auto/Visual Lisp [Выбрать]
  1. System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
  2.    at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
  3.    at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
  4.    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  5.    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  6.    at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
  7.    at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.InvokeLisp(); error: ADS request error

Сам код имеет вот такой вид

Код - vb.net [Выбрать]
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.ApplicationServices
  3. Imports Autodesk.AutoCAD.DatabaseServices
  4.  
  5. Public Class Initialization
  6.     <LispFunction("lmxWindowTest")>
  7.     Public Sub lmxDisplayFullName()
  8.         Dim WinTest As tWindow = New tWindow()
  9.         Application.ShowModalWindow(WinTest)
  10.     End Sub
  11. End Class

Отмечено как Решение Lemieux 23-10-2019, 22:49:43

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #35 : 23-10-2019, 22:20:49 »
Метод лисп-функции должен иметь входной параметр типа ResultBuffer, даже если лисп-функция не будет иметь аргументов. А у Вас пустые скобки, то есть, входных параметров нет.
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-3B2760FE-A0DC-4229-AEBE-5CC83290BA95-htm.html

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #36 : 23-10-2019, 22:54:34 »
Метод лисп-функции должен иметь входной параметр типа ResultBuffer, даже если лисп-функция не будет иметь аргументов. А у Вас пустые скобки, то есть, входных параметров нет.
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-3B2760FE-A0DC-4229-AEBE-5CC83290BA95-htm.html
ёмоё. Я изначально делал по примеру из хелпа по API и не работало, сюда я скопировал последний вариант пробы. Моя невнимательность.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #37 : 24-10-2019, 09:03:16 »
Ну зато теперь на всю жизнь запомните  8)

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #38 : 30-10-2019, 19:38:24 »
А кто-то может подсказать как тип Object преобразовать в TypedValue?

Я делаю вот так
Код - C# [Выбрать]
  1. object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2. TypedValue[] lxType = (TypedValue[])lxCollectionTB;

В лисп переменной у меня хранится список из строк. И при выполнении кода переменная "lxCollectionTB" хранит в себе "TypeValue[]".

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

Сразу напрашивается вопрос - зачем мне это?
По советам выше я пробовал сделать через "LispFunction", но пришёл к выводу, что мне удобнее хранить в переменной и вызывать окно через "CommandMethod".

PS Хочу поблагодарить за советы выше. Я попробовал все варианты и сократил код, с помощью словарей примерно в 2 раза.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #39 : 30-10-2019, 19:44:26 »
Lemieux,
Как я понимаю lxDocument.GetLispSymbol("lmxNameTerminals") возвращает ResultBuffer
Соответственно:
Код - C# [Выбрать]
  1.     object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2.     TypedValue[] lxType = lxCollectionTB.AsArray();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #40 : 30-10-2019, 19:47:14 »
Lemieux,
Как я понимаю lxDocument.GetLispSymbol("lmxNameTerminals") возвращает ResultBuffer
Соответственно:
Код - C# [Выбрать]
  1.     object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2.     TypedValue[] lxType = lxCollectionTB.AsArray();
Александр, в том-то и дело, что по хелпу он возвращает Object. С ResultBuffer было бы просто.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #41 : 30-10-2019, 19:48:32 »
Lemieux,
Сечас перепроверю.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #42 : 30-10-2019, 20:21:40 »
Да именно так и следует делать:
Код - C# [Выбрать]
  1. TypedValue[] lxType = (TypedValue[])lxCollectionTB;
Только желательно сначала проверить не равен ли случайно lxCollectionTB null (если такой переменной нет или она nil)


Впрочем возможен вариант, что в этой переменной не список и тогда преобразовывать в TypedValue[] нельзя.
Правильнее вот так:

Код - C# [Выбрать]
  1. [CommandMethod("GetLispVar")]
  2. public void GetLispVar()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.  
  7.   Editor ed = doc.Editor;
  8.   PromptResult rs =  ed.GetString("\nУкажите имя переменной: ");
  9.   if (rs.Status == PromptStatus.OK)
  10.   {
  11.     var o = doc.GetLispSymbol(rs.StringResult);
  12.     if (o != null && o is TypedValue[])
  13.     {
  14.       TypedValue[] tvs = o as TypedValue[];
  15.       foreach (TypedValue tv in tvs)
  16.       {
  17.         ed.WriteMessage($"\n{tv.TypeCode} - {tv.Value}");
  18.       }
  19.     } else
  20.     {
  21.       ed.WriteMessage($"\n{o}");
  22.     }
  23.   }
  24. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #43 : 30-10-2019, 20:37:55 »
Да именно так и следует делать:
Код - C# [Выбрать]
  1. TypedValue[] lxType = (TypedValue[])lxCollectionTB;
Только желательно сначала проверить не равен ли случайно lxCollectionTB null (если такой переменной нет или она nil)


Впрочем возможен вариант, что в этой переменной не список и тогда преобразовывать в TypedValue[] нельзя.
Правильнее вот так:

Код - C# [Выбрать]
  1. [CommandMethod("GetLispVar")]
  2. public void GetLispVar()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.  
  7.   Editor ed = doc.Editor;
  8.   PromptResult rs =  ed.GetString("\nУкажите имя переменной: ");
  9.   if (rs.Status == PromptStatus.OK)
  10.   {
  11.     var o = doc.GetLispSymbol(rs.StringResult);
  12.     if (o != null && o is TypedValue[])
  13.     {
  14.       TypedValue[] tvs = o as TypedValue[];
  15.       foreach (TypedValue tv in tvs)
  16.       {
  17.         ed.WriteMessage($"\n{tv.TypeCode} - {tv.Value}");
  18.       }
  19.     } else
  20.     {
  21.       ed.WriteMessage($"\n{o}");
  22.     }
  23.   }
  24. }

Меню смутило то, что я так, можно сказать в наглую, преобразовываю типы. А проверку я делаю следующим этапом, перед циклом для организации string массива. И там всегда будет список, так как никто к этой переменной не имеет доступа, а формируется она функцией написанной мной.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #44 : 30-10-2019, 20:43:39 »
Lemieux,
Кстати, ты обратил внимание что в этом списке есть не только строки, но и Autodesk.AutoCAD.Runtime.LispDataType.ListBegin и Autodesk.AutoCAD.Runtime.LispDataType.ListEnd (это как скобки в lisp)? У них TypeCode 5016 и 5017
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение