Author Topic: How to 'NEW' a COM object in lisp?  (Read 7723 times)

0 Members and 1 Guest are viewing this topic.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
How to 'NEW' a COM object in lisp?
« on: May 16, 2011, 02:17:42 PM »
I hope I'm just being dense from being away from lisp for a while, but I'm drawing complete blank how to, or even if I can, do this....

Say I have a method that requires a certain COM object to be passed as a parameter. This object is not a drawing object, but is a definition data object for a Vertical App's object.

In VBA it would be done like so:

Dim myObjData As New SpecialObjectData

Then I could set the data via it's properties:
myObjData.prop1 = "Test"
myObjData.prop2 = "This is some fun stuff!!!"
etc.

And then I could pass this to the first method mentioned:

Dim myObj as SpecialObject
Set myObj = DocDB.AddSpecialObject(myObjData)

I want to do this in lisp, not VBA, so....

Can lisp create that myObjData object to pass to the method? How?

Thanks!

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: How to 'NEW' a COM object in lisp?
« Reply #1 on: May 16, 2011, 02:22:09 PM »
How about (vlax-create-object...), or (vlax-get-or-create-object...)?
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: How to 'NEW' a COM object in lisp?
« Reply #2 on: May 16, 2011, 02:23:46 PM »
Is this what you are looking for?

Code: [Select]
(setq comobj (vlax-get-or-create-object objtype))

beat me to it ...
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: How to 'NEW' a COM object in lisp?
« Reply #3 on: May 16, 2011, 02:40:59 PM »
Thanks, guys, but I don't think that will work. The objects in both of those cases refer to Application objects, such as working with Excel:
Code: [Select]
(vlax-create-object "Excel.Application")
#<VLA-OBJECT _Application 0017b894>
This is just an object defined by the COM Application which has previously been loaded.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: How to 'NEW' a COM object in lisp?
« Reply #4 on: May 16, 2011, 02:41:56 PM »
vlax-invoke?
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: How to 'NEW' a COM object in lisp?
« Reply #5 on: May 16, 2011, 02:44:41 PM »
vlax-get-or-create-object works great for loading Excel working with it .. in fact, that is EXACTLY the bit of code I used from an application I wrote some time ago to export block information to a spreadsheet.

If you would like to have some pointers on working with excel, let me know.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How to 'NEW' a COM object in lisp?
« Reply #6 on: May 16, 2011, 02:45:03 PM »
If you already have instances of the objects (myObjData and DocDB), then ...

