TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Hangman on April 30, 2010, 02:10:17 PM
-
I have a piece of code Tim helped put together for me which grabs a string of text from an attribute block or any text element, and copies it to another element.
Here's a piece of it:
(mapcar
'(lambda (x)
(vlax-put ToObj x (vlax-get FromObj x)))
'("TextString")
)
My question is this; is there a documented something out there somewhere that will tell me more about what the vlax-put and the vlax-get commands can control ??
For example, the code here shows it'll grab the '("TextString") of object 'FromObj' variable. I have another piece of code identical to it, but it gets the '("ScaleFactor") of a text object.
I'm wondering if there's more I can add to this. Getting an insertion point of a text object, or layer, or ... something else. What are my options ??
I hope this is making some sense, I know what I want to search for but I don't know just how to explain it I think.
Thank you for your help.
-
This (http://www.theswamp.org/index.php?topic=5185.msg62997#msg62997)may help. Haven't use it for years myself but I just tried it with AutoCAD 2008 and it appears to still work.
-
Kudos to MP once again for his fine work (as usual).
Thanks, MP. :)
Haven't use it for years myself
Eh? Meaning,
a) you've got the ACAD AX typelib committed to memory, or
b) you no longer write AutoLISP
?
Other options per hangman's Q:
1. invoke VBAIDE and use its object browser - bad habit for the long run, as Adesk admits VBA is going away
2. go to Microsft website, down load a free version of one of their compilers and use its object browser
3. search the web for a free or nearly free typelib browser.
All those options will give you the ability to browse other typelibs on your machine,
But none, AFAIK, will tell you the difference between a (vlax-get) and (vlax-get-property) call.
Thx, MP.
-
Thanks Herman, nice of you to say. As for memory -- I forget when I had a good one -- I lean on one of my other tools to help me with my object model exploits.
-
Just for the record. You don't need the mapcar statement or a list for that.
eg.
((lambda (x)
(vlax-put ToObj x (vlax-get FromObj x))
)
"TextString"
)
-
vlax-put / get are undocumented as far as I know, but here's my take on the subject:
Using the example of retrieving the Centre of a Circle:
A Circle has the center property and this can be retrieved using the following methods, each with varying returns:
Method 1:
(vla-get-Center <circle>)
Returns a Variant:
#<variant 8197 ...>
[ The 8197 indicates the variant type (which can also be obtained using the vlax-variant-type, in this case 8197 = 8192 + 5 indicating that the variant is a safearray of Doubles. ]
This can be converted to a SafeArray, then a 3D point using:
(vlax-safearray->list
(vlax-variant-value
(vla-get-center <circle>)))
We now have the data in list form.
Method 2:
(vlax-get-property <circle> 'Center)
This will also return a variant, and the above applies.
Method 3:
(vlax-get <circle> 'Center)
This is an older method, and the function vlax-get isn't documented. The method will return data in AutoLISP data types:
(-46.4701 16.7293 0.0)
This method is preferable in most cases, but can sometimes be troublesome with some properties.
A similar reasoning applies to Methods,
Using our Circle as an example again, let's say we want to perform the Move Method:
Method 1:
We could use:
(vla-move <circle> (vlax-3D-point <point1>) (vlax-3D-point <point2>))
Notice that we require the vlax-3D-point function to convert our 3 element lists into safearray variants of Doubles.
Aside: Another way to create our variants for use with this method would be:
(vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray vlax-vbDouble '(0 . 2)) <point>))
But this is of course slightly verbose...
Method 2:
Using the logic that applied to the property functions, we could also use:
(vlax-invoke-method <circle> 'Move (vlax-3D-point <point1>) (vlax-3D-point <point2>))
This again deals in variants.
Method 3:
Finally, we can use:
(vlax-invoke <circle> 'Move <point1> <point2>)
This method deals in native AutoLISP datatypes such as lists, and can sometimes be more manageable.
Thats all for now,
Lee
-
Very nice explanation Lesson Lee -- the only thing I'd add for the OP is that all the vla-* stuff is just a large <convenience> wrapper library -- everything that is accessible via vla-get* | vla-put* | vla-method* is also accessible via vlax-get | vlax-put | vlax-invoke -- but not vice versa.
-
Most educational!
(http://blogs.guardian.co.uk/music/billandted460.jpg)
-
mmm, IC
Command: (vla-get-center obj)
#<variant 8197 ...>
Command: (type (vla-get-center obj))
variant
Command: (vlax-variant-type (vla-get-center obj))
8197
so, all we need is a LIST of variant types (exists somewhere handy, no doubt) & we can construct a decoder for the variant type which means something to LISP programmers (a.k.a. "humans")
Thx, Lee. :)
One o' these days, "we" will have an automatic decoder for AX typelib "documentation" which gives examples only in the obsolete language called VBA.
Said translator/decoder will be written in LISP (natch).
Doug Broad hinted at such in a post on a.a.c some time ago...
So, the concept exists...
@ MP:
they say memory is the first thing to go...and I can't remember wut goes next 8-)
-
so, all we need is a LIST of variant types (exists somewhere handy, no doubt) & we can construct a decoder for the variant type which means something to LISP programmers (a.k.a. "humans")
vlax-safearray->list
-
I've always Enjoyed the comments :-D
The code's pretty cool too !
(defun lisp-value (v)
;; Copyright 2002 Vladimir Nesterovsky.
;; Free for use by any commercial entity with
;; less then $100 million annual revenue.
(cond
((= (type v) 'variant)
(lisp-value (variant-value v)))
((= (type v) 'safearray)
(mapcar 'lisp-value (safearray-value v)))
(T v)
)
)
-
^ one my personal favorite bits of code as well. ...hey look, COND not OR. *LOL*
-
:-P
Want to borrow my t-shirt John ??
-
Hi,
about variants and safearrays, you can see this thread (http://www.theswamp.org/index.php?topic=31674.0).
-
Thanks Michael - I suppose that fact reveals itself more prominently when interfacing with objects outside of AutoCAD. :-)
I must say, that's great code Kerry!
-
Yes, but not exclusively.
Try this (hope I type this out on my blackberry correctly, ain't ez) --
(vlax-get (setq object (vlax-ename->vla-object (car (entsel)))) 'EntityType)
Then this --
(vla-get-entitytype object)
*faceplant*
-
Ooo didn't know about that one! In that case, I'm sure there are others. Thanks dude :-)
-
Yes, but not exclusively.
Try this (hope I type this out on my blackberry correctly, ain't ez) --
(vlax-get (setq object (vlax-ename->vla-object (car (entsel)))) 'EntityType)
Then this --
(vla-get-entitytype object)
*faceplant*
I know the returned integer pertains to the specific object, but what's the purpose of EntityType?
-
The succinct description from the property itself is "Returns the entity type of the object as an integer". Example, lines are 19, arcs are 4, circles 8 etc. Obviously they are members of an enumeration tho it appears not formally. That is, while I found the enumeration AcEntityName, with values confirming the preceding "lines are 19" etc. the return type for the EntityType property is not spec'd as AcEntityName but merely Long:
Property EntityType As Long
read-only
Member of AutoCAD.AcadLine
Returns the entity type of the object as an integer.
(http://i40.tinypic.com/1zztjqa.jpg)