Lesson 6 -- Writing the Interface

Now that we have a game plan we can start writing some code.

Macro Skeleton

Lets start with the portions of the program that must exist. In every macro you write you must have a certain minimum amount of code in order to compile the macro. We will call this minimum code the Macro Skeleton. For more information on the parts of the macro code refer to Lesson 2 Building on the Basics.

Here is the basic Macro Skeleton

ex6-1.jpg (22562 bytes)
figure 6-1 Macro Skeleton

Notice that the Skeleton begins with a comment. It cannot be stressed enough how important comments are to your source code. Without good comments your code will make no sense when you come back to it at a later date. What seems perfectly clear when written will be less than obvious in a matter of days. Use good comments.

Our comment here is a good one to start all your source code listings with. It simply states the macro name, purpose, author and date. If the macro is subsequently revised you would add notes below this block to explain the revision and perhaps the date of the revision.

The next (and first line of 'real' code) is the PROGRAM declaration. This line tells the compiler that this is a a Program as opposed to a Module and it is named rename. I also like to put a comment here listing the name of the source code file, in this case {rename.dcs}

Finally our Skeleton ends with the END declaration that matches up with the PROGRAMMING declaration at the start of the code. Notice that the final END in the Program (or Module) is followed by a period.

While this Skeleton doesn't really do anything it can be compiled and run.

If this isn't clear to you review Lesson 2 Building on the Basics

Interface Code

Now that we have a basic skeleton we can begin to add some code to do the work.

 ex6-2.gif (39343 bytes)
figure 6-2 Our Interface Code

We have now added our code to display an interface to the user. In DataCAD, and thus DCAL, the interface is normally the function keys. The PROCEDURE mainMenu has been added to display our function keys when the macro is run. This procedure runs from lines 16 thru 60. Notice that we have also added a BEGIN statement just before the end of the program. This BEGIN is the main macro BEGIN and tells DataCAD where to begin executing the macro code. In our case we tell DataCAD to start by running mainMenu.

We start mainMenu by declaring it on line 16. Next we declare the VARIABLES that we will use. Notice the searchString and replaceString variables and their type. These two string variables are declared as STR8. STR8 is a built-in DCAL type that is a string of 8 characters. Why do we use this type and not another? Simply because a layer name can not exceed 8 characters so this is all we will need. Give careful thought to the types of variables your program uses. Declaring variables larger than you need will make the program larger than it needs to be.

