InputQuery格式问题

时间:2017-02-10 02:14:13

标签: forms user-interface delphi inputbox

我在Delphi XE2上遇到InputQuery / InputBox问题。

输入区域不合适(应在文本下)。

在制作我自己的输入表单之前,有没有办法重新对齐它?

enter image description here

谢谢!

1 个答案:

答案 0 :(得分:1)

InputQuery()并非旨在以这种方式使用。提示文本是一个显示在文本字段左侧的短标签(类似于TLabeledEdit)。它并非旨在显示提示上方的指令,就像您正在尝试的那样。只需使用您想要的任何控件和布局创建自己的自定义窗体,就可以更好地处理这种情况。例如,使用TDateTimePicker表示日期和时间,TCheckBoxTRadioGroup表示重复,等等。

然而,话虽如此,InputQuery()是使用自定义VCL TForm实现的,因此技术上可行来完成您要实现的目标。您可以使用TScreen.OnActiveFormChange事件在Form对象可见时访问它,然后您可以随意操作它。例如:

procedure TMyForm.ActiveFormChanged(Sender: TObject);
var
  Form: TCustomForm;
  Prompt: TLabel;
  Edit: TEdit;
  Ctrl: TControl;
  I, J, ButtonTop: Integer;
begin
  Form := Screen.ActiveCustomForm;
  if (Form = nil) or (Form.ClassName <> 'TInputQueryForm') then Exit;

  for I := 0 to Form.ControlCount-1 do
  begin
    Ctrl := Form.Controls[i];
    if Ctrl is TLabel then
    begin
      Prompt := TLabel(Ctrl);
    end
    else if Ctrl is TEdit then
    begin
      Edit := TEdit(Ctrl);
    end;
  end;

  Edit.SetBounds(Prompt.Left, Prompt.Top + Prompt.Height + 5, Prompt.Width, Edit.Height);
  Form.ClientWidth := (Edit.Left * 2) + Edit.Width;
  ButtonTop := Edit.Top + Edit.Height + 15;

  J := 0;
  for I := 0 to Form.ControlCount-1 do
  begin
    Ctrl := Form.Controls[i];
    if Ctrl is TButton then
    begin
      Ctrl.SetBounds(Form.ClientWidth - ((Ctrl.Width + 15) * (2-J)), ButtonTop, Ctrl.Width, Ctrl.Height);
      Form.ClientHeight := Ctrl.Top + Ctrl.Height + 13;
      Inc(J);
    end;
  end;
end;

procedure TMyForm.DoSomething;
var
  value: string;
begin
  Screen.OnActiveFormChange := ActiveFormChanged;
  try
    InputQuery('Enter New Schedule', 'Format: <Second> <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> <Year>.'#10'Use * for repeating cycles. ex: 0 0 7 * * * * (trigger at 7AM everyday)', value);
  finally
    Screen.OnActiveFormChange := nil;
  end;
end;

image

可替换地:

class procedure TScreenEvents.ActiveFormChanged(Sender: TObject);
var
  Form: TCustomForm;
  Instructions: TLabel;
  Ctrl: TControl;
  I, J, K, Offset: Integer;
begin
  Form := Screen.ActiveCustomForm;
  if (Form = nil) or (Form.ClassName <> 'TInputQueryForm') then Exit;

  for I := 0 to Form.ControlCount-1 do
  begin
    Ctrl := Form.Controls[I];
    if Ctrl is TLabel then
    begin
      Instructions := TLabel.Create(Form);
      Instructions.Parent := Form;
      Instructions.Caption := 'Format: <Second> <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> <Year>.'#10'Use * for repeating cycles. ex: 0 0 7 * * * * (trigger at 7AM everyday)';
      Instructions.SetBounds(Ctrl.Left, Ctrl.Top, Instructions.Width, Instructions.Height);

      Offset := Instructions.Top + Instructions.Height + 5;
      Form.ClientWidth := Instructions.Width + (Instructions.Left * 2);

      K := 0;
      for J := 0 to Form.ControlCount-1 do
      begin
        Ctrl := Form.Controls[J];
        if Ctrl <> Instructions then
        begin
          Ctrl.Top := Ctrl.Top + Offset;
          if Ctrl is TEdit then
          begin
            Ctrl.Width := (Form.ClientWidth - Ctrl.Left - Instructions.Left);
          end
          else if Ctrl is TButton then
          begin
            Ctrl.Left := (Form.ClientWidth - (Ctrl.Width + 5) * (2-K));
            Inc(K);
          end;
        end;
      end;

      Form.ClientHeight := Form.ClientHeight + Offset;
      Break;
    end;
  end;
end;

procedure TMyForm.DoSomething;
var
  value: string;
begin
  Screen.OnActiveFormChange := ActiveFormChanged;
  try
    InputQuery('Enter New Schedule', 'Value', value);
  finally
    Screen.OnActiveFormChange := nil;
  end;
end;

image