0

我想从用户那里获取多个不同类型的值(时间、压力、名称……)。我想自定义我的输入框。但它只取一个值。

有什么办法可以解决这种情况,或者使用任何组件吗?

4

5 回答 5

7

弗朗索瓦是对的。你已经达到了你得到的工具的极限。InputBox根本不是为复杂输入而设计的,也不是为了处理多个值而设计的。

您在评论中链接到的页面有一个示例,但它的呈现效果很差,所以我不怪您误解它。我也读了几本书才明白。它的核心是MyAsk底部的功能。(忽略TAppendThread顶部的类声明。它没用。)MyAsk接受带有提示和值的记录列表,并且对于每条记录,它调用InputBox以向用户请求一个值。没有记录可能更容易理解。可以这样重写:

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;

像这样称呼它:

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

不过,这对用户来说是一个糟糕的界面。没有办法回去,没有办法取消,没有迹象表明询问将持续多长时间,也没有办法强制某些数据类型的格式。如果您设计一个能够准确获取所需信息的自定义表单,您的情况会好得多。您正在使用一种工具来设计一个关于世界上最简单的事情的表单。不要抗拒。

如果您需要获取时间、压力和名称,则制作一个具有三个输入控件的表单。使用 aTDateTimePicker作为时间,考虑使用 aTSpinEdit作为数字输入,使用 aTEdit作为名称。将TLabel控件放在每个输入旁边,以便用户知道每个输入的用途。将确定和取消按钮放在表单上。设置各种其他表单属性,例如边框样式和标题。几乎没有代码可以以这种形式编写。不过,您可以自由添加代码来验证输入值,以确保它们有意义。

要使用它,只需创建它,填充它的初始值,以模态方式显示它,并在它关闭时读出新值。

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;

还要注意我如何检查ShowModal方法的结果。这让您知道用户是否按下了确定或取消来关闭表单。你不能这样做InputBox,它总是返回一个字符串。(InputQuery可以告诉您该信息,这是这两个函数之间的主要区别,但仅此一点并不能真正使这两个函数在您的情况下值得使用。)

不要担心这个新的表单类会影响您的项目。对项目规模影响最大的两件事是SysUtilsForms单元。你已经包括了那些,所以最糟糕的已经过去了。将表单添加到已经至少有一个表单的项目中,根本不会影响项目大小,尤其是我上面描述的表单,它只有八个控件。

于 2009-12-10T15:04:23.390 回答
3

“输入框”到底是什么意思 - TEdit?有许多不同种类的输入组件,它们可以做许多不同的事情。对于名称,TEdit 非常好 - 但对于时间,您可能想要一个日历控件,对于压力,您可能想要使用一个看起来非常适合数字的控件。

于 2009-12-10T08:27:20.387 回答
3

是的,设计一个表格!

Dialogs.InputBox 旨在从用户那里获取 1 个字符串,快速而简单。
如果你想要更多,你必须设计一个参赛表格。
如果您想要一个基本对话框,您可以查看 Dialogs.InputQuery 中的代码,并将其用作编写您自己的过程的起点。

如果你想要真正的交易,你必须深入挖掘并编写一个真正的表单。

于 2009-12-10T09:25:20.477 回答
0

Rob 的 Kennedy 是对的。输入框不是一个好的选择...您到底想保存什么?Exe 空间、资源或源代码?或者你只是想用你的“绿色”代码来拯救环境?

如果您看一下 InputQuery 函数,您会发现它所做的是创建一个 TForm 并创建一些 TButtons/TLabels/TEdit,定位并显示模态表单。

您将使用添加到项目中的新表单来做什么......除此之外,您还可以验证、自定义控件并定位它们,甚至添加提示......

使用新表格...

于 2009-12-10T16:49:20.940 回答
0

您不必将每个表单都设置为自动创建,在创建表单后进入项目选项,选择表单选项并将所有您不希望自动创建的表单移到右侧。

我最常用于这些非自动创建表单的模式如下所示:

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;

GetValues/SetValues 方法从保存例程中使用的值的记录或类填充对话框。我从不尝试从表单外部操作表单上的控件,而是编写例程在表单本身中进行操作。

于 2009-12-10T17:25:31.990 回答