I've frequently heard how difficult or laborious dcl programming is and I just don't see it. While a dcl based dialog can't challenge one defined by a more modern application like Delphi or Visual BASIC, they're a snap to make
(and since they're plain text, can be written on the fly, though that's another discussion), particularly if you build sub assemblies to use in your dialog. Once you define sub assemblies the only thing, generally speaking, that varies from instance to instance is the key (and sometimes the label).
For example, in the dcl CAB authored it could be broken down like this (
this would all be in one file, but breaking it up like this for discussion makes it easier to digest):
General dcl settings //
// general dcl settings
//
dcl_settings : default_dcl_settings
{ audit_level = 3; }
Sub assembly definitions://
// sub assembly definitions
//
attribute_prompt : text {
value = "Attribute Prompt" ;
width = 30;
fixed_width = true;
}
attribute_value : edit_box {
edit_width = 34;
edit_limit = 200;
fixed_width = true;
}
attribute_state : image_button {
height = 1;
width = 2;
fixed_width = true;
fixed_height = true;
aspect_ratio = 1;
color = -15;
}
mybutton : button {
width = 12;
fixed_width = true;
}
Dialog definition://
// dialog definition
//
MyAttEdit : dialog {
label = " MyAttEdit by CAB v1.0";
: text {
value = "Block Name: My Block";
key = "txtblock";
width = 50;
}
: text {
value = "Page # ";
key = "page";
width = 10;
alignment = right;
}
spacer_1;
// use the sub assemblies we defined
: row {
: attribute_prompt { key = "txt1"; }
: attribute_value { key = "eb1"; }
: attribute_state { key = "im1"; }
}
: row {
: attribute_prompt { key = "txt2"; }
: attribute_value { key = "eb2"; }
: attribute_state { key = "im2"; }
}
: row {
: attribute_prompt { key = "txt3"; }
: attribute_value { key = "eb3"; }
: attribute_state { key = "im3"; }
}
: row {
: attribute_prompt { key = "txt4"; }
: attribute_value { key = "eb4"; }
: attribute_state { key = "im4"; }
}
: row {
: attribute_prompt { key = "txt5"; }
: attribute_value { key = "eb5"; }
: attribute_state { key = "im5"; }
}
: row {
: attribute_prompt { key = "txt6"; }
: attribute_value { key = "eb6"; }
: attribute_state { key = "im6"; }
}
: row {
: attribute_prompt { key = "txt7"; }
: attribute_value { key = "eb7"; }
: attribute_state { key = "im7"; }
}
: row {
: attribute_prompt { key = "txt8"; }
: attribute_value { key = "eb8"; }
: attribute_state { key = "im8"; }
}
spacer_1;
: row {
: mybutton { key = "ok"; label = "&OK"; }
: mybutton { key = "cancel"; label = "&Cancel"; is_cancel = true; }
: mybutton { key = "prev"; label = "&Previous"; }
: mybutton { key = "next"; label = "&Next"; }
: mybutton { key = "help"; label = "&Help"; }
}
}
This greatly speeds up dcl development, moreover, it makes maintenance a snap. Did ya note how I right aligned the key values for all the instanced sub assemblies? Makes it easy to assign and ensure the keys are correct (typically numerically incremented).
But more on maintenance ...
For example, if the
attribute_prompt sub assembly width is found to be too wide, the
width = 30; statement could be changed to
width = 25; and all 8 instances will reflect same. Really takes the chore out of maintenance and makes it a lot easier to achieve consistancy throughout a dialog.
Another example: Say we decide to change the
attribute_state sub assembly to a
text tile from an
image_button. No Problem:
/*attribute_state : image_button {
height = 1;
width = 2;
fixed_width = true;
fixed_height = true;
aspect_ratio = 1;
color = -15;
}*/
attribute_state : text {
fixed_width = true;
width = 1;
is_bold = true;
}
Now all 8 instances of
attribute_state are
text tiles instead of
image buttons (ps: I think if you made the image buttons just image tiles there may not be a border around them Alan).
Of course the code would have to reflect same:
(defun asterisk ( tile / x y )
(set_tile tile "*")
;| <comment out former code>
(setq
X (dimx_tile tile)
Y (dimy_tile tile)
)
(start_image tile)
(fill_image 0 0 x y -15)
(mapcar 'vector_image; Color 1
(list 5 1 1 0)
(list 0 9 1 5)
(list 5 9 9 10)
(list 10 1 9 5)
(list 1 1 1 1)
)
(end_image)
</comment out former code> |;
)
And:
(defun ast_clear ( tile / x y )
(set_tile tile "")
;| <comment out former code>
(setq
X (dimx_tile tile)
Y (dimy_tile tile)
)
(start_image tile)
(fill_image 0 0 x y -15)
(end_image)
</comment out former code> |;
)
Final tip: Read up on
@include statement (in the context of dcl source files and subassembly discussion above).