Author Topic: ActiveX Attribute Definition Insertion point always goes to Origin (0.0 0.0 0.0)  (Read 2647 times)

0 Members and 1 Guest are viewing this topic.

PKENEWELL

  • Bull Frog
  • Posts: 321
Hi All,

I wonder if anyone can take a look at my code for placing attribute definitions via ActiveX and tell me if or what I am doing wrong. No matter what Insertion Point I provide - the Attribute Definition keeps getting placed at the WCS origin (0.0 0.0 0.0). Is there something I am not seeing, or is this a know problem?

Thanks for any insights.

Code - Auto/Visual Lisp: [Select]
  1. ;|==============================================================================
  2.   Function Name: (pjk-AddAttributeDef) by Phil Kenewell 1/2014
  3.   Arguments:
  4.                 sty = string; The Text Style to apply or NIL for current
  5.                 hgt = real; The height of the attribute text or NIL for the current TEXTSIZE value
  6.                 just = string; a string code the same at the options of the -ATTDEF command for
  7.                                     justification options. [LEFT/RIGHT/CENTER/ALIGNED/MIDDLE/FIT/TL/TC/TR/ML/MC/MR/BL/BC/BR]
  8.                 mode = integer; a bitcode for the attribute modes enum
  9.                                        acAttributeModeNormal
  10.                                         acAttributeModeInvisible
  11.                                         acAttributeModeConstant
  12.                                         acAttributeModeVerify
  13.                                         acAttributeModeLockPosition
  14.                                         acAttributeModeMultipleLine
  15.                                         acAttributeModePreset
  16.           inspt = 3D point; a point in list form as returned from (getpoint)
  17.           tag = string; A tag value for the Attribute Definition
  18.           prmt = string; A Prompt value for the Attribute Definition
  19.           def =  string; A default value for the Attribute Definition or NIL for none
  20.           lyr =  string; An existing Layer name to apply to the Attribute Definition or NIL for the current layer
  21.  
  22.   Returns: boolean; T if sucessful, NIL if not.
  23.   Description:
  24.                 This function creates an Attribute definition using ActiveX methods.
  25. ================================================================================|;
  26. (defun pjk-AddAttributeDef (sty hgt just mode inspt tag prmt def lyr / attd doc ret space)
  27.            space (if (> (getvar "CVPORT") 1)(vla-get-modelspace doc)(vla-get-paperspace doc))
  28.            sty   (if sty sty (getvar "textstyle"))
  29.            hgt   (if hgt hgt (getvar "textsize"))
  30.            just  (if just just "MC")
  31.            mode  (if mode mode 0)
  32.            inspt (vlax-3d-point (trans inspt 1 0))
  33.            prmt  (if prmt prmt "Enter Value: ")
  34.            def   (if def def "")
  35.             lyr   (if (and lyr (tblsearch "LAYER" lyr)) lyr (getvar "CLAYER"))
  36.            attd  (vla-AddAttribute space hgt mode prmt inspt tag def)
  37.         )
  38.         (if attd
  39.                 (progn
  40.                        (vla-put-layer attd lyr)
  41.                         (vla-put-StyleName attd sty)
  42.                         (pjk-SetTextAlignment attd just)
  43.                         (if (not (wcmatch just "LEFT,ALIGNED,FIT"))
  44.                                 (vla-put-TextAlignmentPoint attd inspt)
  45.                                 (vla-put-InsertionPoint attd inspt)
  46.                         ) ;; Added This IF statement
  47.                         (vlax-release-object attd)
  48.                         (setq ret T)
  49.                 )
  50.         )
  51.        (mapcar 'vlax-release-object (list space doc))
  52.         ret
  53. );; End Function (pjk-AddAttributeDef)
  54.  
  55. ;|==============================================================================
  56.   Function Name: (pjk-SetTextAlignment) by Phil Kenewell 6/2011
  57.   Arguments:
  58.                 obj = VLA-object; The Object to apply the alignment property to ("AcDbText", "AcDbAttributeDefinition")
  59.                 just = string; a string code the same at the options of the TEXT / -ATTDEF command for
  60.                                  justification options. [LEFT/RIGHT/CENTER/ALIGNED/MIDDLE/FIT/TL/TC/TR/ML/MC/MR/BL/BC/BR]
  61.  
  62.   Returns: the VLA-object that the property was applied to.
  63.   Description:
  64.                 This function sets the alignment property of TEXT or ATTDEF objects
  65.                 using the ActiveX enum, given a justification option equivalent to
  66.                 the TEXT or -ATTDEF commands
  67. ================================================================================|;
  68. (defun pjk-SetTextAlignment (obj just / prop)
  69.         (cond
  70.                 ((= (strcase just) "LEFT")(setq prop acAlignmentLeft))
  71.                 ((= (strcase just) "RIGHT")(setq prop acAlignmentRight))
  72.                 ((= (strcase just) "CENTER")(setq prop acAlignmentCenter))
  73.                 ((= (strcase just) "ALIGNED")(setq prop acAlignmentAligned))
  74.                 ((= (strcase just) "MIDDLE")(setq prop acAlignmentMiddle))
  75.                 ((= (strcase just) "FIT")(setq prop acAlignmentFit))
  76.                 ((= (strcase just) "TL")(setq prop acAlignmentTopLeft))
  77.                 ((= (strcase just) "TC")(setq prop acAlignmentTopCenter))
  78.                 ((= (strcase just) "TR")(setq prop acAlignmentTopRight))
  79.                 ((= (strcase just) "ML")(setq prop acAlignmentMiddleLeft))
  80.                 ((= (strcase just) "MC")(setq prop acAlignmentMiddleCenter))
  81.                 ((= (strcase just) "MR")(setq prop acAlignmentMiddleRight))
  82.                 ((= (strcase just) "BL")(setq prop acAlignmentBottomLeft))
  83.                 ((= (strcase just) "BC")(setq prop acAlignmentBottomCenter))
  84.                 ((= (strcase just) "BR")(setq prop acAlignmentBottomRight))
  85.         )
  86.         (if prop (vla-put-Alignment obj prop))
  87. );; End Function (pjk-SetTextAlignment)
  88.  

