使用ModalResult退出表单

Kin*_*ong 14 forms delphi

我有一堆表格,我想自动化它们,以便它们自己打开和关闭.

我知道如何让它们打开(通过具有OnActivate功能),但我无法关闭它们.

所以,例如,我有

procedure TProgressForm.FormActivate(Sender: TObject);
begin
  inherited;
  if FModItem.IsInQueue then
    begin
      RunBtnClick(Self);
      ModalResult := mrOK;
    end;    
end;
Run Code Online (Sandbox Code Playgroud)

它运行一个功能.我希望在函数运行后关闭窗口,这是ModalResult应该做的.

(我也尝试在RunBtnClick过程的最后添加ModalResult行,但这也不起作用)

我正在创建这样的表单:

ProgForm := TProgressForm.Create(Self, FModItem);
Self.Visible := False;
try
 if ProgForm.ShowModal = mrOK then
  begin
    Left := ProgForm.Left;
    Top := ProgForm.Top;
  end;
Run Code Online (Sandbox Code Playgroud)

我只能通过将mrOK添加到Object Inspector中的Modal Result来创建关闭表单的按钮,但我似乎无法明确地执行此操作

谁能明白为什么它不起作用?

谢谢

NGL*_*GLN 15

不工作的原因是VCL在显示表单后在TCustomForm.ShowModal中主动将ModalResult设置为0,但在开始检查对ModalResult的更改之前.所以在OnActivate和OnShow中,你要早.

解决方案是延迟通知.这可以通过PostMessage完成,如下所示:

const
  UM_ACTIVATED = WM_USER + 1;

type
  TProgressForm = class(TForm)
    procedure FormActivate(Sender: TObject);
  private
    procedure UMActivated(var Message: TMessage); message UM_ACTIVATED;
  end;

...

procedure TProgressForm.FormActivate(Sender: TObject);
begin
  PostMessage(Handle, UM_ACTIVATED, 0, 0);
end;

procedure TProgressForm.UMActivated(var Message: TMessage);
begin
  { Your code here }
  ModalResult := mrOk;
end;
Run Code Online (Sandbox Code Playgroud)

资料来源:NLDelphi


Cos*_*und 6

我会覆盖ShowModal并执行您现在在OnActvate那里进行的测试.这有两大优点:

  • 不显示形式在所有如果它并不需要显示.启动表单关闭OnActivate会导致表单在屏幕上"闪烁":显示并立即关闭.
  • 不依赖于您无法控制的代码.您不再关心祖先中的操作顺序ShowModal,因为只有在需要实际显示表单时才调用它.

当然,使用GUI元素(表单)这种方式有点代码味道,因为它基本上使用GUI而不需要用户交互.毫无疑问,这可以重构为使用中间函数返回mrOkRunBtnClick()执行无需GUI的操作,并在Form需要时创建唯一的函数.我想这是一种成本效益的情况.

码:

TMyForm = class(TForm)
....
public
  function ShowModal:Integer;override;
end;

function TMyForm.ShowModal:Integer;
begin
  if FModItem.IsInQueue then
    begin
      RunBtnClick(Self);
      Result := mrOK;
    end
  else
    Result := inherited ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)