-
Compteur de contenus
12 247 -
Inscription
-
Dernière visite
-
Jours gagnés
209
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par (gile)
-
Désactiver les accrochages 2 (le retour)
(gile) a répondu à un(e) sujet de (gile) dans ObjectARX/DBX, C++, .NET, RealDWG
Salut, Tu ne devrais pas voir besoin de débloquer le XML (c'est juste un fichier texte). Par contre, il est possible que tu doives le faire pour la DLL. -
Salut, Il y a 3 façons d'accéder aux propriétés d'un objet en LISP : - les données DXF, c'est la méthode "classique" avec la fonction entget comme l'a montré didier. - les propriétés COM/ActiveX, avec les fonctions vla-. On liste les propriétés avec la fonction vlax-dump-object : (vl-load-com) (setq doc (vla-get-ActiveDocument (vlax-get-acad-object))) (setq layers (vla-get-Layers doc)) (vlax-dump-Object (vla-Item layers "0")) - les propriétés ObjectARX exposées aux fonctions getpropertyvalue et setpropertyvalue qu'on peut lister avec la fonction dumpallproperties : (dumpallproperties (tblobjname "layer" "0"))
-
J'aurais dit : Ami 6. Et ce n'est pas celle que je regrette le plus de ne plus voir dans les rues (Citroën était capable du meilleur comme du pire).
-
TROUVER DANS UN BLOC DIRECTEMENT L'ATTRIBUT
(gile) a répondu à un(e) sujet de PHILPHIL dans Pour aller plus loin en LISP
Petite précision, ces fonctions ne sont pas liées à ActiveX. Au contraire, elles ont été développées pour les versions MAC comme une alternative à ActiveX (qui est spécifique à Windows). Pour le "EffectiveName", tu peux aussi les utiliser : (getpropertyvalue (getpropertyvalue (entlast) "BlockTableRecord") "Name") Qui peut s'écrire plus implement pour les dernières versions : (getpropertyvalue (entlast) "BlockTableRecord/Name") -
TROUVER DANS UN BLOC DIRECTEMENT L'ATTRIBUT
(gile) a répondu à un(e) sujet de PHILPHIL dans Pour aller plus loin en LISP
Salut, Tu fais : (setq bloc (car (entsel))) et tu sélectionnes ton bloc, puis tu fais : (dumpallproperties bloc) et tu ouvres la fenêtre de texte (F2). Tu devrais trouver des propriétés nommées "AcDbDynBlockPropertyXXX" qui correspondent à chacune des propriétés dynamiques de ton bloc ainsi que des propriétés correspondant aux étiquettes des attributs ("REF"). Tu peux lire les valeurs de ces propriétés avec getpropertyvalue et modifier leurs valeurs avec setpropertyvalue (setpropertyvalue bloc "AcDbDynBlockPropertyLONGUEUR BAS" 50.0) (setpropertyvalue bloc "REF" "toto") Ces fonctions qui permettent d'accéder "directement" à une valeur d'attribut ou de propriété dynamique en LISP font très probablement le 'foreach' dans leur implémentation (mais e C, c'est peut-être un peu plus rapide). -
SVP Routine : Bloc (NON Annotatif) --> Bloc Annotatif
(gile) a répondu à un(e) sujet de lecrabe dans Routines LISP
Cette version ajoute l'échelle courante à toutes les références des définitions de bloc modifiées. (defun c:setannot (/ ss2bnames annotativeblock massoc getreferences ss pos) (defun ss2bnames (ss / i lst) (repeat (setq i (sslength ss)) (setq name (cdr (assoc 2 (entget (ssname ss (setq i (1- i))))))) (if (null (member name lst)) (setq lst (cons name lst)) ) ) lst ) (defun annotativeblock (blk pos) (and (setq blk (tblobjname "block" blk)) (progn (regapp "AcadAnnotative") (and pos (regapp "AcadAnnoPO")) (entmod (append (entget (cdr (assoc 330 (entget blk)))) (list (append '(-3) '(("AcadAnnotative" (1000 . "AnnotativeData") (1002 . "{") (1070 . 1) (1070 . 1) (1002 . "}") ) ) (if pos '(("AcadAnnoPO" (1070 . 1))) ) ) ) ) ) ) ) ) (defun massoc (key alst) (if (setq alst (member (assoc key alst) alst)) (cons (cdar alst) (massoc key (cdr alst))) ) ) (defun getreferences (bname / blk refs elst) (if (and (setq blk (tblobjname "BLOCK" bname)) (setq refs (vl-remove-if-not 'cdr (mapcar (function (lambda (x) (if (setq elst (entget x)) (cons x (entget (cdr (assoc 330 elst)))) ) ) ) (massoc 331 (entget (cdr (assoc 330 (entget blk))))) ) ) ) ) (mapcar 'car refs) ) ) (if (setq ss (ssget '((0 . "INSERT") (2 . "~`*U*")))) (progn (initget "Oui Non") (setq pos (= "Oui" (getkword "\nFaire correspondre l'orientation du bloc a la presentation [Oui/Non] <N>: " ) ) ) (foreach bname (ss2bnames ss) (annotativeblock bname pos) (foreach br (getreferences bname) (command-s "AIOBJECTSCALEADD" br "" "") ) ) ) ) (princ) ) -
SVP Routine : Bloc (NON Annotatif) --> Bloc Annotatif
(gile) a répondu à un(e) sujet de lecrabe dans Routines LISP
Salut, pas vraiment testé. (defun c:setannot (/ ss2bnames annotativeblock ss pos) (defun ss2bnames (ss / i lst) (repeat (setq i (sslength ss)) (setq name (cdr (assoc 2 (entget (ssname ss (setq i (1- i))))))) (if (null (member name lst)) (setq lst (cons name lst)) ) ) lst ) (defun annotativeblock (blk pos) (and (setq blk (tblobjname "block" blk)) (progn (regapp "AcadAnnotative") (and pos (regapp "AcadAnnoPO")) (entmod (append (entget (cdr (assoc 330 (entget blk)))) (list (append '(-3) '(("AcadAnnotative" (1000 . "AnnotativeData") (1002 . "{") (1070 . 1) (1070 . 1) (1002 . "}") ) ) (if pos '(("AcadAnnoPO" (1070 . 1))) ) ) ) ) ) ) ) ) (if (setq ss (ssget '((0 . "INSERT") (2 . "~`*U*")))) (progn (initget "Oui Non") (setq pos (= "Oui" (getkword "\nFaire correspondre l'orientation du bloc a la presentation [Oui/Non] <N>: " ) ) ) (foreach b (ss2bnames ss) (annotativeblock b pos) ) ) ) (princ) ) -
Bravo, succès mérité ;)
-
Salut, Ça fonctionne bien chez moi sur A2020.
-
BOITE DE DIALOGUE SUR DEUX COLONNES
(gile) a répondu à un(e) sujet de PHILPHIL dans Pour aller plus loin en LISP
Oups!... J'avais oublie : "colonnes nommées". La fonction prend désormais 4 arguments : - le titre de la boite de dialogue - le nom de la première colonne - le nom de la seconde colonne - une liste de 20 paires pointées du type (message . valeur) (defun 20inputbox (box col1 col2 lst / temp file keys i dcl_id res) (setq temp (vl-filename-mktemp "Tmp.dcl") file (open temp "w") keys '("val1" "val2" "val3" "val4" "val5" "val6" "val7" "val8" "val9" "val10" "val11" "val12" "val13" "val14" "val15" "val16" "val17" "val18" "val19" "val20" ) ) (write-line (strcat "xInputBox:dialog{key=\"box\";initial_focus=\"val1\"; :row{ :column{label=\"" col1 "\";" ) file ) (setq i 0) (repeat 10 (write-line (strcat ":edit_box{label=" (vl-prin1-to-string (car (nth i lst))) ";key=\"val" (itoa (setq i (1+ i))) "\";edit_width=36;allow_accept=true;}spacer;" ) file ) ) (write-line (strcat "} :column{label=\"" col2 "\";" ) file ) (repeat 10 (write-line (strcat ":edit_box{label=" (vl-prin1-to-string (car (nth i lst))) ";key=\"val" (itoa (setq i (1+ i))) "\";edit_width=36;allow_accept=true;}spacer;" ) file ) ) (write-line "}} spacer; ok_cancel; }" file) (close file) (setq dcl_id (load_dialog temp)) (if (not (new_dialog "xInputBox" dcl_id)) (exit) ) (set_tile "box" box) (mapcar 'set_tile keys (mapcar 'cdr lst)) (action_tile "accept" "(setq res (mapcar 'cons (mapcar 'car lst) (mapcar 'get_tile keys))) (done_dialog)" ) (start_dialog) (unload_dialog dcl_id) (vl-file-delete temp) res ) -
BOITE DE DIALOGUE SUR DEUX COLONNES
(gile) a répondu à un(e) sujet de PHILPHIL dans Pour aller plus loin en LISP
Salut, Pour faire deux colonnes, il suffit de faire ne rangée (row) avec deux colonnes (column) Un exemple de fichiers dcl qui ferait un peu ce que tu veux : test : dialog { label = "Test"; : row { : column { :edit_box { label="Valeur 1"; key="val1"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 2"; key="val2"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 3"; key="val3"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 4"; key="val4"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 5"; key="val5"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 6"; key="val6"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 7"; key="val7"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 8"; key="val8"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 9"; key="val9"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 10"; key="val10"; edit_width=36; allow_accept=true; } spacer; } spacer; :column { :edit_box { label="Valeur 11"; key="val11"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 12"; key="val12"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 13"; key="val13"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 14"; key="val14"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 15"; key="val15"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 16"; key="val16"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 17"; key="val17"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 18"; key="val18"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 19"; key="val19"; edit_width=36; allow_accept=true; } spacer; :edit_box { label="Valeur 20"; key="val20"; edit_width=36; allow_accept=true; } spacer; } } spacer; ok_cancel; } Il suffit de transcrire ça pour écrire le fichier DCL "à la volée". Comme LISP est un langage de traitement de liste, il me semble qu'il serait plus judicieux d'utiliser des listes, ou mieux des listes d'associations pour les données en entrée et surtout pour la valeur de retour (ta routine ne renvoie que la valeur de l'évaluation de la dernière expression, soit : v20). Dans l'exemple suivant les arguments sont : - le titre de la boite de dialogue - une liste de 20 paires pointées du type (message . valeur) et la valeur de retour est une liste de même type. (defun 20inputbox (box lst / temp file keys i dcl_id res) (setq temp (vl-filename-mktemp "Tmp.dcl") file (open temp "w") keys '("val1" "val2" "val3" "val4" "val5" "val6" "val7" "val8" "val9" "val10" "val11" "val12" "val13" "val14" "val15" "val16" "val17" "val18" "val19" "val20" ) ) (write-line "xInputBox:dialog{key=\"box\";initial_focus=\"val1\"; :row{ :column{" file) (setq i 0) (repeat 10 (write-line (strcat ":edit_box{label=" (vl-prin1-to-string (car (nth i lst))) ";key=\"val" (itoa (setq i (1+ i))) "\";edit_width=36;allow_accept=true;}spacer;" ) file ) ) (write-line "} :column{" file) (repeat 10 (write-line (strcat ":edit_box{label=" (vl-prin1-to-string (car (nth i lst))) ";key=\"val" (itoa (setq i (1+ i))) "\";edit_width=36;allow_accept=true;}spacer;" ) file ) ) (write-line "}} spacer; ok_cancel; }" file) (close file) (setq dcl_id (load_dialog temp)) (if (not (new_dialog "xInputBox" dcl_id)) (exit) ) (set_tile "box" box) (mapcar 'set_tile keys (mapcar 'cdr lst)) (action_tile "accept" "(setq res (mapcar 'cons (mapcar 'car lst) (mapcar 'get_tile keys))) (done_dialog)" ) (start_dialog) (unload_dialog dcl_id) (vl-file-delete temp) res ) -
Salut, Fait un (vlax-dump-object table T) sur un tableau tu verras les méthodes : SetColumnWidth SetTextHeight etc.
-
Salut, Quand j'ai été confronté à ce genre de problème (par exemple pour trouver des intersections de lignes et de polylignes dans un programme de simulation de sortie de piste) j'ai dû déplacer tout le dessin vers l'origine pour dessiner les lignes et faire les calculs, puis tout replacer à la position initiale. Ces déplacements étaient quasi instantannés (mais ce n'était pas du LISP).
-
J'ai cherché sur le net principalement dans la documentation du VBA Excel : Application.Calculation XlCalculation énumération Après, je n'en sais pas beaucoup plus, la programmation Excel n'est vraiment pas mon fort, j'en fais quand j'y suis obligé mais j'essaye d'éviter.
-
Je n'ai pas testé mais ça devrait se passer là. Dans le fichier Lxl.lsp, dans la routine 'lancer_excel' ligne 481, on désactive le mode de calcul automatique : (defun lancer_excel(/ sel) (setq xl (vlax-get-or-create-object "Excel.Application")) (vlax-put xl 'Calculation -4135) ; xlCalculationManual (setq wks (vlax-get xl 'Workbooks)) (vlax-for sel wks (setq liste_fichiers_ouvert (append liste_fichiers_ouvert (list (strcase (vlax-get sel 'fullname))))) ) ) dans la routine 'fermer_excel' ligne 521, on réactive le mode calcul automatique : (defun fermer_excel(/ ok sel) (vlax-put xl 'Calculation -4105) ; xlCalculationAutomatic (if (not (member (strcase (vlax-get xls 'fullname)) liste_fichiers_ouvert)) (vlax-invoke-method xls 'close :vlax-false) ) (foreach sel (list xl wks xls classeur) (vlax-release-object sel) ) (setq xl nil wks nil xls nil classeur nil) (gc)(gc) )
-
DEBUGUAGE : Identifier et Lister les variables d'une routine
(gile) a répondu à un(e) sujet de famaice dans Visual LISP
Salut, Tu peux faire en sorte que la "Vérification de texte dans l'éditeur" (Ctrl+Alt+C) te rapporte les variable globales pour la fenêtre active (avec parfois des variables signalées comme globales alors qu'elles ne ne sont pas). Menu Outils > Options d'environnement > Options générales > onglet Diagnostic > cocher la case : "Rapporter les stats lors de la vérification syntaxique". Ceci fait, quand tu feras Ctrl+Alt+C tu auras plus d'infos dans la fenêtre de sortie, notamment la présence de variables globales dans le code. -
Salut, Le mode de calcul est géré au niveau de l'application et vaut pour tous les documents ouverts. Pas testé (remplacer excelApp par la variable liée à l'application Excel). (vlax-put excelApp 'Calculation -4105) ; xlCalculationAutomaticou (vlax-put excelApp 'Calculation -4135) ; xlCalculationManual
-
Salut, D'après le peu que je connais. En dessin architechtural, on appelle : Plan de masse : une vue de dessus (projection sur un plan horizontal) Plan de niveau : une coupe suivant un plan horizontal (généralement à 1m du sol) Elévation : une vue de profil (projection sur un plan vertical) Coupe : une coupe suivant plan vertical En dessin industriel on parle plutôt de vues (de dessus, de gauche, de face, ...), de coupes suivant un ou plusieurs plans (la ligne de coupe peut être brisée) et de sections (qui ne représentent que la partie coupée).
-
Récupérer coordonnées d'un sommet
(gile) a répondu à un(e) sujet de Nicky dans Pour aller plus loin en LISP
Pour éviter le copier/coller, je te donne un exemple simple qui montre le principe. (defun c:test (/ msg pt ents) (while (setq pt (if ents ;; si la liste d'entités n'est pas vide (progn (initget "annUler") (getpoint "\nSpécifiez un point ou [annUler]: ") ) ;; sinon (getpoint "\nSpécifiez un point: ") ) ) (if (listp pt) ;; si l'utilisateur a spécifié un point (une liste) (progn ;; on crée l'entité point (command "_.point" "_non" pt) ;; on ajoute l'entité créée à la liste d'entités (setq ents (cons (entlast) ents)) ) ;; sinon (l'utilisateur a entré U) (progn ;; on efface la première entité de la liste d'entité (entdel (car ents)) ;; on redéfinit la liste sans la première entité (setq ents (cdr ents)) ) ) ) (princ) ) -
Récupérer coordonnées d'un sommet
(gile) a répondu à un(e) sujet de Nicky dans Pour aller plus loin en LISP
Concernant les "paramètres" des objets curvilignes, on peut consulter ce sujet. -
Récupérer coordonnées d'un sommet
(gile) a répondu à un(e) sujet de Nicky dans Pour aller plus loin en LISP
Salut, Les fonctions vlax-curve-* sont tes amies. ;; sélectionner une entité (setq sel (entsel)) ;; récupérer le nom d'entité (ENAME) de l'entité sélectionnée (setq ent (car sel)) ;; controler que l'entité sélectionnée est bien une polyligne (= (cdr (assoc 0 (entget ent))) "LWPOLYLINE") ;; récupérer le point cliqué (coordonnées SCU courant) (setq pt (cadr sel)) ;; traduire le point en coordonnées SCG (setq pt (trans pt 1 0)) ;; obtenir le point le plus proche sur la polyligne (setq pt (vlax-curve-getClosestPointToProjection ent pt (trans '(0 0 1) 2 0 T))) ;; obtenir le paramètre de la polyligne au point cliqué (setq par (vlax-curve-getParamAtPoint ent pt)) ;; obtenir le point sur le sommet précédent (point au paramètre entier inférieur) (setq pt1 (vlax-curve-getPointAtParam ent (fix par))) ;; obtenir le point sur le sommet suivant (point au paramètre entier supérieur) (setq pt2 (vlax-curve-getPointAtParam ent (1+ (fix par)))) -
Salut, Jolie coïncidence, ce sujet a démarré alors que je dispensais une formation LISP où une question similaire est posée le même jour. Ceci m'a permis de montrer qu'il ne fallait pas hésiter à poser une question sur un forum et que la réactivité sur CADxp n'est pas une légende. J'ai pu finir aujourd'hui une routine un peu plus générique que l'exemple proposé par didier. Elle devrait fonctionner avec les blocs avec attributs ou sans. Elle prend en compte la rotation du bloc et une échelle uniforme. Resterait à traiter les échelles non-uniforme et les attributs multiligne. ;; entmakeblockreference ;; Insére une référence bloc et éventuellement ses attributs ;; Renvoie le ename de la référence insérée ou nil ;; ;; arguments : ;; blockname : nom du bloc ;; position : point d'insertion ;; rotation : rotation ;; scale : échelle globale ;; attribs : liste de paires (etiquette . valeur) (defun entmakeblockreference (blockname position rotation scale attribs / mxv rotvec blockdef ; liste dxf de la définition de bloc ent ; une entité elst ; une liste dxf attdefs ; liste des listes dxf des définitions d'attribut blockref ; référence de bloc tag ; étiquette d'attribut vec ; déplacement du point d'alignement par rapport au point dinsertion pt ; point d'alignement ht ; hauteur de texte val ; valeur d'attribut ) ;; MXV ;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky- ;; ;; Arguments- ;; m : une matrice ;; v : un vecteur (defun mxv (m v) (mapcar (function (lambda (r) (apply '+ (mapcar '* r v)))) m) ) ;; ROTSCALEVEC ;; Applique une rotation 2d et une échelle à un vecteur ;; ;; Arguments ;; v : vecteur ;; a : angle en radians ;; s : échelle (defun rotscalevec (v a s) (mxv (list (list (* s (cos a)) (* s (- (sin a))) 0.) (list (* s (sin a)) (* s (cos a)) 0.) '(0. 0. 1.) ) v ) ) ;; on contrôle si la table des block contient une définition de bloc nommée 'blockname' (if (setq blockdef (tblsearch "BLOCK" blockname)) (progn ;; collecte les définitons d'attribut dans la définition de bloc (setq ent (cdr (assoc -2 blockdef))) (while ent (setq elst (entget ent)) (if (= (cdr (assoc 0 elst)) "ATTDEF") (setq attdefs (cons elst attdefs)) ) (setq ent (entnext ent)) ) ;; si aucune définition d'attribut n'a été trouvée, (if (null attdefs) ;; alors, création de la réference de bloc (setq blockref (entmakex (list (cons 0 "INSERT") (cons 100 "AcDbEntity") (cons 100 "AcDbBlockReference") (cons 2 blockname) (cons 10 position) ) ) ) ;; sinon, création de la réference de bloc et des références d'attribut (progn (entmake (list (cons 0 "INSERT") (cons 100 "AcDbEntity") (cons 100 "AcDbBlockReference") (cons 66 1) (cons 2 blockname) (cons 10 position) (cons 41 scale) (cons 42 scale) (cons 43 scale) (cons 50 rotation) ) ) ;; création les definitions d'attributs (foreach attdef attdefs (setq tag (cdr (assoc 2 attdef)) vec (if (= (cdr (assoc 72 attdef)) (cdr (assoc 74 attdef)) 0) (rotscalevec (cdr (assoc 10 attdef)) rotation scale) ; bas gauche (rotscalevec (cdr (assoc 11 attdef)) rotation scale) ; autre ) pt (mapcar '+ position vec) ht (* scale (cdr (assoc 40 attdef))) val (cond ((cdr (assoc tag attribs))) ; valeur dans la liste 'attribs' (T (cdr (assoc 1 attdef))) ; valeur par défaut ) ) (entmake (vl-remove nil (list (cons 0 "ATTRIB") ; type d'entité (cons 100 "AcDbEntity") (assoc 8 attdef) ; calque (assoc 62 attdef) ; couleur (assoc 6 attdef) ; type de ligne (assoc 370 attdef) ; épaisseur de ligne (cons 100 "AcDbText") (cons 10 pt) ; point d'insertion (cons 40 ht) ; hauteur de texte (cons 1 val) ; valeur d'attribut (cons 50 rotation) ; rotation (assoc 41 attdef) ; facteur de largeur (assoc 51 attdef) ; inclinaison (assoc 7 attdef) ; style de texte (assoc 71 attdef) ; génération de texte (assoc 72 attdef) ; justification horizontale (cons 11 pt) ; point d'alignement (assoc 210 attdef) ; direction d'extrusion (cons 100 "AcDbAttribute") (assoc 280 attdef) ; numéro de version (cons 2 tag) ; étiquette (assoc 70 attdef) ; drapeaux d'attribut (assoc 73 attdef) ; style d'espacement des lignes de l'entité MTEXT (assoc 74 attdef) ; justification verticale du texte (assoc 280 (reverse attdef)) ; verrouillage de la position ) ) ) ) ;; création de l'objet SEQEND (entmake '((0 . "SEQEND"))) (setq blockref (entlast)) ) ) ) ) ;; valeur de retour blockref )
-
Salut, Remplace (setvar "CMDECHO" 0) par (setvar "CMDECHO" 1) et tu auras les invites.
-
---- Message INDESIRABLES ----
(gile) a répondu à un(e) sujet de rebcao dans CADxp, comment ça marche?
D'après la réponse que je viens d'avoir (voir ci dessous), il semblerait que des mesures aient déjà été prises, mais d'après ce qu'on a pu voir encore ce matin, il semblerait qu'elles ne soient pas suffisantes... PS : Je n'ai toujours pas reçu le mail de M Gladieux. -
---- Message INDESIRABLES ----
(gile) a répondu à un(e) sujet de rebcao dans CADxp, comment ça marche?
Après avoir ré-essayé un message privé et un mail à Cadmin, tous deux restés sans réponse, j'ai finalement contacté le Responsable Publicité de CAD Magazine en me disant qu'il se sentirait peur-être un plus concerné (difficile de vendre des bannières de publicité sur un site infesté de spams). Bien m'en a pris, il m'a rappelé par téléphone, m'a demandé des exemples (je lui ai envoyé des copies d'écran) et semble bien décider à s'en occuper, tout du moins à contacter les personnes pouvant agir. À suivre...