EDIT: Corrected code after determining the problem.
EDIT2: Corrected code again to prevent error with TextAlignmentPoint
« Last Edit: February 06, 2014, 06:36:00 PM by PKENEWELL »
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

PKENEWELL

  • Bull Frog
  • Posts: 321
Hi All,

I wonder if anyone can take a look at my code for placing attribute definitions via ActiveX and tell me if or what I am doing wrong. No matter what Insertion Point I provide - the Attribute Definition keeps getting placed at the WCS origin (0.0 0.0 0.0). Is there something I am not seeing, or is this a know problem?

Thanks for any insights.

Never Mind - I figured it out. After you set the Alignmentpoint to something other than "acAlignmentLeft", you have to set the "TextAlignmentPoint" property.
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
:)
Was just writing that when you posted yours.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

PKENEWELL

  • Bull Frog
  • Posts: 321
:)
Was just writing that when you posted yours.

LOL - Thanks anyway  :laugh:
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
I would suggest something along the following lines:

Code - Auto/Visual Lisp: [Select]
  1. (defun addattdef ( sty hgt jus flg ins tag pmt def lay / obj )
  2.     (setq obj
  3.         (vlax-invoke
  4.                 (if (= 1 (getvar 'cvport))
  5.                     'paperspace
  6.                     'modelspace
  7.                 )
  8.             )
  9.             'addattribute
  10.             (cond ( hgt ) ((getvar 'textsize)))
  11.             (cond ( flg ) (acattributemodenormal))
  12.             (cond ( pmt ) ("Enter value:"))
  13.             (trans ins 1 0)
  14.             tag
  15.             (cond ( def ) (""))
  16.         )
  17.     )
  18.     (if (and lay (tblsearch "layer" lay))
  19.         (vla-put-layer obj lay)
  20.     )
  21.     (if (and sty (tblsearch "style" sty))
  22.         (vla-put-stylename obj sty)
  23.     )
  24.         (cond
  25.             (   (eval
  26.                     (cdr
  27.                         (assoc (strcase jus t)
  28.                            '(
  29.                                 ("left"    . acalignmentleft)
  30.                                 ("center"  . acalignmentcenter)
  31.                                 ("right"   . acalignmentright)
  32.                                 ("aligned" . acalignmentaligned)
  33.                                 ("middle"  . acalignmentmiddle)
  34.                                 ("fit"     . acalignmentfit)
  35.                                 ("tl"      . acalignmenttopleft)
  36.                                 ("tc"      . acalignmenttopcenter)
  37.                                 ("tr"      . acalignmenttopright)
  38.                                 ("ml"      . acalignmentmiddleleft)
  39.                                 ("mc"      . acalignmentmiddlecenter)
  40.                                 ("mr"      . acalignmentmiddleright)
  41.                                 ("bl"      . acalignmentbottomleft)
  42.                                 ("bc"      . acalignmentbottomcenter)
  43.                                 ("br"      . acalignmentbottomright)
  44.                             )
  45.                         )
  46.                     )
  47.                 )
  48.             )
  49.             (   acalignmentmiddlecenter   )
  50.         )
  51.     )
  52.     (if (= acalignmentleft (vla-get-alignment obj))
  53.         (vla-put-insertionpoint     obj (vlax-3D-point (trans ins 1 0)))
  54.         (vla-put-textalignmentpoint obj (vlax-3D-point (trans ins 1 0)))
  55.     )
  56.     obj
  57. )

PKENEWELL

  • Bull Frog
  • Posts: 321
I would suggest something along the following lines:

As always Lee - You code structure is impeccable. You have given me some ideas to think about. I also realize on further testing of my code that I need to prevent an automation error when the alignment point is Left, Aligned, or Fit. The reason I use a separate function for setting the alignment property is because I use it with single line Text objects as well.

I have always been confused on the practice of releasing objects, so I tend to set them to a variable - then release them when finished. By your practices, I assume that if you do not set ActiveX objects to variables, then there is no need to release them? I have always been confused by this, since It has been debated that you need to release the objects rather than just set the variables to nil.

Anyway - thanks much for your examples! Your code is brilliant! I have learned much about streamlining Autolisp code from you. I have been coding Autolisp for almost 20 years, and thought I was pretty decent at it until I encountered you and the other Swampers. I used to use loops like foreach, repeat, and while in much of my old code to handle lists. I have converted much code recently to using mapcar and lambda thanks you your tutoring on this forum. Also using things like (cond) for defaulting is new to me.
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
I would suggest something along the following lines:

< .. >

Perhaps adding an additional parameter to indicate the owner of the attribute would make the function more generic.

ie: either a block object or nil.
if nil use your current owner code, otherwise add the attribute to the block object nominated.

Just a thought.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
As always Lee - You code structure is impeccable. You have given me some ideas to think about. I also realize on further testing of my code that I need to prevent an automation error when the alignment point is Left, Aligned, or Fit. The reason I use a separate function for setting the alignment property is because I use it with single line Text objects as well.

Thank you for your compliments PKENEWELL -
My example was just a refinement of your code, as I noticed that some expressions could be written more clearly & concisely - I'm glad that you can take some ideas/techniques from the code.

I have always been confused on the practice of releasing objects, so I tend to set them to a variable - then release them when finished. By your practices, I assume that if you do not set ActiveX objects to variables, then there is no need to release them? I have always been confused by this, since it has been debated that you need to release the objects rather than just set the variables to nil.

Your assumption is not true that if objects are not assigned to variables that they do not need to be released - the object still resides in the allocated memory, only, there is no pointer to the memory address in which it resides. When assigning data to variables, the variables are simply pointers to the location of the data in the system memory - data which is not assigned to a variable still exists in the system memory, only we don't know where (those who know more on this subject, please feel free to correct me).

However, having also queried the practices of releasing objects myself in the past, I hold the understanding that the general consensus is that it is not necessary to release objects which fall within the AutoCAD Object Model (i.e. anything derived from vlax-get-acad-object), as AutoCAD will release these objects automatically when a garbage collection is performed periodically during the drawing session (which you can also force manually using gc). However, I believe it is necessary to release objects which are outside of the AutoCAD Object Model, such as when interfacing with the Excel Application object, FSO or WSH.

Anyway - thanks much for your examples! Your code is brilliant! I have learned much about streamlining Autolisp code from you. I have been coding Autolisp for almost 20 years, and thought I was pretty decent at it until I encountered you and the other Swampers. I used to use loops like foreach, repeat, and while in much of my old code to handle lists. I have converted much code recently to using mapcar and lambda thanks you your tutoring on this forum. Also using things like (cond) for defaulting is new to me.

Thank you for your kind words PKENEWELL, I too have learnt a great deal from the knowledgeable community here at the Swamp. As I've discussed in another recent thread, many programs could be written using only foreach / repeat / while loops, and using nested if statements in place of a single cond expression; there are often many ways to perform the same task in AutoLISP, but becoming familiar with all the tools in your AutoLISP toolbox ensures that a program can be built with more than just a sledgehammer  :-)

I would suggest something along the following lines:

< .. >

Perhaps adding an additional parameter to indicate the owner of the attribute would make the function more generic.

ie: either a block object or nil.
if nil use your current owner code, otherwise add the attribute to the block object nominated.

Just a thought.

Agreed, something like:
Code - Auto/Visual Lisp: [Select]
  1.     ( own )
  2.             (if (= 1 (getvar 'cvport))
  3.                 'paperspace
  4.                 'modelspace
  5.             )
  6.         )
  7.     )
  8. )

PKENEWELL

  • Bull Frog
  • Posts: 321
Quote
Your assumption is not true that if objects are not assigned to variables that they do not need to be released - the object still resides in the allocated memory, only, there is no pointer to the memory address in which it resides. When assigning data to variables, the variables are simply pointers to the location of the data in the system memory - data which is not assigned to a variable still exists in the system memory, only we don't know where (those who know more on this subject, please feel free to correct me).

However, having also queried the practices of releasing objects myself in the past, I hold the understanding that the general consensus is that it is not necessary to release objects which fall within the AutoCAD Object Model (i.e. anything derived from vlax-get-acad-object), as AutoCAD will release these objects automatically when a garbage collection is performed periodically during the drawing session (which you can also force manually using gc). However, I believe it is necessary to release objects which are outside of the AutoCAD Object Model, such as when interfacing with the Excel Application object, FSO or WSH.

Thanks Lee! That clears up allot for me. Many Thanks!
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
You're welcome!  :-)