i have the current scenario, im using omnithreadlibrary for some generic background work like this:
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;
so before i start executing i block the interface like this:
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;
and when the thread finish i release the block like this:
procedure TMyForm.IsAvaliable();
begin
try
Self.FWorker.Release();
finally
Self.Enabled := True;
end;
end;
note: TPresentationFormWorker is a animated form that i put in form of the busy one.
the problem is that when the form is "busy" executing the thread even after i disable it, i can still interact with him, for example:
- i can click in any button and when the thread finish the execution the action of the button are triggered;
- i can typing in any control, e.g a Edit some nonsense information and when the thread finish the execution the content i provided to the control are erased back to before (ui rollback? lol);
so my guess is that while the thread are working thanks to the application.processmessages the interaction i made to the disable form are sended to the queue and once the thread finish they are all send back to the form.
my question is: is possible to actually disable the form, when i say disable i mean block all messages until certain point that i manually allow that can start accept again?
thx in advance.
.Enabled := false
should not allow you to modify or operate anything on the form. What isTThreadExecuter
? Is it aTThread
descendent? We need to see more information with context for all of this code - where and how is it all being called? ThatApplication.ProcessMessages
loop does not inspire confidence... – WelshApplication.ProcessMessages
– KidderForm.Enabled := False
? – Telloif the user double click fast a button the second click will be processed when the action of the first is concluded
. Well that's because you are using the evilApplication.Processmessages
... – Granophyre