(vla-put myObjData 'prop1 "Test")

(vlax-invoke DocDB 'AddSpecialObject myObjData)

Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: How to 'NEW' a COM object in lisp?
« Reply #7 on: May 16, 2011, 02:53:51 PM »
Well, looks like I did a poor job of explaining this using generic items....let's try this again using a specific example from the VBA Samples for Civil3D.

Say I want to convert the following to lisp, and I already have the civildocument:
Code: [Select]

    Dim oSurfaces As AeccSurfaces
    ' Get the collection of all surfaces in the drawing.
    Set oSurfaces = g_oDocument.Surfaces

        Dim oTinSurface As AeccTinSurface
        Dim oTinCreationData As New AeccTinCreationData
        
        oTinCreationData.BaseLayer = "0"
        oTinCreationData.Layer = "0"
        oTinCreationData.Description = ""
        oTinCreationData.Name = "EG"
        oTinCreationData.Style = "Standard"
        Set oTinSurface = g_oDocument.Surfaces.AddTinSurface(oTinCreationData)

I should note that this is one reason why I've concentrated my C3D programming efforts to using C# ....

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: How to 'NEW' a COM object in lisp?
« Reply #8 on: May 16, 2011, 02:59:27 PM »
You would need to explore the document interface object and see what properties and methods are available. However, if you only have an ename for an object, you will need to turn it into a vla-object.

Code: [Select]
(setq MyDoc (vlax-ename->vla-object document))

If you already have the document as a vla-object, dump it from the command line and see which properties and methods are available.

Code: [Select]
(vlax-dump-object document)

Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: How to 'NEW' a COM object in lisp?
« Reply #9 on: May 16, 2011, 04:46:22 PM »
Thanks, guys, but I don't think that will work. The objects in both of those cases refer to Application objects, such as working with Excel:
Code: [Select]
(vlax-create-object "Excel.Application")
#<VLA-OBJECT _Application 0017b894>
This is just an object defined by the COM Application which has previously been loaded.

I routinely use them with "non-application" objects, like

Code: [Select]
(vlax-create-object "MSXML2.DOMDocument.6.0")
C3D COM may not expose enough of itself for LISP to do this, though.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: How to 'NEW' a COM object in lisp?
« Reply #10 on: May 16, 2011, 05:05:51 PM »
You might still be able to invoke some of the methods even if you can't see them when dumped.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

hermanm

  • Guest
Re: How to 'NEW' a COM object in lisp?
« Reply #11 on: May 17, 2011, 01:03:53 AM »
Is there a tlb for Civil3D?
You can use VS to browse the COM interface - may be a dll, not tlb.

I'm guessing, but you may need to do something like:

Code: [Select]
(setq C3DObject1 (vlax-invoke *ACAD* 'GetInterfaceObject "CIVIL3D.SomeObject"))

where "CIVIL3D" (or Aecc, or something else) is the name of the tlb, and SomeObject is one of its classes

Looks like there is a container object for the data, which must be passed to another object which creates the surface..correct?

maybe:
Code: [Select]
(setq TCData (vlax-invoke *ACAD* 'GetInterfaceObject "Aecc.AeccTinCreationData"))
(vlax-put-property TCData 'SomeProperty somevalue)
<put more properties>
(setq Surfaces (vlax-get g_oDocument 'Surfaces))
(setq NewSurface (vlax-invoke Surfaces 'AddTinSurface TCData))
or, maybe not  :|

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: How to 'NEW' a COM object in lisp?
« Reply #12 on: May 17, 2011, 10:06:42 AM »
Ding Ding Ding Ding  We have a winner!!!!!!!!

Thank you Herman, this is precisely what I needed. Here is the portion of code to create an AeccTinSurface in C3D 2010-2012:
Code: [Select]

(vl-load-com)
(setq prod (vlax-product-key))
(setq verstr (cond ((vl-string-search "\\R18.0\\" prod)
    "7.0"
   )
   ;;2010
   ((vl-string-search "\\R18.1\\" prod)
    "8.0"
   )
   ;;2011
   ((vl-string-search "\\R18.2\\" prod)
    "9.0"
   )
   ;;2012
     )
)
(setq prodStr (strcat "AeccXUiLand.AeccApplication." verstr))
(setq datastr (strcat "AeccXLand.AeccTinCreationData." verstr))

(if (and (setq *acad* (vlax-get-acad-object))
(setq C3D (vla-getinterfaceobject *acad* prodStr))
(setq C3Ddoc (vla-get-activedocument C3D))
(setq surfs (vlax-get C3Ddoc 'surfaces))
(setq tincreationdata (vla-getinterfaceobject *acad* datastr))
    )
  (progn
    (vlax-put tincreationdata 'baselayer "0")
    (vlax-put tincreationdata 'layer "0")
    (vlax-put tincreationdata 'description "Surface from Lisp")
    (vlax-put tincreationdata 'name "Lisp EG")
    (vlax-put tincreationdata 'style "Border Only")   ;;style must exist!
    (setq surf (vlax-invoke-method surfs 'addtinsurface tincreationdata))
    ;; do whatever else is needed
    (vlax-release-object tincreationdata)
    (vlax-release-object surf)
    (vlax-release-object surfs)
    (vlax-release-object c3ddoc)
  )
)
Thanks again! I don't think I would've ever figured that out on my own...I can only recall ever using the GetInterfaceObject for the Application object.

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: How to 'NEW' a COM object in lisp?
« Reply #13 on: May 17, 2011, 10:26:10 AM »
I tried that with ADT (Architecture) some time ago with some success.   I didn't have the time to explore, but it appeard to be a pretty powerful way to automate AEC stuff.  The one thing I remember is to release the created AEC object as soon as possible.  And use (GC) liberally.  The AEC stuff isn't really meant to be manipulated using vl, vlax stuff.  Why it was created this way I just don't know. 

Good luck!

Oh, and practice / perfect the code in drawings you don't mind corrupting.  It happens with AEC!

jb
James Buzbee
Windows 8

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: How to 'NEW' a COM object in lisp?
« Reply #14 on: May 17, 2011, 01:19:55 PM »
D'OH!  Keep forgetting about that GetInterfaceObject function, mostly from lack of use.  Most of my vlax- stuff doesn't rely on items that have an interface object (e.g. a specialized constructor) between me and its contents.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

Michael

  • Guest
Re: How to 'NEW' a COM object in lisp?
« Reply #15 on: May 20, 2011, 05:19:09 PM »
Thanks for the great info....I was just scratching my head on how to do this very thing.  :-)