;;;Código fuente del libro "Experto AutoCAD con Visual LISP"
;;; (c) 2012 Ediciones ARTUAL, S.L. Barcelona, España.
;;; (c) 2012-2020 Reinaldo Togores. Todos los derechos reservados
;;; Se permite su uso mencionando la obra y su autor.
;;;CapÃtulo 6.  Estructuras y Datos ActiveX--------------------------
;;;6.1  Matrices (Arrays)
(defun ax-cuadrada? (matriz / dim tmp)Â
  (setq dim 1)
  (repeat (vlax-safearray-get-dim matriz)Â
    (setq tmp (consÂ
                (- (vlax-safearray-get-u-bound matriz dim)Â
                   (vlax-safearray-get-l-bound matriz dim))
                tmp)
          dim (1+ dim)))
  (apply '= tmp))
;;;Listado 6.1. Función AX CUADRADA?.
(defun ax-safearrayp (dato)Â
  (eq (type dato) 'safearray))
;;;Listado 6.2. Predicado AX-SAFEARRAYP.
(defun ax-matriz->lista (s-arr)Â
  (if (ax-safearrayp s-arr)Â
    (vlax-safearray->list s-arr)))
;;;Listado 6.3. Función AX-MATRIZ->LISTA.
(defun ax-tipo-dato (lista)Â
  (ifÂ
    (apply 'andÂ
           (mapcar '(lambda (x y) (eq (type x) (type y)))Â
                   lista
                   (cdr lista)))
    (ax-tipo (car lista))
    vlax-vbVariant))
;;;Listado 6.4. Función AX TIPO-DATO.
(defun ax-tipo (dato)Â
  (setq dato (type dato))
  (condÂ
    ((eq dato 'INT) vlax-vbLong)
    ((eq dato 'REAL) vlax-vbDouble)
    ((eq dato 'STR) vlax-vbString)
    ((eq dato 'VLA-OBJECT) vlax-vbObject)
    (t vlax-vbVariant)))
;;;Listado 6.5. Función AX-TIPO.
(defun ax-lista->matriz (lista)Â
  (vlax-safearray-fillÂ
    (vlax-make-safearrayÂ
      (ax-tipo-dato lista)
      (cons 0 (1- (length lista))))
    lista))
;;;Listado 6.6. Función AX-LISTA->MATRIZ.
;;;6.6  Procesamiento de Colecciones.--------------------------------
(defun ax-act-des (dibujo)Â
  (vlax-map-collectionÂ
    (vla-get-layers dibujo)
    '(lambda (x)Â
       (if (equal (vla-get-LayerOn x) :vlax-true)Â
         (vla-put-LayerOn x :vlax-false)
         (vla-put-LayerOn x :vlax-true)))))
;;;Listado 6.7. Función para activar/desactivar capas mediante ActiveX.
(defun ax-lista-capas (dibujo / capas)Â
  (vlax-for capaÂ
            (vla-get-layers dibujo)
            (setq capas (cons (vla-get-name capa) capas)))
  (acad_strlsort capas))
;;;Listado 6.8. Obtención de una lista de las capas del dibujo mediante ActiveX.
(defun ax-lista-nombres (dibujo nombre / nombres)Â
  (setq coleccion (vlax-get-property dibujo nombre))
  (vlax-for objÂ
            coleccion
            (setq nombres (cons (vla-get-name obj) nombres)))
  (acad_strlsort nombres))
;;;Listado 6.9. Función genérica para obtener los nombres de los objetos de una colección.
;;;6.7.Managing exceptions.
(defun tan~ (ang) (/ (sin ang) (cos ang)))
;;;Listado 6.10. Cálculo de tangente sin prever la división por cero.
(defun tan (ang / coseno)Â
  (if (zerop (setq coseno (cos ang)))Â
    1.8E+308
    (/ (sin ang) coseno)))
;;;Listado 6.11. Cálculo de la tangente previendo la división por cero.
(defun ax-existe? (elemento colección)Â
  (notÂ
    (vl-catch-all-error-pÂ
      (vl-catch-all-applyÂ
        'vla-item
        (list colección elemento)))))
;;;Listado 6.12. Comprobar si existe un elemento en una colección.
(defun ax-existe? (elemento colección / resultado)Â
  (ifÂ
    (notÂ
      (vl-catch-all-error-pÂ
        (setq resultado (vl-catch-all-applyÂ
                          'vla-item
                          (list colección elemento)))))
    resultado))
;;;Listado 6.13. Función AX-EXISTE? que devuelve el objeto-VLA.