Search code examples
delphievent-handlingpython-idledelphi-2006taction

Delphi idle handler only fires when I move the mouse


I have an OnIdle handler in my D2006 app. With this code:

procedure TMainForm.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);

begin
Inc (IdleCalls) ;
Sleep (10) ;
Done := False ;
end ;

the app runs smoothly, the idle handler is called 100 times per second, and the CPU usage is next to zero.

I then added a TActionList and connected up some controls to actions, coded an Execute and Update handler.

procedure TMainForm.ActionNewButtonExecute(Sender: TObject);
begin
DoNewProject ;
end ;

procedure TMainForm.ActionNewButtonUpdate(Sender: TObject);
begin
ActionNewButton.Enabled := AccessLevelIsSupervisor ;
end;

Problem. The OnUpdate event doesn't fire. On a hunch I set Done := true in the OnIdle handler and the OnIdle handler is then only called when I move the mouse. And the Update action still doesn't fire.

Why might the Update handler not be firing, and should I set Done to true or false? Or both?


Solution

  • As mentioned in the comments, Sleep in the idle handler will do no good, also the bacground processing will stall if there is no activity on the application.

    You can however lower the CPU usage w/o much disturbing effects:
    After processing all OnIdle events, the application will call WaitMessage (which will sleep while the message queue is empty), if the Done parameter is True - you can just unconditionally set it in your handler.

    As for background processing, use either a thread and call back to the main thread via Synchronize or, if you really-really have to, use a timer and don't ever forget to handle reentrancy (both solutions will by the way wake the application even while WaitMessage).