A student created ooRexx scripts to drive AutoCAD. In that context he experienced a problem not
being able to use a method addCircle(center, radius) from ooRexx. The core reason for this problem
is AutoCAD reporting a wrong datatype to be used for center, namely VT_VARIANT where in fact it must
be of VT_ARRAY,VT_R8 (an array of decimals/reals) with three elements.
Using the internet, researching AutoCAD samples in VBA makes it clear that "center" is a point in
the 3-dimensional space, also that the VBA samples explicitly create an array of type decimal (VT_R8).
In the case a VT_VARIANT is sought by the Windows program and supplying an ooRexx array for it,
ooRexx will create an array of type VT_ARRAY,VT_VARIANT. A VT_VARIANT type can effectively contain
any datatype, cf. [1] below.
All the Windows programs, especially the reference implementation with MS Office can use
VT_ARRAY/VT_VARIANT without any problems. The COM/OLE infrastructure by Microsoft makes it fairly
easy to convert one datatype to any other datatype (if conversion is principally possible). So it is
not a problem to e.g. get a VT_ARRAY/VT_VARIANT and convert e.g. elements of type VT_I4, VT_R4 to
VT_R8, it just needs to be done by the Windows application. AutoCAD does not do that, even if the
array elements are all of type VT_R8.
Using OLEVariant to denote the ooRexx array to be converted to VT_ARRAY/VT_R8 did not work in ooRexx
as ooRexx always created VT_ARRAY/VT_VARIANT arrays: cf.
<https://sourceforge.net/p/oorexx/bugs/1821/>, fixed with [r12425]. Here a code snippet that does
not work for AutoCAD:
myApp = .oleobject~new("AutoCAD.Application")
myApp~visible = .true -- show window
myActiveDoc = myApp~ActiveDocument
space = myActiveDoc~ModelSpace
center=(100,200,300) -- ooRexx array, turned into VT_ARRAY,VT_VARIANT by
default
radius=50
res=space~addCircle(center,radius)
myApp~ZoomExtents
myApp~quit
Running the above in a rexxtry.rex session will yield the error:
........................................... rexxtry.rex on WindowsNT
res=space~addCircle(center,radius)
Oooops ! ... try again. OLE error.
OLE exception: Code: 80070057 Source: unavailable
Description: unavailable (80070057 "The parameter is incorect.").
rc = 92.906 ............................... rexxtry.rex on WindowsNT
Unfortunately, AutoCAD does not report more!
---
With the mentioned fix (included in latest build of ooRexx 5.0) one can now use an OLEVariant to
force the creation of the needed VT_ARRAY/VT_R8 array:
myApp = .oleobject~new("AutoCAD.Application")
myApp~visible = .true -- show window
myActiveDoc = myApp~ActiveDocument
space = myActiveDoc~ModelSpace
center=(100,200,300) -- ooRexx array, turned into VT_ARRAY,VT_VARIANT by
default
*ovCenter = .oleVariant~new(center,"VT_ARRAY,VT_R8") -- explicit: creaete
VT_ARRAY,VT_R8*
radius=50
res=space~addCircle(*ovCenter*,radius)
myApp~ZoomExtents
myApp~quit
In the case that one needs to change the center point later on, one could change the ooRexx array
"center" but supply the OLEVariant instance "ovCenter" as argument to AutoCAD. The conversion from
an ooRexx array to VT_ARRAY,VT_R8 will then be carried out with the current data in the ooRexx array.
---
Although the problem surfaced with AutoCAD it makes a nice example of how to solve it easily, now
that OLEVariant typed VT_ARRAYs get honored. So in the unlikely case, that other Windows
applications report wrong COM/OLE datatypes ooRexx has to rely on, one can fix the problem.
HTH,
---rony
[1] VARENUM enumeration (wtypes.h):
<https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-varenum>
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel