HOME - - - / - - / - - / TUTORIALS INDEX - - - / - - / - - / - - / - - - Other material for programmers

Delphi: Getting input via a user- created dialog box

This page is information rich, and a has search button at the bottom of the page.

Please don't dismiss it because it isn't full of graphics, scripts, cookies, etc!

Click here if you want to know more about the source and format of these pages.


This is the more advanced of two tutorials on the subject of getting input from users.

The less advanced tutorial uses radiobuttons.


You often need a "Yes" / "No" answer from your application's user. There are similar cases where you need an answer from just a few options.

In this tutorial you will create a small application which does nothing useful, but illustrates one way the application can get input from the outside world. (Stephanie.) In a "real" application, of course, that input would cause meaningful changes in the application's behavior. In the illustrative application, the input is used merely to cause a change in the color of a rectangle on the form.

There will be a button on the form, called buSetColor. When you click the button, a dialog... written by you, tailored to the "needs" of this hypothetical application... will pop up. The dialog will have buttons marked "red", "green" and "blue". The dialog won't go away until you click one of the buttons. When you do, the dialog goes away, and the rectangle changes color. In a "real" application, probably a different mechanism would be used to bring up the dialog, but the dialog itself would be the same.

Please! I know there are MANY ways to set the color of a rectangle! The point of the tutorial is to illustrate one of them, not to argue that it is the best way to do this job. What is illustrated in the tutorial IS the best way to do many things!


Create a folder called DD46.

Start up Delphi, and open a new application. Name the form DD46f1. Save the unit as DD46u1, being sure to save it in the DD46 folder you created. Save the project as DD46.

From the "Additional" tab of the component palette, add a TShape object to the form. The default name, "Shape1", will do.

Use the Delphi menu (File|New|Form) to add a new form to the application. Change it's name to diaAskColor. ("dia", for Dialog, which is what windows calls the little boxes with simple questions it, like "You have not saved your work. Save it now? Y/N/Cancel".) Put three buttons on the new form. (Be sure you've gone back to the "Standard" tab of the Component Palette, and that you're adding standard buttons, not the more exotic BitBtns, which are on the Component Palette's Additional page.) Name them buRed, buGreen, buBlue. Move and resize the form so that it doesn't waste space, and doesn't completely cover other things.

Go back to the first form. Put a button on it; name that buSetColor. Make the button's OnClick handler.....
procedure TDD46f1.buSetColorClick(Sender: TObject);
var c1:integer;
begin
c1:=diaAskColor.showmodal;
end;
.... and save the project, giving the name dd46diau1.pas to the unit holding this new form. Don't expect the program to run yet! Try it. You should get "Form DD46f1 references form 'diaAskColor'.... which is not in your "uses" list. Do you want to add it?", or some such. Say "Yes". As soon as you say yes, the program WILL run, even if it doesn't do much yet! (By the way: To get out of the "Red/Green/Blue?" dialog box, click on the little "x" in its upper right corner.)

The reason you were asked if you wanted to add diaAskColor to the main form's uses clause is as follows: The new form, diaAskColor, is not part of the form your buSetColor button is on. When the compiler tries to create the code for SetButton's event handler tries to do something with diaAskColor, it gets stuck because it hasn't heard of any diaAskColor thing. Delphi is, however, remarkably programmer-friendly (really!)... it has "noticed" that you have started the new form, and correctly guesses what you want... and even has the grace to refrain from assuming it's guess is right. When you said "Yes" to the "Add it?" question, "dd46diau1" was added to the "uses" clause of dd46u1. (You can see it there, if you look. It is near the top of the code.)

Once the "uses" clause has "dd46diau1" in it, you can refer to things within that unit, e.g. and in particular diaAskColor.

We've finished the "user interface"! It doesn't do much yet, but already your program has everything your user will see while using the program. You want to have a very clear idea of what the user interface will be before you start a project. You also, of course, need a clear idea of what pressing the various buttons will (eventually) do!


Let's move on to making our program do what it should.

First: Make OnClick handlers for the three buttons which you just put on diaAskColor. They should be:
procedure TdiaAskColor.buRedClick(Sender: TObject);
begin
ModalResult:=1;
end;

