AfraLISP - Learn AutoLISP for AutoCAD productivity

Hiding Dialog Boxes Revisited - Part 1

by Kenny Ramage

Ladies and Gentlemen "WASSUP"

Hee, hee - I've always wanted to do that.

Probably the most vexing (on my part) query I get, is in regards to hiding dialog boxes. It seems to take ages and numerous emails before the poor soul trying to grasp the concept finally understands the principle, or (and this is more likely) gives up and joins a monastery/nunnery. So, without further due, and absolutely no regard for my own safety, I'm going to have another shot at explaining how to go about hiding such a wee delicate thing as a dialog box.

Okay, are you ready? Are you sat nice and comfy on your cuddly, wuddly little bottom? Then let's do it! ("Randall, could you please keep the noise down 'cos I'm trying to explain something here. What? You're eating! Try and use a knife and and fork - I know it's chicken and you're allowed to use your fingers, but you're supposed to cook the thing and remove the feathers first.")

On to the more serious bit…

Often you need to make a selection on the screen whilst a dialog box is active. But to do this, you need to be able to hide the dialog box to allow the user to make a selection from the screen. You must then restore the dialog box, along with the values that the user has selected. To accomplish this lets first have a look at two of the most critical DCL functions :

(done_dialog [status])
  • status : A positive integer that (start_dialog) will return instead of returning 1 for OK or 0 for Cancel. The meaning of any status value greater than 1 is determined by your application.
  • Usage Notes : An explicit AutoLISP action for the "accept" button must specify a status of 1 (or an application-defined value); otherwise, (start_dialog) returns the default value, 0, which makes it appear as if the dialog box was canceled.
  • Return Values : The (start_dialog) function returns the optional status passed to (done_dialog). The default value is 1 if the user presses OK, 0 if the user presses Cancel, or -1 if all dialog boxes are terminated with (term_dialog). If (done_dialog) is passed an integer status greater than 1, (start_dialog) returns this value, whose meaning is determined by the application.

What the heck does all this mean?

When you want to close a dialog, you call the (done_dialog) function. But did you know that when you call the (done_dialog) function a status argument is returned? Well it's true!

Now think about this. When (done_dialog) is called from a tile who's key is ‘cancel’ (the Cancel button), it returns a status of 0. If a tile who's key is ‘accept’ is chosen (the OK button), it will return a status value of 1. Note carefully, YOU must define a status of 1. Now here's the important bit, if you use the (done_dialog) function along with a status value of say 4, you know that the dialog box has been hidden and not ended or cancelled. But how do I retrieve that status value? Easy, when you call (start_dialog), it returns the (done_dialog) status value.

(setq flag (start_dialogue))

By testing this value in a (while) loop we can determine whether the dialog was simply hidden or accepted or cancelled. Below is a sample routine that should, hopefully, I hope and pray, explain it to you a lot better. This routine simply displays a dialog box with three buttons. If you select "OK" or "Cancel", an alert box is displayed and the dialog is simply closed. But, if you click the "Select Object" button, the dialog is hidden and an alert box is displayed informing you of the fact. After selecting OK, the dialog is re-displayed or, to use the words of a great magician that I once knew, ‘un-hidden’.

Hide Dialog

First the DCL Coding :

hidedialog1 : dialog {
	label = "Hide Dialogue";
	: button {
	label = "Hide Dialog >>";
	key = "hide";
	width = 8;
	fixed_width = true;
	mnemonic = "H";
                alignment = centered;
                is_default = true;
	: spacer { width = 1;}

Save this as HideDialog1.dcl

And now the AutoLISP coding. Save this as HideDialog1.lsp :

(defun c:hidedialog1 ( / dcl_id flag)
  ;set flag to 4
  (setq flag 4)
  ;load the DCL file
  (setq dcl_id (load_dialog "hidedialog1.dcl"))
  ;check the flag status and carry on looping
  ;if it is greater than 2
  (while (> flag 2)
  ;load the dialog box
  (if (not (new_dialog "hidedialog1" dcl_id))
    ;if not loaded exit
  ;Note: I have explicitly defined the status 
  ;return value for the "cancel" "accept" and "hide"
  ;tiles. I recommend you do the same.
  ;if Cancel button selected, close
  ;the dialog. This action sets the
  ;flag to 0.
  (action_tile "cancel" "(done_dialog 0)")
  ;if OK button was selected, close
  ; the dialog. This action
  ;sets the flag to 1.
  (action_tile "accept" "(done_dialog 1)")
  ;if pick button selected, hide the dialog
  ;and set the flag to 4
  (action_tile "hide" "(done_dialog 4)")
  ;start the dialog and set flag
  ;to value of start dialog
  (setq flag (start_dialog))
  ;if the OK button was selected
  (if (= flag 1) (alert "You chose the OK button"))
  ;if the Cancel button was selected
  (if (= flag 0) (alert "You chose the Cancel button"))
  ;if the pick button was selected
  (if (= flag 4) (alert "You chose the Hide Dialog button"))
  ;unload the dialog
  (unload_dialog dcl_id)
(princ);load clean

Let's now get really brave and in Part 2 we'll have a look at a wee practical example…