Aller au contenu

Liaison Lisp / C#


Messages recommandés

Coucou

 

Je pourrais carrément poser ma question à (gile) en privé mais je me dis qu'il existe toujours une possibilité que quelqu'un d'autre réponde et surtout si quelqu'un se pose la même question elle sera résolue (ou pas) à la vue de toutes et tous.

 

Question : est-il possible d'utiliser la puissance (et la facilité) de C# pour créer des boîtes de dialogue dont les valeurs seront injectées dans un lisp et inversement?

Car je galère tellement avec ce langage DCL qui n'est pas interactif aux évènements du lisp que j'aimerais explorer cette piste de recherche.

 

Merci d'avance à toutes celles et à tous ceux qui ont cette connaissance pour me (nous) dépatouiller.

 

Amicalement

 

Lien vers le commentaire
Partager sur d’autres sites

Salut Didier,

 

Oui c'est tout à fait possible. C'est une technique que j'utilise parfois lorsque j'ai une "grosse" fonction déjà développée en lisp et que je veux faire une case de dialogue pour faire saisir les paramètres.

Le seul souci, c'est que dans ta case de dialogue, souvent il faudra afficher les calques ou les blocs, choisir une couleur ou choisir un objet à l'écran, donc il faudra quand même une "petite" partie de dev en C# à l'intérieur de ton dialogue.

Par contre c'est à la fermeture du dialogue que tu lances ta fonction lisp, donc pas d'aller retour entre Lisp et C#.

C'est un aller simple sans retour possible!!

 

Olivier

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Tu peux utiliser l'attribut LispFunction pour créer une fonction LISP en .NET (comme on crée une commande avec CommandMethod).

La méthode qui définit la fonction LISP ne prend qu'un argument de type ResultBuffer (une collection de TypedValue représentant les arguments de la fonction LISP) et peut renvoyer tout type de donnée compatible avec AutoLISP (CF l'énumération LispDataType utilisable pour les instances de TypedValue dans un Resultbuffer).

Comme le dit Olivier, il faudra coder en C# la récupération des arguments (le ResultBuffer), le comportement de la boite de dialogue et la valeur de retour.

Un peu plus d'explications et un exemple ici.

 

Personnellement, j'ai bien sûr essayé des liaisons AutoLISP / .NET et même si c'est dans ce sens là que ça fonctionne le mieux (le moins mal plutôt), j'ai assez vite renoncé. Quand on commence à coder du .NET pour AutoLISP on s'aperçoit assez vite qu'il est plus simple de tout coder en .NET que de faire interagir les deux.

Mais si tu veux tenter le coup, je peux essayer de te guider

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Coucou

 

Un grand Merci à vous deux pour ces réponses aussi rapides qu'explicites

 

Franchement en posant la question je ne pensais pas à une réelle possibilité de ce que je demandais...

Je note ce qu'écrit (gile) comme quoi il vaut mieux éviter de mélanger les serviettes et les torchons, sans manque de respect à ces deux outils, serviettes et torchons ou lisp et C# (hihi) je vais me ménager du temps pour mieux apprendre et ne pas trop en perdre avec le DCL quelque peu obsolète.

 

Ma fainéantise m'a fait poser la question car j'ai de beaux exemples de lisp hyper-fonctionnels pour mes besoins personnels mais qui nécessitent des cases de dialogue si je veux les partager en particulier sur mon site et je pensais dans un coin perdu de ma tête qu'une poudre de perlimpinpin m'aurait peut-être évité de tout ré-écrire, tant pis pour la fainéantise...

 

Je vais tenter d'écrire ces fonctionnalités en C#... (il faut que je vérifie mon stock d'aspirine en stock)

 

Amicalement

Lien vers le commentaire
Partager sur d’autres sites

Un exemple avec une boite de dialogue toute simple pour récupérer une entrée utilisateur.

Le formulaire windows (Dialog) contient :


     
  • un Label (lblMessage) pour le message d'invite à afficher
  • un TextBox (tbxResult) pour l'entrée utilisateur et, éventuellement une valeur par défaut
  • un Button (btnOk) pour valider l'entrée
  • un Button (btnCancel) pour annuler

 

http://gilecad.azurewebsites.net/DotNet/inputbox.png

 

Le code la boite de dialogue :

using System.Windows.Forms;

