Re: COM/Automation: how do I pass an array to a variant parameter in LWW ?
At 21:53 18/10/2006, Martti Halminen wrote:
>I'm trying to use LWW 4.4.6 for programming AutoCAD 2006 through ActiveX,
> and got stuck when trying to send a Lisp array to it in a parameter
>expecting a variant.
>I can't make any sense of the documents, and no example code I have found
>shows LWW operation with variants
> containing arrays.
>
>Neither the array as such nor anything produced by com:make-lisp-variant
>that I have tried works.
>
>The receiving function definition in the type library as IDL:
>
> [id(0x0000000e), helpstring("Append loops to the hatch"),
>helpcontext(0x00010117)]
> HRESULT AppendOuterLoop([in] VARIANT ObjectArray);
>
>
>
>In VBA this can be used directly with an array of objects:
> ' Create the associative Hatch object
> Set hatchObj = ThisDrawing.ModelSpace.AddHatch(PatternType,
>patternName, bAssociativity)
>
> ' Create the outer loop for the hatch.
> ' An arc and a line are used to create a closed loop.
> Dim outerLoop(0 To 1) As AcadEntity
> Dim center(0 To 2) As Double
> Dim radius As Double
> Dim startAngle As Double
> Dim endAngle As Double
> center(0) = 5: center(1) = 3: center(2) = 0
> radius = 1
> startAngle = 0
> endAngle = 3.141592
> Set outerLoop(0) = ThisDrawing.ModelSpace.AddArc(center, radius,
>startAngle, endAngle)
> Set outerLoop(1) =
>ThisDrawing.ModelSpace.AddLine(outerLoop(0).startPoint,
>outerLoop(0).endPoint)
>
> ' Append the outer loop to the hatch object, and display the hatch
> hatchObj.AppendOuterLoop (outerLoop)
> hatchObj.Evaluate
>
>
>
>So, how am I supposed to call invoke-dispatch-method with an array of
>i-dispatch objects?
Hi,
I would expect something like this to work (completely untested btw) ...
(defun add-hatch (model-space pattern-type pattern-name b-associativity)
(let((center (vector 5.0 3.0 0.0))
(radius 1.0)
(start-angle 0.0)
(end-angle 3.141592))
(com:with-temp-interface
(hatch)
(com:invoke-dispatch-method model-space "AddHatch" pattern-type
pattern-name b-associativity)
(com:with-temp-interface
(arc-entity)
(com:invoke-dispatch-method model-space "AddArc" center radius
start-angle end-angle)
(let ((start-point (com:invoke-dispatch-get-property arc-entity
"startPoint"))
(end-point (com:invoke-dispatch-get-property arc-entity
"endPoint")))
(com:with-temp-interface
(line-entity)
(com:invoke-dispatch-method model-space "AddLine"
start-point end-point)
(com:invoke-dispatch-method hatch "AppendOuterLoop" (vector
arc-entity line-entity))
(com:invoke-dispatch-method hatch "Evaluate")))))))
What errors do you get ?
The LWW doc is not explicit about how it handles types inside arrays:
http://www.lispworks.com/documentation/lw50/COM/html/com-95.htm#84037
But as it can handle conversion between com:com-interface and IDispatch*
(VT_DISPATCH) as top level arguments I would expect it to work when these
values are in an array. LWW should create a VARIANT with vt set to VT_ARRAY
| VT_DISPATCH. This should work with the AppendOuterLoop method.
If you want or need to try creating a variant explicitly then I think you
need to do
(make-lisp-variant '(:array :dispatch :dispatch) (vector arc-entity
line-entity))
rather than just (vector arc-entity line-entity) in the code above.
(BTW I am guessing that startPoint and endPoint are properties that return
an array of floats. If they return IDispatch interfaces then they should be
wrapped in com:with-temp-interface or explicitly released. If they are
methods not properties then use com:invoke-dispatch-method - to state the
obvious ;-)
HTH
paulm