procedure TdiaAskColor.buGreeClick(Sender: TObject);
begin
ModalResult:=2;
end;

procedure TdiaAskColor.buBlueClick(Sender: TObject);
begin
ModalResult:=3;
end;
(Advanced programmers, and the tidy minded, should chafe at seeing so much verbiage to achieve "Put 1,2 or 3 in ModalResult, depending on which button was pushed." They're right: There is a more elegant way. But that way is less obvious, and a topic for another tutorial.)

Now... you may find the underlying mechanism of ShowModal hard to grasp.... but you must master this. There is good news, though: "ShowModal" is easy enough to "just use".

"ModalResult" is one of the properties of a button, and of any form. In the discussion that follows, we're talking about the ModalResult property of the diaAskColor form and of the color selection buttons. The main form has a ModalResult property, too, but that is irrelevant to us here. For the form, you won't see ModalResult listed in the Object Inspector. This is because, for the form, ModalResult is "run time only". In other words, the value in the form's ModalResult can only be changed while the program is running, as we are doing in our example. For the button, you can set a limited number of values in the button's ModalResult property at design time. By "at design time", mean with the Object Inspector. The Object Inspector can only be used while the program is not running.

Before we continue with the explanation of why it works, just make sure your program does "work" at this point. You won't see the shape's color change yet, but clicking the "Set color" button should bring up diaAskColor. Until you click one of the three buttons (or the little "x" in the upper right of diaAskColor), you should not be able to do anything else with DD46. When you do click a button, or the "x", diaAskColor should go away.

I'll talk more about it later, but for now realize that when you say....
procedure TdiaAskColor.buGreeClick(Sender: TObject);
begin
modalresult:=2;
end;
... you are setting the form's ModalResult property to 2. You could make the relevant line.....
diaAskColor.modalresult:=.....
... if you wanted to be sure that it was the form's ModalResult you were setting.

When a form it is opened, its ModalResult property will be zero. When the form's ModalResult becomes anything other than 0, the form goes away. Furthermore, the part of your program which made diaAskColor appear has access to whatever number was in diaAskColor's ModalResult property at the time diaAskColor went away! That is why we can say, in DD46u1,....
c1:=diaAskColor.showmodal;
C1 is filled with what was in diaAskColor's ModalResult property. ShowModal is a FUNCTION... it "returns" a value, in this case an integer. You won't always need to USE the value... "diaAskColor.showmodal;" is a complete statement, too. In that use, the result is just thrown away.

By now, I hope you've guessed the next bit. In buSetColor's OnClick handler, just after "c1:=diaAskColor.showmodal;", add....
if c1=1 then shape1.brush.color:=clRed;
if c1=2 then shape1.brush.color:=clGreen;
if c1=3 then shape1.brush.color:=clBlue;
(And yes, there's a "clever" way to write that better, too!)

... and now you have a working program!

You may want to play with various things. In particular, removing all of the BorderIcons from diaAskColor makes sense. (Use the Object Inspector.)

A plea: Don't OVER use modal dialogs? Let's say that the current program were extended to have two shapes, two GetColor dialogs. There would be no need for either to be modal. It might be messy to leave both open, but it would do no harm. Most serious applications ask you if you want to save your work if you attempt to close the application when you have unsaved work in it. THAT is a good place to use a modal dialog. The user needs to be forced to answer the question before doing anything else.


I'd like to thank Dave Jewell for his many helpful writings on Delphi. Something I saw while flipping though his book, ISBN-874416-57-5, 438pgs, Wrox Press, inspired this tutorial.


(Note to myself: See source for extensions planned.)




Click here if you're feeling kind! (Promotes my site via "Top100Borland")
   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search
Ad from page's editor: Yes.. I do enjoy compiling these things for you... I hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's Sheepdog Software (tm) freeware, shareware page.

Link to Tutorials main page
Here is how you can contact this page's author, Tom Boyd.


Valid HTML 4.01 Transitional Page WILL BE tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


If this page causes a script to run, why? Because of things like Google panels, and the code for the search button. Why do I mention scripts? Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....