namespace InputBoxLispFunction
{
   public partial class Dialog : Form
   {
       /// <summary>
       /// Crée une nouvelle instance de dialog
       /// </summary>
       /// <param name="title">Titre de la boite de dialogue</param>
       /// <param name="message">Message d'invite</param>
       /// <param name="value">Valeur par défaut</param>
       public Dialog(string title, string message, string value)
       {
           InitializeComponent();
           Text = title;
           lblMessage.Text = message;
           tbxResult.Text = value;
           btnOk.DialogResult = DialogResult.OK;
           btnCancel.DialogResult = DialogResult.Cancel;
       }

       /// <summary>
       /// Obtient le contenu du TextBox
       /// </summary>
       public string StringResult => tbxResult.Text;
   }
}

 

Le code de la fonction LISP :

using System.Windows.Forms;

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;

using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace InputBoxLispFunction
{
   public class LispFunction
   {
       /// <summary>
       /// Fonction LISP pour ouvrir une boite de dialogue pour récupérer une entrée utilisteur
       /// (InputBox titre message [defaut])
       /// </summary>
       /// <param name="resbuf">Arguments passé à la fonction : 2 ou 3 chaînes de caractèrers</param>
       /// <returns>La chaîne entée par l'utilisateur dans la boite de dialogue ou nil</returns>
       [LispFunction("InputBox")]
       public static string InputBox(ResultBuffer resbuf)
       {
           var ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
           try
           {
               // contrôle des arguments
               if (resbuf == null)                                         // aucun argument
                   throw new TooFewArgsException();

               var args = resbuf.AsArray();
               if (args.Length < 2)                                        // moins de 2 arguments
                   throw new TooFewArgsException();

               if (args.Length > 3)                                        // plus de 3 arguments
                   throw new TooManyArgsException();

               if (args[0].TypeCode != (int)LispDataType.Text)             // le premier argument n'est pas une chaîne
                   throw new ArgumentTypeException("stringp", args[0]);
               string title = (string)args[0].Value;

               if (args[1].TypeCode != (int)LispDataType.Text)             // le deuxième argument n'est pas une chaîne
                   throw new ArgumentTypeException("stringp", args[1]);
               string message = (string)args[1].Value;

               string value = "";
               if (args.Length == 3)                                       // le troisième argument (optionnel) est spécifié
               {
                   if (args[2].TypeCode != (int)LispDataType.Text)         // le troisième argument n'est pas une chaîne
                       throw new ArgumentTypeException("stringp", args[2]);
                   else
                       value = (string)args[2].Value;
               }

               // ouverture de la boite de dialogue
               using (var dialog = new Dialog(title, message, value))
               {
                   var result = AcAp.ShowModalDialog(dialog);              // afficher la boite de dialogue
                   if (result == DialogResult.OK)
                       return dialog.StringResult;                         // l'utilisateur a cliqué OK
                   else
                       return null;                                        // l'utilisateur a cliqué Annuler
               }
           }
           catch (System.Exception ex)
           {
               ed.WriteMessage("\nErreur: " + ex.Message + "\n");
               return null;
           }
       }
   }
}

 

Le code des classes définissant les exceptions LISP (nombre et type des arguments) :

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;

namespace InputBoxLispFunction
{
   /// <summary>
   /// Classe de base pour les exceptions LISP
   /// </summary>
   public class LispException : System.Exception
   {
       public LispException(string msg) : base(msg) { }
   }

   public class TooFewArgsException : LispException
   {
       /// <summary>
       /// Exception LISP "Nombre d'arguments insuffisant"
       /// </summary>
       public TooFewArgsException() : base("Nombre d'arguments insuffisant") { }
   }

   public class TooManyArgsException : LispException
   {
       /// <summary>
       /// Exception LISP "Nombre d'arguments trop important"
       /// </summary>
       public TooManyArgsException() : base("Nombre d'arguments trop important") { }
   }

   public class ArgumentTypeException : LispException
   {
       /// <summary>
       /// Exception LISP "Type d'argument incorrect"
       /// </summary>
       /// <param name="s">Type attendu (fixnump, numberp, listp, consp, stringp, lentityp, lselsetp)</param>
       /// <param name="tv">Valeur de l'argument</param>
       public ArgumentTypeException(string s, TypedValue tv)
           : base(string.Format(
           "Type d'argument incorrect: {0} {1}",
           s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value))
       { }
   }
}

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

salut,

pour ceux qui comme moi développent avec le langage VB,

il y a ce sujet de 2012,

déjà largement inspiré par les conseils de Gille.

sujet sur les liaison lisp/vb.net

finalement, j'ai très peu utilisé cette technique, en lisp je remplace les cases de dialogue au maximum par des choix ligne de commande, et lorsque le dialogue s'impose, je fais des DCL ultra minimaliste.

a+

gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité