AfraLISP - Learn AutoLISP for AutoCAD productivity

Getting Started with DCL - Part 1

by Kenny Ramage

Dialog Control Language, or DCL, always seems to frighten off a lot of Lispers. I admit, it did me too until I was forced into a situation were I had to learn it and quickly. (make it work, or you're out boy!)

Well, I would hate for any of you to be in the same situation, so for the next few issues, I'll be taking you step by step, hand in hand, through the minefield of the DCL language. I will share your pain and misery, and will wipe away your tears, I will… ("Hey Kenny, get on with it!"). Oops, sorry!

Anyway, where was I? Oh yeah, I will suffer… (thump!).
As I was saying before I got this black eye, there are a few terms that you need to familiarise yourself with before we get stuck into some coding. Firstly, the dialog box itself is known as a "dialog definition". Secondly, each "control" on the dialog is known as a "tile definition". Thirdly, each "property" of a "tile" is known as a dialog "attribute". And fourthly, each "method" of a "tile" is known as an "action expression". Why? Who knows? Who cares? All I know is that it will help you immensely in understanding the AutoCAD DCL reference book if you have a basic knowledge of these terms. Right, enough waffle, I'm bored and my eye's sore. Let's have a look at some DCL coding and design ourselves a simple dialog box.

Copy and paste this into Notepad and save it as test_dcl1.dcl. Oh, before I forget, please ensure that you save this file, and it's namesake AutoLisp file, into a directory that is within your AutoCAD search path.

//DCL CODING STARTS HERE
test_dcl1
 
: dialog
 
{
label = "Test Dialog No 1";
 
	: text
	{
	label = "This is a Test Message";
	alignment = centered;
	}
 
	: button
	{
	key = "accept";
	label = "Close";
	is_default = true;
	fixed_width = true;
	alignment = centered;
	}
 
}
//DCL CODING ENDS HERE

We'll have a closer look at what this all means a bit later. First, let's load some AutoLisp coding and try out our new dialog box. Copy and paste this into Notepad and save it as test_dcl1.lsp.

;AUTOLISP CODING STARTS HERE
(prompt "\nType TEST_DCL1 to run...")
 
(defun C:TEST_DCL1 ()
 
(setq dcl_id (load_dialog "test_dcl1.dcl"))
 
     (if (not (new_dialog "test_dcl1" dcl_id))
	 (exit )
     );if
 
(action_tile "accept"
    "(done_dialog)"
);action_tile
 
(start_dialog)
(unload_dialog dcl_id)
 
(princ)
 
);defun
(princ)
;AUTOLISP CODING ENDS HERE

Now load and run your program.

the DCL dialog box

A very simple dialog box containing a message should appear on your screen. It did? Good, well done!! (thunderous applause from the peanut gallery.)

Right, let's dissect the DCL coding. (theme music from an old Dracula movie starts in the background.)

//DCL CODING STARTS HERE
Anything starting with "//" in DCL is regarded as a comment.

test_dcl1
The name of the dialog.

: dialog
The start of the dialog definition.

{
The opening bracket for the dialog definition.

label = "Test Dialog No 1";
The Label of the dialog definition.
This is what appears in the title bar of the dialog.

: text
The start of a text tile definition.

{
The opening bracket for the text tile definition.

label = "This is a Test Message";
The label attribute of the text tile.

alignment = centered;
The alignment attribute of the text tile.

}
The closing bracket of the text tile.

: button
The start of a button tile definition.

{
The opening bracket for the button tile definition.

key = "accept";
The key, or name of the button tile.
You will use this name to reference this button in your AutoLisp coding.

label = "Close";
The label attribute. What appears on it.

is_default = true;
The default attribute. If this is true, this button will automatically be selected if the <Enter> key is pressed.

fixed_width = true;
Forces the button to be just large enough for the label attribute.

alignment = centered;
The alignment attribute.

}
The closing bracket for the button tile.

}
The closing bracket for the dialog definition.

OK, that was easy hey? By the way, did you notice that each of the attribute lines finished with a semicolon(;)?

Another important thing that you must remember when dealing with attributes is that their values are case sensitive. (e.g. "True" does not equal "true".)

Now let's have a wee look at the AutoLisp coding that puts this whole thing together. Again, we'll take it line by line :

(prompt "\nType TEST_DCL1 to run...") Inform the user how to start the program. Just good manners.

(defun C:TEST_DCL1 (/ dcl_id)
Define the function and declare variables.

(setq dcl_id (load_dialog "test_dcl1.dcl"))
Load the dialog file and set a reference to it.

(if (not (new_dialog "test_dcl1" dcl_id))
Load the dialog definition and check for it's existence.
Remember, a dialogue file can hold various dialogue definitions.

(exit)
Exit the program if the dialog definition is not found.

);if
End if

(action_tile "accept"
If the user selects the tile who's name is "accept", then do the following :

"(done_dialog)"
Close the dialog

);action_tile End of action_tile

(start_dialog)
Start the dialog

(unload_dialog dcl_id)
Unload the dialog from memory

(princ)
finish clean

);defun
End of function

(princ)
Load clean

Many people get confused in regards to the order of AutoLisp statements when dealing with DCL files. I don't blame 'em really. I mean look at the coding above!

  • First we load the dialog file.
  • Then we load the dialog definition.
  • Then we run an action_tile statement.
  • Then we start the dialog.
  • And right after that, we unload the dialog.

Where's the logic in that?

Haha. But did you notice that the action_tile statement was quoted? e.g. "(done_dialog)".

In effect, what we are telling the tile is this:
"Remember this string, then pass it back to me when the user activates you.". "So, in other words, coding is pre-stored within a particular tile. When I select that tile the coding runs?"

Yep, that's it. But remember, no values will be returned until (done_dialog) is called, which is also quoted. So, the sequence is like this :

  • First we load the dialog file.
  • Then we load the dialog definition.
  • Then we run AND REMEMBER all theaction_tile statements.
  • Then we start the dialog.
  • The dialog is displayed.
  • Any action_tile statement is processed IF the relevant tile is selected.

When a tile that contains the (done_dialog) function is selected, we unload the dialog and return all tile values.

And that's it. Easy hey?

In Part 2, we'll have a look at some predefined tiles, how to enter and retrieve values from a dialog, and how to validate these values.