views:

479

answers:

5

I want to get multiple different types values (time, pressure, name, ...) from user. and I want to customize my inputbox. But it take only one value.

Are there any way to solve this situation, or any component to use?

+3  A: 

What exactly do you mean by "inputbox" - a TEdit? There are many different kinds of components for input, which can do many different things. For a name, TEdit is very good - but for time, you may want a calendar control, and for pressure you may want to use a control that looks great for numbers.

Lars D
+3  A: 

Yes, design a Form!

Dialogs.InputBox is designed to get 1 string from the user, quick and simple.
If you want more, you have to design an Entry Form.
If you want a basic dialog, you can look at the code in Dialogs.InputQuery, and use it as a starting point to code your own procedure.

If you want the real deal, you have to dig in and code a real Form.

François
No need to get nasty François.
Craig Young
Thanks but I want to make lighter my software, so I don't want to add any more forms to my project.There is an example that I found but it is difficult to understand.. :(http://www.delphipages.com/forum/showthread.php?t=154839
Rapunzo
@François: Craig is right. I would have voted this up if it weren't for the rudeness of the final sentence.
Ken White
I guess I was too tired to notice it could be interpreted as I see it now... Changed.
François
@Rapunzo: If you already have a number of forms in your project, an extra one isn't going to make much difference. Just make sure you manage it appropriately depending on how it will be used. I.e. Create it at startup or on demand? Keep it or recreate it on every use? Allow multiple instances or only one? ..... That said, if you really are striving for an extremely light-weight app, Delphi is probably not the best choice; but 99% of the time the overhead is relatively insignificant, and the benefits you gain make it all worthwhile. (See Rob Kennedy's answer)
Craig Young
+5  A: 

François is right. You've reached the limit of the tool you've been given. InputBox simply isn't designed for complex input, and it's not designed to be extended to handle multiple values, either.

The page you linked to in your comment has an example, but it's presented rather poorly, so I don't blame you for misunderstanding it. It took me a few reads to get, too. At its core is the MyAsk function at the bottom. (Ignore the TAppendThread class declaration at the top. It's useless.) MyAsk accepts a list of records with with prompts and values, and for each record, it calls InputBox to request a value from the user. It might be easier to understand without the record. It could be rewritten like this:

procedure MultiInputBox(const Prompts: array of string; var Values: array of string]);
var
  i: Integer;
begin
  Assert(Length(Prompts) = Length(Values));
  for i := 0 to High(Prompts) do begin
    Values[i] := InputBox(Application.Title, Prompts[i], Values[i]);
  end;
end;

Call it like this:

TempTime := TimeToStr(DefaultTime);
TempPressure := IntToStr(DefaultPressure);
TempName := DefaultName;
MultiInputBox(['Time', 'Pressure', 'Name'], [TempTime, TempPressure, TempName]);
TimeToUse := StrToTime(TempTime);
PressureToUse := StrToInt(TempPressure);
NameToUse := TempName;

That's a terrible interface for the user, though. There's no way to go back, there's no way to cancel, there's no indication of how long the interrogation is going to last, and there's no way to enforce formats for certain data types. You'll really be much better off if you design a custom form that gets exactly the information you need. You're using a tool that makes designing a form about the easiest thing in the world. Don't resist that.

If you need to get the time, the pressure, and the name, then make a form with three input controls. Use a TDateTimePicker for the time, consider a TSpinEdit for the numeric input, and use a TEdit for the name. Put TLabel controls next to each input so the user knows what each one is for. Put OK and Cancel buttons on the form. Set various other form properties, such as the border style and the caption. There's almost no code to write in that form. You're free to add code to validate the input values, though, to make sure they make sense.

To use it, simply create it, populate its initial values, show it modally, and read the new values out when it closes.

var
  form: TDatePressureNameDialog;
begin
  form := TDatePressureNameDialog.Create(nil);
  try
    form.TimePicker.Value := DefaultTime;
    form.PressureEdit.Value := DefaultPressure;
    form.NameEdit.Text := DefaultName;
    if form.ShowModal = mrOK then begin
      TimeToUse := Frac(form.TimePicker.Value);
      PressureToUse := form.PressureEdit.Value;
      NameToUse := form.NameEdit.Text;
    end;
  finally
    form.Free;
  end;
end;

Notice also how I check the result of the ShowModal method. That lets you know whether the user pressed OK or Cancel to close the form. You can't do that with InputBox, which always returns a string. (InputQuery can tell you that information, which is the primary difference between those two functions, but that alone doesn't really make either function worth using in your situation.)

Don't worry about this new form class weighing down your project. The two things that have the biggest impact on project size are the SysUtils and Forms units. You've already included those, so the worst of it is already past. Adding a form to a project that already has at least one form doesn't affect the project size much at all, especially not the form I described above, which only has eight controls.

Rob Kennedy
A: 

Rob's Kennedy is right.. An input box is NOT a good option... What exactly are you trying to save ? Exe Space, ressources or source code? Or you just want to save the environment with your "green" code?

If you take a look at the InputQuery function you'll see that what it does is create a TForm and it create somes TButtons/TLabels/TEdit, position and show modal the form.

Exactly what you would do with a new form that you would add to your project.. beside you can validate, customize the controls and position them and even add hints...

Go with the new form...

Pmax
A: 

You don't have to set every form to auto-create, after you create your form go into project options, select the forms option and move all forms you don't want auto-created to the right.

The pattern I most generally use for these non-auto-created forms is something like the following:

Function GetValuesFromDialog : boolean;
var
  dlg : tValuesDialog;
begin
  result := false;
  dlg := tValuesDialog.Create(nil);  
  try
    // set initial values in dialog
    dlg.SetValues( rData );
    // show the dialog
    result := dlg.ShowModal = mrOk;
    // pull values from dialog
    if result then
      dlg.GetValues( rData );
  finally
    dlg.free;
  end;
end;

the GetValues/SetValues methods populate the dialog from a record or class which holds the values that are used in the routine. I never try to manipulate controls on a form from outside the form but instead write routines to do it in the form itself.

skamradt