Creating Scripts

Introduction

TurboCAD v4 comes with a programmable CAD interface. Its built-in Cypress Enable -- Basic Scripting for Applications interpreter allows programmers to create scripts in Enable Basic that can access a wide variety of TurboCAD's functionality via the TurboCAD Application Interface Dynamic Link Library. Enable Basic supports a substantial subset of Microsoft Visual Basic so you do not have to learn another scripting language to program in TurboCAD v4.

You can create scripts using any text editor or word processor, then run the script directly from TurboCAD using the Menu:Tools|Run Scripts command. A built-in Enable Basic debugger is also provided (Menu:Options|Scripts and select Debug).

Scripts can be attached to a specific drawing through the Menu: Options|Scripts property sheet. You can also modify the TCW40.ini file to have your scripts made available on the Scripts toolbar for all your drawings.

This manual is aimed at those familiar with Basic or other programming languages. It is not a tutorial.

System Requirements

To run TurboCAD v4, your computer system needs to meet the following minimum requirements:

Getting Started

"Hello World"
Anyone who programs has probably written the classic ``hello world'' Basic program. Maybe you wrote it in C. Even if you haven't written a program that prints ``hello world'', you can write that functionality in TurboCAD v4.

'Hello World in TurboCAD
Sub Main()
		Dim hDrawing As Long
		Dim hGraphic As Long
		Dim Result As Long
		Dim e As String
		'Must have a drawing active
		hDrawing = TCWDrawingActive()
		If (hDrawing = 0) Then
			TCWLastErrorGet(e)
			MsgBox e
			Stop
		End If
		'Create a graphic that has the text "hello world"  
		'TCWText takes 6 parameters: X, Y, Z, string, font size, and
		'angle to print text
		hGraphic = TCWText(2#, 2#, 0#, "Hello World!", .5, 0#)
		'hGraphic should how have a handle to our text graphic
		If (hGraphic = 0) Then
			TCWLastErrorGet(e)	
			MsgBox e
			Stop
		End If
End Sub

Save the file as hworld.bas (text format). Then launch TurboCAD v4, select Menu:Tools|Run Scripts... and select hworld.bas.

Now we've written our first sample program and run it in TurboCAD v4. Let's look at the parts of our script and explain some of the basics about programming in TurboCAD v4.

TurboCAD v4 Script Basics

There are a couple of issues you need to be aware of when writing scripts for TurboCAD v4.

Calling Functions in TCADAPI

Tcwapi40.h and Tcwapi40.app define the programming interface to TurboCAD. Tcwapi40.h includes all the function declarations to Tcapi40.DLL, while Tcwapi40.app has several TurboCAD functions written in Enable Basic.

Enable Basic includes built-in functions as well (e.g. MsgBox, Cos, Strcomp). You can also call Windows API functions from your Basic script. Just add a Declare statement for the function call.

Cypress Enable Basic does not verify that you have passed the correct number of parameters or the correct values for the parameters when calling TCADAPI or any other DLL. It is the programmer's responsibility to ensure that functions are called correctly.

Error Checking

Check return values and use TCWLastErrorGet when you don't get the expected result. This will make your programs more robust.

Scripting Requires a Drawing to be Active

You must have a drawing active within the program to run a script. Many of the API functions interact with a drawing, hence the requirement. You can create a new drawing, open an existing drawing or just access the current active drawing in TurboCAD.

In our ``Hello World'' example, we use the currently active drawing:

Hello World in TurboCAD
Sub Main()

Dim hDrawing As Long Dim Result As Long Dim e As String 'Must have a drawing active hDrawing = TCWDrawingActive() If (hDrawing = 0) Then TCWLastErrorGet(e) MsgBox e Stop End If

TCWDrawingActive will return the handle of the active drawing. If no drawing is active (all drawings are closed), then hDrawing will be NULL. Here we have used the API TCWLastErrorGet to retrieve the error string and display our error.

Graphics Usually Get Added to the Drawing

All graphic creation functions that are named after the graphic types they create ( e.g. TCWText, TCWCircleCenterAndPoint, TCWDimensionHorizontalEntity) are added to the drawing. You do not have to do any additional work to include the graphic in your drawing.

TCADAPI provides another method of creating graphics: TCWGraphicCreate will create a graphic but will not add the graphic to the drawing. You must do this yourself. This function gives you more control over how you construct graphics. TCWGraphicCreate will be discussed in a later chapter of the manual.

Our ``hello world'' script example will create a text graphic with our ``Hello World!'' string. Our graphic will be added to the active drawing automatically. If TurboCAD couldn't make the graphic (e.g. no memory), TCWText will return a NULL handle for our graphic. In this case, we call TCWLastErrorGet to see the error result.

		'Create a graphic that has the text "hello world"  
		'TCWText takes 6 parameters: X, Y, Z, string, font size, and
		'angle to print text in radians
		hGraphic = TCWText(2#, 2#, 0#, "Hello World!", .5, 0#)
		'hGraphic should how have a handle to our text graphic
		If (hGraphic = 0) Then
			TCWLastErrorGet(e)	
			MsgBox e
			Stop
		End If

TCADAPI Get and Set Properties Functions

The following TCADAPI functions are coded in Basic to get around limitations with Variants in DLLs with Enable Basic:

		TCWAppPropertyGet, TCWAppPropertySet
		TCWDrawingPropertyGet, TCWDrawingPropertySet
		TCWGraphicPropertyGet, TCWGraphicPropertySet
		TCWLayerPropertyGet, TCWLayerPropertySet

You must call these functions with function calling syntax:

result = TCWGraphicPropertySet(g, ``PenColor'', &HFFFFFF)

and not as a subroutine. Enable Basic will report an error if you call these functions as subroutines. See the section on Writing TurboCAD v4 Scripts for the difference between calling subroutines and functions.

Writing TurboCAD v4 Scripts

Basic Subroutine and Function Calls

Basic programs are made up of two different types of components: subroutines and functions. You can use subroutines and functions to divide your program into more manageable pieces.

There are several fundamental differences between a subroutine and a function:

While calling a function that takes two parameters and returns a result looks like this:

			result = atan2(dx, dy)

You must use parentheses around the arguments being passed to a function.

Running TurboCAD v4 Scripts

Menu:Tools|Run Scripts does the following:

The same steps occur when you run a script from the Scripts property sheet or Scripts Toolbar as well. Debugging TurboCAD v4 scripts will be discussed in a later section of this manual.

Overview of TurboCAD Application Interface

The TurboCAD Application Interface has been grouped into the following functional areas:

Application Functions

Application functions allow you to do the following:

Accessing Your Open Drawings

With two TCADAPI functions, you can cycle through your open drawings. TCWDrawingCount will return the number of drawings currently open in TurboCAD v4. You can then use TCWDrawingAt(index) to access each drawing. The index is 0 based, so you can cycle through 0 to count -1 drawings. For example, the following Basic script will cycle through all your open drawings and add the name of the drawing to the location specified. This script uses the following TCADAPI functions:

			TCWDrawingCount, TCWDrawingAt, TCWDrawingName

Here's the script:

'Program to loop through open drawings and add drawing name 
      Dim x As Long

Dim y As Long Dim angle As Double Sub Main() Dim dCount as Long Dim hDrawing as Long Dim i As Long Dim dName as Long 'Get count of number of drawings open dCount = TCWDrawingCount() If (dCount = 0) Then MsgBox "No drawings open" Stop End If 'Loop through open drawings For i = 0 to dCount -1 'activate drawing "i" hDrawing = TCWDrawingAt(i) 'Get drawing name TCWDrawingName dName 'Prompt for location and angle of text MyDialog 'Calculate angle in radians for text angle = angle * 3.14159265359 angle = angle / 180 'Write the name on the drawing TCWText x, y, 0.0, dName, .2, angle Next i End Sub Sub MyDialog() Begin Dialog MyUI 60, 60, 240, 105, "Add Drawing Name" Text 10, 10, 150, 10, "X Coordinate for name:" TextBox 120, 10, 110, 10, .x Text 10, 20, 150, 10, "Y Coordinate for name:" TextBox 120, 20, 110, 10, .y Text 10, 30, 150, 10, "Angle to print text (in degrees):" TextBox 120, 30, 110, 10, .angle OKbutton 80, 50, 40, 12 CancelButton 120, 50, 40, 12 End Dialog Dim Dlg1 As MyUI Dlg1.x = 0.0 Dlg1.y = 0.0 Dlg1.angle = 90.0 button = Dialog(Dlg1) if button = 0 then END elseif button = -1 then x = Dlg1.x y = Dlg1.y angle = Dlg1.angle end if End Sub

Drawing Functions

Drawing functions allow you to do the following:

File Input and Output Functions

These functions are for reading and writing to and from text files. See the example on Exporting Vertex Data for writing to a file. Details of file input and output can be found in the TCADAPI reference section.

You can also use Automation to read from Microsoft Excel spreadsheets or Word documents. All this and more can be found in the examples and references sections in this manual.

Graphic Functions

Graphic functions allow you to:

Here is the MakeObject subroutine from padwiz.bas that shows how to set graphic properties for the graphics created. This subroutine uses the following TCADAPI functions:

TCWCircleCenterAndPoint, TCWLineRectangle, TCWGraphicPropertySet

Here's the subroutine of padwiz.bas:

Sub MakeObject(ByVal x As Double, ByVal y As Double)
	Dim gP As Long
	Dim g1 As Long
	Dim g2 As Long
	Dim r As Double
	r = PadSize / 2#
	If PadShape = 0 Then
		g1 = TCWCircleCenterAndPoint(x, y, 0#, x - 2 * r, y, 0#)
	Else
		' Create the empty rectangle graphic
		g1 = TCWLineRectangle(x - r, y - r, 0#, x + r, y + r, 0#)
	End If
	' Color is set as R, G, B - this is black
	Result = TCWGraphicPropertySet(g1, "PenColor", &H0)
	' Fill Pattern is a style. We know that style 1 is always solid
	Result = TCWGraphicPropertySet(g1, "BrushStyle", BrushSolid)
	' Add the black background of the pad to the pad group
	' Make the hole 1/3 of the size of the pad unless it is smaller
	' then a minimum, in which case it is set to that minimum
	r = PadSize / 6#
	If r > 0.0625 Then
		r = 0.0625
	End If
	If PadShape = 0 Then
		' Create the empty arc graphic
		g2 = TCWCircleCenterAndPoint(x, y, 0#, x - 2 * r, y, 0#)
	Else
		' Create the empty rectangle graphic
		g2 = TCWLineRectangle(x - r, y - r, 0#, x + r, y + r, 0#)
	End If
	' Color is set as R, G, B - this is white
	Result = TCWGraphicPropertySet(g2, "PenColor", &HFFFFFF)
	' Fill Pattern is a style. We know that style 1 is always solid
	Result = TCWGraphicPropertySet(g2, "BrushStyle", BrushSolid)
End Sub

Layer Functions

You can create new layers, delete existing layers, get the layer count and access all layers in your drawing. You can also get and set layer properties, such as read-only, line style, color and name. The following program will cycle through the layers of a drawing and display the layers ID and name. Layer.bas uses the following TCADAPI functions:

TCWDrawingOpen, TCWLayersCount, TCWLayersAt, TCWLayerPropertyGet
Here's the program:

'Program to get the id and name of each layer in the drawing
Sub Main()
	Dim dActive As Long
	Dim hDrawing As Long
	Dim count As Long
	Dim i As Long
	Dim LayerID As Long
	Dim LayVar As String
	Dim Result As Variant
	hDrawing = TCWDrawingOpen("c:\imsi\tcw40\Samples\mouse.tcw")
	count = TCWLayersCount()
	i = 1
	LayVar = "Name"
	Do While (i <> count)
		LayerID = TCWLayersAt(i)
		Msgbox LayerID
		Result = TCWLayerPropertyGet(LayerID, LayVar)
		MsgBox Result
		i = i + 1
	Loop
	MsgBox "Finished"
End Sub

Screen Functions

TCWGetPoint accepts mouse clicks from the user and returns the X and Y coordinates of that mouse click in the vertex that you supply as an input parameter. This function can then be used with TCWVertexFindVertex or TCWVertexFindGraphic to get the handle of the vertex or graphic that is nearest to the mouse click.

Vertex Functions

Vertex functions allow you to:

View Functions

View functions allow you to zoom in and out and get the extents of your current view. If you have multiple views, you can get the count and cycle through each view with TCWViewCount and TCWViewAt.

Programming Examples

All the Enable Basic programs that are in this section can be found in the Scripts folder
(\IMSI\TCW40\Scripts) that comes with TurboCAD v4.

Calculator Example

This example shows how you can use TCWBasicRun to execute a basic statement.

Calculator.bas

sub main()
	Title$ = "TCAPI Calculator"
	Prompt$ = "Enter a valid Enable Basic numeric expression. (e.g. " 
	& Chr(34) & "sqr(47) / 2" & Chr(34)
	Default$ = ""
	E$ = InputBox$(Prompt$, Title$, Default$)
	If E$ <> "" Then
		TCWBasicRun "A# = " & E$ & Chr(10) & "MsgBox A#"
	End If
end sub

The expression you type into the input box will be encapsulated into a new basic program, compiled and then executed. Execution by the calling script will proceed when TCWBasicRun returns.

You can also specify the name of another script as the parameter to TCWBasicRun. Now you can put commonly used subroutines and functions into files, and call them from your script, instead of copying and pasting the procedures into each of your scripts.

TCWBasicDebug just like TCWBasicRun except that it will start up the Enable Debugger so that you can step through the script.

Exporting Vertex Data Example

The following example will show you how to cycle through selected graphics in a drawing, retrieve their vertices, extract the X, Y, and Z coordinates from the vertices, and write that data to a file. Expoint.bas uses the following TCADAPI functions:

TCWDrawingActive, TCWSelectionCount, TCWSelectionAt, TCWOpenOutput, TCW-
WriteOutput, TCWCloseOutput, TCWGraphicPropertyGet, TCWVertexCount,
TCWVertexAt, TCWGetX, TCWGetY, TCWGetZ

Here's the program:

Expoint.bas

Global Const GK_GRAPHIC = 11
Global Const NULL 		= 0
Sub Main ()
	Dim FileName As String
	Dim myLine As String 
	Dim g As Long
	Dim v As Long
	Dim vi As Long
	Dim vCount As Long
	Dim gCount As Long
	Dim i As Long
	Dim fh As Long
	Dim dActive As Long
	' Check for valid drawing
	dActive = TCWDrawingActive ()
	If dActive = NULL Then
		MsgBox "Program requires active drawing"
		' Terminate the program
		Stop
	End If
	' Get the name of the output file.
	FileName = InputBox("Type in the filename to export to")
	If FileName <> "" Then
		gCount = TCWSelectionCount()	    
		If (gCount = 0) Then
			MsgBox "Need to have at least one graphic selected"
			Stop
		End If
		' Open the output text file.
		fh = TCWOpenOutput(FileName)
		' Walk through the selected graphics and pick only
		' GK_GRAPHICS.
		for i = 0 to gCount - 1
			g = TCWSelectionAt(i)
			If TCWGraphicPropertyGet(g, "Kind") = GK_GRAPHIC Then
				If vi > 0 Then
					' Place a blank line after the previous graphic
						TCWWriteOutput fh, ""
				End If
				vCount = TCWVertexCount(g)
				' Iterate through the vertices of the graphic g.
				for vi = 0 to vCount - 1
					v = TCWVertexAt(g, vi)
					' Write the coordinates of vertex v into the string Line.
					' The delimiter for numeric fields is chr(9) character.
					myLine = Str$(vi) & chr$(9) & Str$(TCWGetX(v)) & chr$(9) & _ 
					Str$(TCWGetY(v)) & chr$(9) & Str$(TCWGetZ(v))
					TCWWriteOutput fh, myLine
				next vi
			End If
		next i
		TCWCloseOutput fh
	End If
End Sub

Importing Vertex Data Example

Here is the other side of the program. We will import vertex data from the file we created with Expoint.bas and redraw our graphics. Impoint.bas uses the following TCADAPI functions:

TCWDrawingActive, TCWOpenInput, TCWReadInput, TCWCloseInput, 
TCWGraphicCreate, TCWGraphicAppend, TCWGraphicXYZAdd, TCWGraphicDraw

Here's the script

Impoint.bas:

' This sample program is an example of how to do custom file IO from
' TurboCAD. We will build graphics from the vertices in the table.
'Constants
Global Const GK_GRAPHIC = 11
Global Const NULL 		= 0
' File I/O constants
Global Const EOFILE     = -1
Sub Main ()
	Dim FileName As String
	Dim LineBuffer As String
	Dim g As Long
	Dim v As Long
	Dim vi As Long
	Dim fh As Long
	Dim dActive As Long
	Dim x As Double
	Dim y As Double
	Dim z As Double
	Dim Part As String 
	Dim PartX As String
	Dim PartY As String
	Dim PartZ As String
	Dim Delim As String
	Dim Pos As Integer
	' Check for valid drawing
	dActive	= TCWDrawingActive ()
	If dActive = NULL Then
		MsgBox "Program requires active drawing."
		' Terminate the program
		Stop
	End If
	vi = 0
	g = NULL
	' Delimiter for record fields in the input text file (tab)
	Delim = Chr$(9)
	' Get the name of the input file
	FileName = InputBox("Type in the filename to import from")
	If (FileName <> "") Then	
		' Open input text file.
		fh = TCWOpenInput(FileName)
		' Read lines from the input file and break them down
		' to numeric values
		vi = 0 
		while (TCWReadInput(fh, LineBuffer) <> EOFILE)
			' Graphic separator
			if  LineBuffer = "" Then
				if ((g <> NULL) And (vi > 0)) Then
					TCWGraphicAppend NULL, g 
					TCWGraphicDraw g, 0           
					g = NULL
				End If 
				vi = 0
			End If
			if  (LineBuffer <> "") Then 
				' find the first delimiters position in Line
				Pos = InStr(1, LineBuffer, Delim, 0)
				' Let's remove the index part
				Part = Right$(LineBuffer, Len(LineBuffer) - Pos)
				' Let's find position of the second delimiter						
				Pos = InStr(1, Part, Delim, 0)
				' Let's extract the first number
				PartX = Left$(Part, Pos-1) 
				x = Val(PartX)
				Part = Right$(Part, Len(Part) - Pos)
				' Let's find the position of the third delimiter
				Pos = InStr(1, Part, Delim, 0)
				PartY = Left$(Part, Pos-1)
				y = Val(PartY)
				PartZ = Right$(Part, Len(Part) - Pos)
				z = Val(PartZ)
				' Add vertex (x, y, z) to the graphic g	
				If vi = 0 Then
					g = TCWGraphicCreate(GK_GRAPHIC, "")
				End If
				If g <> NULL Then   				
					TCWGraphicXYZAdd g, x, y, z 
				End If   
				vi = vi + 1 
			End If
		wend
		' If anything is left out we need to add to the drawing
		' now.
		if ((g <> NULL) And (vi > 0)) Then
			TCWGraphicAppend NULL, g
		End If
		TCWCloseInput fh
	End If
End Sub

Reading An Excel Spreadsheet

Here is a code fragment that shows you how to read data from a Microsoft Excel Spreadsheet. For this example we created an employee database with name, title, supervisor, phone extension and email address. These two procedures open the spreadsheet and then read the data from each cell.

Sub OpenOrgSheet()
	Dim xlFile  As String
	Dim shtNum  As Integer
	CurrentRow = 1
	CurrentCol = 1
	'CreateObject will create an instance of an Excel object
	Set xlApp = CreateObject("Excel.Application")
	'Open our Excel Spreadsheet file
	Set xlWbk = xlApp.Workbooks.Open("Org Chart Data.XLS")
	'Access our worksheet
	Set xlSht = xlWbk.Worksheets("Employee Database")
End Sub
Function GetNextOrgSheetValue() As Variant
	Dim RtnVal As String
	If FileLoaded <> 0 Then
		'Get the data in our cell 
		RtnVal = xlSht.Cells(CurrentRow, CurrentCol).Value
		CurrentCol = CurrentCol + 1
		'If the data returned is Null, then go to next row
		If RtnVal = "" Then
			CurrentCol = 1
			CurrentRow = CurrentRow + 1            
		End If
		GetNextOrgSheetValue = RtnVal
	Else
		GetNextOrgSheetValue = Null
	End If
End Function

Copying Text Along An Arc

This example will place text along an arc. Radcopy.bas uses the following TCADAPI functions to accomplish the task:

TCWDrawingActive, TCWSelectionCount, TCWSelectionAt, TCWGraphicPropertyGet, TCWGraphicPropertySet, TCWVertexAt, TCWDeselectAll, TCWGetX, 
TCWGetY, TCWUndoRecordStart, TCWUndoRecordEnd, TCWText

Radcopy.bas

'Sample that shows how to draw text along arcs
' Misc
Global Const NULL 	= 0
GLobal Const GK_ARC     = 2
sub Main
	Dim t As Long
	Dim gCount As Long
	Dim ga As Long
	Dim vCount As Long
	Dim vc As Long
	Dim vs As Long
	Dim ve As Long
	Dim strText As String
	dim g as Long
	dim i as integer
	dim x as double
	dim y as double
	dim angle as double
	dim angle2 as double
	dim r as double
	dim s as double
	dim pi as double
	dim l as long
	dim a as double
	dim c as string
	dim hActive as long
	dim gText As Long
	dim res As Long
	'Get drawing handle
	hActive = TCWDrawingActive()
	if (hActive = NULL) then
		MsgBox "Need active drawing."
		'Terminate Program
		Stop
	end if
	'Get selection count to see that we have 1 graphic selected
	gCount = TCWSelectionCount
	if (gCount = NULL) or (gCount <> 1) then
	    MsgBox "Program requires an arc (not circle) to be selected."
	    'Terminate the program
	    Stop
	end if
	'Get graphic handle for the selection
	ga = TCWSelectionAt(0)
	if (ga = NULL) then
		MsgBox "Program requires an arc (not circle) to be selected."
		' Terminate the program
	    Stop
	end if
	'Make sure we have an arc and not a circle
	if ((TCWGraphicPropertyGet(ga, "Kind") <> GK_ARC) or TCWGraphicPropertyGet(ga, "Closed")) then
		MsgBox "Program requires an arc (not circle) to be selected."
		' Terminate the program
		Stop
	End If
	vc = TCWVertexAt(ga,1)		' center of arc
	vs = TCWVertexAt(ga,2)		' start point of arc
	ve = TCWVertexAt(ga,3)		' end point of arc
	'Deselect the arc
	TCWDeselectAll
	'Text to put around the arc
	strText = "He who goes round in circles shall be known as a big wheel!"
	'Calculate the value of pi
	pi = atn(1)*4
	'Calculate the start angle
	angle = arctan((TCWGetY(vs)-TCWGetY(vc)),(TCWGetX(vs)-TCWGetX(vc)))
	'Calculate the end angle
	angle2 = arctan((TCWGetY(ve)-TCWGetY(vc)),(TCWGetX(ve)-TCWGetX(vc)))
	while (angle > angle2)
		angle2 = angle2 + pi*2
	wend
	'Calculate the radius of the arc
	r = sqr((TCWGetY(ve)-TCWGetY(vc))*(TCWGetY(ve)-TCWGetY(vc))  +   
		  (TCWGetX(ve)-TCWGetX(vc))*(TCWGetX(ve)-TCWGetX(vc)))
	' text character width = chord length / number of chars in string
	s = ((angle2-angle) * r) / len(strText)
	'Length of string
	l = len(strText)
	'Setup Undo Record for this copy, we don't need to add the text graphics to 
	'the undo record because TCADAPI will do that for us
	TCWUndoRecordStart hActive, "Radical Text Copy"
	'put the characters around the arc
	for i = 0 to l - 1
		a = angle + ((angle2 - angle)*i)/l
		x = TCWGetX(vc) + r * cos(a)
		y = TCWGetY(vc) + r * sin(a)
		c = mid(strText, l-i, 1)
		gText = TCWText(x, y, 0.0, c, s, (a - (pi/2)))
		res = TCWGraphicPropertySet(gText, "TextFont", "Arial")
	next i
	' End undo record
	TCWUndoRecordEnd hActive
End Sub
' Four quadrant ArcTan function written by a mathematically impaired programmer who did not want to
' leave anything to chance. (It will take dx and dy and deliver an angle between 0 and 2pi).
function arctan(ByVal dy As double, ByVal dx As Double) As Double
	Dim pi as Double	
	Dim a as double
	pi = atn(1)*4
	if (abs(dx) < 0.0001) then
		if (dy > 0) then
			a = pi/2
		else
			a = 3*pi/2
		end if
		a = abs(atn(dy/dx))
		if (dx < 0) then
			if (dy < 0) then  ' 3rd quad
				a = pi+a
			else			' 2nd quad
				a = pi-a
			end if
		else 
			if (dy < 0) then  ' 4th quad
				a = 2*pi-a
			else			' 1st quad
			end if
		end if
	end if
	arctan = a
end function

Linear Graphic Copy Example

Lincopy.bas will copy selected graphics based on number of copies and two mouse clicks that are entered by the user. This is similar to TurboCAD's Menu:Edit|Copy Entities|Linear. The script uses the following TCADAPI functions:

TCWDrawingActive, TCWVertexCreate, TCWGetPoint, TCWVertexDispose, TCWSelectionCount, TCWGetX, TCWGetY, TCWGetZ, TCWGraphicCount, TCWSelectionAt, 
TCWGraphicCopy, TCWGraphicAppend, TCWDeSelectAll, TCWGraphicAt, TCWGraphicPropertySet, TCWSelectionMove

Here's the program:

Lincopy.bas

'Sample that shows how to do a linear copy of selected graphics
' Misc
Global Const NULL 	= 0
dim v1 as long
dim v2 as long
dim copies as long
dim hActive as long
sub Main
	'Get drawing handle
	hActive = TCWDrawingActive()
	if (hActive = NULL) then
		MsgBox "Need active drawing."
		'Terminate Program
		Stop
	end if
	'Get number of copies from the user
	copies = Val(InputBox$("Input number of copies to make"))
	'create a vertex
	v1 = TCWVertexCreate(0.0, 0.0, 0.0)
	if (v1 = NULL) then
		MsgBox "Cannot create vertex"
		Stop
	end if
	v2 = TCWVertexCreate(0.0, 0.0, 0.0)
	if (V2 = NULL) then
		MsgBox "Cannot create vertex"
		Stop
	end if
	'click on screen to get points
	result = TCWGetPoint(v1,"Get first point", NULL, NULL, 0, 1)
	result = TCWGetPoint(v2,"Get second point", NULL, NULL, 0, 1)
	If copies = 0 Then
		MsgBox "No copies desired, finished!"	    
		Stop
	end if
	'Go and copy away
	DoCopy
	'Need to delete the two vertex objects that we created above
	TCWVertexDispose v1
	TCWVertexDispose v2
End Sub
Sub DoCopy ()
	Dim gCount As Long
	Dim sCount As Long
	Dim ga As Long
	dim g as Long
	dim i as integer
	dim j as integer
	dim result as long
	dim dx as double
	dim dy as double
	dim dz as double
	'Get selection count to see that we have something selected
	sCount = TCWSelectionCount
	if (sCount = NULL) then
	    MsgBox "Program requires at least one graphic to be selected."
	    'Terminate the program
	    Stop
	end if
	'Calculate the delta between the points for the copy
	dx = (TCWGetX(v2) - TCWGetX(v1))
	dy = (TCWGetY(v2) - TCWGetY(v1))
	dz = (TCWGetZ(v2) - TCWGetZ(v1))
	for i = 1 to copies
		'Get total graphics in drawing
		gCount = TCWGraphicCount(hActive)
		'loop through selected graphics making copies
		for j = 0 to sCount-1
			ga = TCWSelectionAt(j)
			if (ga = NULL) then
				MsgBox "Lost Selection?"
				Stop
			end if
			'make copy of selected graphic
			g = TCWGraphicCopy(ga)
			'add copy to the drawing
			result = TCWGraphicAppend(NULL, g)
		next j
		'Deselect the original graphics
	 	TCWDeSelectAll
		'Select the newly added graphics that we just copied
		'they will be at gCount+1...
		for j = 0 to sCount-1
			ga = TCWGraphicAt(hActive, gCount+j)
			if (ga = NULL) then
				MsgBox "Cannot find new copied graphic"
				stop
			end if
			'select the graphic
			result = TCWGraphicPropertySet(ga, "Selected", 1)
		next j
		'move the selection on the vector
		TCWSelectionMove dx, dy, dz
		'Select the newly added graphics that we just copied again,
		'TCWSelectionMove loses the selection state
		for j = 0 to sCount-1
			ga = TCWGraphicAt(hActive, gCount+j)
			if (ga = NULL) then
				MsgBox "Lost selection"
				stop
			end if
			'set selected
			result = TCWGraphicPropertySet(ga, "Selected", 1)
		next j
	next i
End Sub

Troubleshooting and Debugging Scripts

Adding Scripts to the Script Toolbar and Menu

You can attach scripts to TurboCAD v4, so that every time you run TurboCAD, you can get to your scripts easily and efficiently. All you need to do is edit the TCW40.ini file, locate [Script_Table], and add entries like the following:

[Script_Table]
rad_copy = c:\imsi\tcw40\Scripts\radcopy.bas

Obviously the script names will vary according to your requirements. The ``_'' in the name will be translated into a `` `` (Spaces are not allowed left of the ``='' in the INI file). TurboCAD will always load the scripts in the INI file first.

You can also attach scripts to a specific drawing or template. You attach scripts to a drawing or template through the Menu:Options|Scripts property page.

TurboCAD v4 Enable Basic Debugger

New to TurboCAD v4 is an embedded Enable Basic debugger. You launch the interactive debugger from Menu:Options|Scripts and click the Debug button. If you already have scripts attached to your drawing, then select the script you want to debug and then click Debug to launch the debugger.

You can use the debug source window to create scripts and then save them to a file. Find a mistake while debugging? Make changes to your script, recompile and continue testing. Save your changes along the way.

Features include single step(into or over), break points and go to execute your program. You can add your variables to the watch window and see their values as you step through the program.

Known Issues and Problems with Enable Basic

The following list includes known bugs at the time this manual was written.

Last Modified: 04:33pm , April 07, 1997