CADxp: Liaison Lisp / C# - CADxp

Aller au contenu

Page 1 sur 1
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

Liaison Lisp / C#

#1 L'utilisateur est hors-ligne   didier 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 8260
  • Inscrit(e) : 18-décembre 02
  • LocationPlanète : Terre

Posté 15 juin 2019 - 17:33

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?
C
ar 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

Éternel débutant ...
Programmer AutoCAD
0

#2 L'utilisateur est hors-ligne   Olivier Eckmann 

  • ceinture noire 2em dan
  • Groupe : Membres
  • Messages : 1235
  • Inscrit(e) : 29-décembre 11
  • LocationLongjumeau (91)

Posté 15 juin 2019 - 20:43

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
0

#3 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11222
  • Inscrit(e) : 02-septembre 05

Posté 15 juin 2019 - 23:41

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
Image IPB
0

#4 L'utilisateur est hors-ligne   didier 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 8260
  • Inscrit(e) : 18-décembre 02
  • LocationPlanète : Terre

Posté 16 juin 2019 - 13:32

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...
J
e 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

Éternel débutant ...
Programmer AutoCAD
0

#5 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11222
  • Inscrit(e) : 02-septembre 05

Posté 16 juin 2019 - 16:47

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


Image IPB

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
Image IPB
0

#6 L'utilisateur est hors-ligne   GEGEMATIC 

  • ceinture noire 1er dan
  • Groupe : Membres
  • Messages : 857
  • Inscrit(e) : 04-novembre 05

Posté 17 juin 2019 - 09:49

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é
---------------------------------------------------------------------- PowerClic sur http://www.g-eaux.com
0

Partager ce sujet :


Page 1 sur 1
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

1 utilisateur(s) en train de lire ce sujet
0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)