如何在执行线程时阻止所有传入消息到表单

时间:2015-02-06 19:00:45

标签: delphi delphi-xe2 omnithreadlibrary

我有当前的场景,我使用omnithreadlibrary进行一些通用的背景工作:

TMethod = procedure of object;

TThreadExecuter = class;

IPresentationAnimation = interface
  ['{57DB6925-5A8B-4B2B-9CDD-0D45AA645592}']
  procedure IsBusy();
  procedure IsAvaliable();
end;

procedure TThreadExecuter.Execute(AMethod: TMethod); overload;
var ATask : IOmniTaskControl;
begin
  ATask := CreateTask(
    procedure(const ATask : IOmniTask) begin AMethod(); end
  ).OnTerminated(
    procedure begin ATask := nil; end
  ).Unobserved().Run();

  while Assigned(ATask) do
    begin
      Sleep(10);
      Application.ProcessMessages;
    end;
end;

procedure TThreadExecuter.Execute(ASender: TCustomForm; AMethod: TMethod); overload;
var AAnimator : IPresentationAnimation;
begin
  if(Assigned(ASender)) then
    begin
      TInterfaceConsolidation.Implements(ASender, IPresentationAnimation, AAnimator, False);
      if(Assigned(AAnimator)) then AAnimator.IsBusy()
      else ASender.Enabled := False;
    end;
  try
    Self.Execute(AMethod);
  finally
    if(Assigned(ASender)) then
      begin
        if(Assigned(AAnimator)) then AAnimator.IsAvaliable()
        else ASender.Enabled := True;
      end;
  end;
end;

所以在我开始执行之前我阻止了这样的界面:

TMyForm = class(TForm, IPresentationAnimation);

procedure TMyForm.LoadData();
begin
  TThreadExecuter.Execute(Self, Self.List);
end;

procedure TMyForm.IsBusy();
begin
  try
    Self.FWorker := TPresentationFormWorker.Create(Self);
    Self.FWorker.Parent := Self;
    Self.FWorker.Show();
  finally
    Self.Enabled := False;
  end;
end;

当线程结束时,我发布了这样的块:

procedure TMyForm.IsAvaliable();
begin
  try
    Self.FWorker.Release();
  finally
    Self.Enabled := True;
  end;
end;

注意:TPresentationFormWorker是一个动画形式,我把它放在忙碌的形式。

问题是当表单“忙”执行线程时,即使我禁用它,我仍然可以与他交互,例如:

  • 我可以点击任何按钮,当线程完成执行时,触发按钮的动作;
  • 我可以键入任何控件,例如编辑一些无意义的信息,当线程完成执行时,我提供给控件的内容将被删除回到之前(ui rollback?lol);

所以我的猜测是,当线程正在运行时,感谢application.processmessages,我对禁用表单的交互被发送到队列,一旦线程完成,它们都被发送回表单。

我的问题是:是否有可能实际禁用表单,当我说禁用时我的意思是阻止所有消息,直到我手动允许的某些点可以再次开始接受?

提前thx。

0 个答案:

没有答案