The code that does the work of this PROCEDURE follows the variable declarations . We begin with a BEGIN on line 24 (makes sense doesn't it?) This indicates that this is where the actual code of this PROCEDURE is to be executed from.

On line 25 we make sure that the variable done is set to false. Done is a BOOLEAN type variable that can be either true or false. The reason this variable is set to false will become more obvious as me move along.

Line 27 initiates a REPEAT loop. You should recall from Lesson 4 Flow Control that a REPEAT loop will be executed until it a specific condition is met. The REPEAT loop must be terminated with an UNTIL declaration. In our example we find the UNTIL on line 59. Our code says UNTIL done. This means repeat the code between REPEAT and UNTIL until done = true. You can say either done = true or simply done. Either way is correct. Note the the UNTIL declaration must be followed by an expression that can be evaluated to true or false. Now it should be obvious why we set done equal to false on line 25. We want to be sure that the loop is repeated until we set done = true. We will see where that happens in a second.

Within the REPEAT loop we will display our function keys. The reason this code is enclosed within a loop is so that the keys are not simply flashed and then discarded. We want to keep looping while we wait and process the users input.

Lines 28 and 29 simply display some information about the macro. The 'error line' is the 'Attention' toolbar. WRTERR simply displays a string on the Attention toolbar. The 'level area' is the DataCAD Menu Title. This area normally displays what menu or area of DataCAD you are presently in. It is a nice touch to use this to display the status of DataCAD while in your macro. We will use the WRTLVL routine to display 'rename' in the level area.

WRTERR: Attention Toolbar
WRTERR: Attention Toolbar

WRTLVL: DataCAD Menu Title
WRTLVL: DataCAD Menu Title

LBLSINIT on line 31 resets the function keys so that we may redefine them. You must do this before defining the function keys.

Next we define the function keys to display. On line 33 we use LBLSET to setup function key F1. Notice that we use the number 1 to define function key F1. We use the numbers 1-20 to define the 20 available function keys. As you will see later we use the built-in constants F1-F0 & S1-S0 to determine which key was pressed. This can be confusing to beginners so make a note of this. So we want F1 to read 'Search'

Line 34 works in conjunction with line 33. The LBLMSG procedure displays a message when the user places the cursor over the corresponding function key. Notice that we again use the number 1 to indicate this procedure is to be used with function key F1.

Lines 35 thru 39 setup the rest of the keys we will be using. Key F2 will read 'Replace.' Key S9 (notice the number 19 is used in this instance) will display 'Begin' and finally S0 will be 'Exit'

A note here about interface design. You have unlimited power when programming to do as you wish with the user interface. Such power should be used wisely. The best programs tend to be those that are intuitive. Users are conditioned to expect certain things from the DataCAD interface. One of these things users will take for granted is that Exit is always at S0. You should think long and hard about changing something like this and be prepared to defend your decision when users ask why you did so. Of similar importance is making the user comfortable. We did not have to use WRTERR, WRTLVL or LBLMSG to display information to the user. However it is a good practice to provide as much feedback and information as possible. Little details like this give your program some professional polish and go a long way towards making a program more user friendly.

On line 41 we turn on the newly defined function keys. We do this with a call to LBLSON. This routine displays all the keys we have setup with valid definitions since calling LBLSINIT.

Next we prompt the user with what we expect them to do. Line 43 displays our message on the message line. The message line is the bottom most line of the prompt area. WRTMSG displays the specified string in the message line.

WRTMSG: Message Toolbar
WRTMSG: Message Toolbar

Now that we have setup the interface we must wait for the user to do something. Remember that we are already in a loop so all we need to do is issue a command to get input form the user and the macro will repeat this command until some other part of our code breaks us out of the loop. In our macro we only need to allow the user to press a function key at this time, so we use GETESC to get a key from the user. Once the user has pressed a key we store the key pressed in a variable aptly named 'key.' Note that key is of type integer. All the keys on the keyboard are considered integers within DCAL.

Now that we have the users key we need to evaluate the key that was pressed. The loop that follows checks the key against conditions we want to work with. First we check if the key pressed was F1. Here is where we use the F1 constant that was described earlier. If you try to evaluate for key = 1 (using the syntax of LBLSET from above) your code will not work.

This portion of the code is where we start to do more detailed work. We have presented some options to the user and presumably the user has acted on one of our choices. The IF, THEN, ELSIF, END loop allows us to evaluate many possible conditions in one brief section of code. This whole process occurs between lines 48 and 58.

Within this IF THEN loop we only need to check for conditions we are interested in. Anything else will be ignored. So following our code here is what happens. First we check if the user pressed F1 (key = F1) if so we show the user a message again using WRTMSG. We ask them to input a search string. We then use GETSTR to wait until the user enters a valid string. Since we only need a maximum of 8 characters in this string we use the parameter 8 within the GETSTR call. The string the user gives us is stored in the variable searchString.

We continue checking by looking for the F2 key press in line 51. If the user pressed F2 we use the same technique described above to get our replacement string.

If the user selects S9 'Begin' then we call another procedure to do the work. This procedure is not yet written in our code but we will call it 'doit'. If you want to compile and run this portion of the code you must comment our line 55 or the compiler will complain that it does not know what doit is.

If the user pressed S0 'Exit' then we set done to true. You should recall that this will terminate the main loop in this procedure. All that is required is to set done = true and the program will remember this when it next comes to the UNTIL done line on line 59. At that time the macro will end.

Finally, our procedure ends on line 60 with an END declaration. Notice that this END is followed by the name of the procedure and a semi-colon. Remember that only Programs and Modules are ended with a period. The reason for this is the period tells the compiler there is no more code to read.

That might seem like a lot of materials to cover but this is the standard way of creating a user interface with DCAL. You will use this same code over and over when writing macros. It should become second nature after a while.

If you wish to see what you have accomplished thus far comment out line 55 (change it to read !doit;) and then compile and run the macro. You should see something like this

 Rename Macro Interface
figure 6-3 the completed interface

< Previous Lesson  |   Next Lesson >
DCAL Tutorial Contents