Using Delphi 3 to write AutoCAD R14 Automation Clients

Here's an example which draws a circle using late binding

When using Late binding with the initial release of R14, you must use the VarArrayRef() function to pass a variant array when AutoCAD requires an array of 3 doubles (a 3D coordinate). In R14.01, you do not need to use VarArrayRef(), and you can just pass the variant array instead.

var
  Acad, Circle, vPoint, Mspace : OleVariant;
begin

  // Create the point array and assign values to it
  vPoint := VarArrayCreate([0,2], VT_R8);
  vPoint[0] := 2.0; vPoint[1] := 4.0; vPoint[2] := 0.0;

  // Get the AutoCAD application object
  Acad := GetActiveOleObject('AutoCAD.Application.14');

  // Get the ActiveDocument's model space object
  Mspace := Acad.ActiveDocument.Modelspace;

  // call the AddCircle() method to create the
  // circle with a radius of 10 units:

  Circle := Mspace.AddCircle(VarArrayRef(vPoint), 10.0);  // R14.00 only

  Circle := Mspace.AddCircle(Vpoint, 10.0);                // R14.01 only

  // Update the circle
  Circle.Update;

end;

Using early binding is a bit more complicated. Delphi has a bug that incorrectly declares SafeArray's as OleVariants in the imported type library (and generates a warning for each, but even the warning is incorrect - these parameters must be declared as const PSafearray (a constant pointer to a TSafeArray). So, for the AddCircle() method used in the above example, this would be the correct declaration that must appear in AutoCAD_TLB.pas:

function AddCircle(const center: PSafeArray; radius: Double): IDispatch; safecall;

Assuming you correct the declaration to read like the above, to use Early binding you must pass the safearray pointer. You can use this helper function to convert a variant array to a PSafeArray:

Function SafeArrayRef(V : OleVariant): PSafeArray;
begin
  Result := PSafeArray(TVarData(V).VArray);|
end;

Here is the same example from above, only using early binding:

var
  Acad, vPoint: OleVariant;
  Mspace : IAcadModelSpace;
  Circle : IAcadCircle;
begin
  vPoint := VarArrayCreate([0,2], VT_R8);
  vPoint[0] := 2.0; vPoint[1] := 4.0; vPoint[2] := 0.0;
  Acad := GetActiveOleObject('AutoCAD.Application.14');
  Mspace := IDispatch(Acad.ActiveDocument.ModelSpace) as IAcadModelspace;
  Circle := IDispatch(Mspace.AddCircle(SafeArrayRef(vPoint), 10.0)) as IAcadCircle;
  Circle.Update;
end;