Issue 1: UI update code in ActionList.OnUpdate not updating UI controls.

I had just Updated my subscription for TMS Scripter. And I have just done a clean install of Script from v7.10.1 (that last update I was able to receive) to 7.22. I had hoped that a few of issues that I had seen in 7.10.1 would have been fixed by this time. But, seems to still be an issue in 7.22.

I'll take about the first issue here. And then the remaining issues in their own topics.

Issue 1: UI Update code in ActionList.OnUpdate not updating UI controls.

The first issue I had come across. Is that the UI controls linked to any Actions in a ActionList, or the ones that you have kindly supplied in the dIDEActions, are not updated.

What do I mean by this? Well, when you Run a script by pressing on the Run button. The UI controls links to the acRun, acPause and acRest are not properly Enabled and Disabled. As in the acRun is not disabled and the acPause & acRest are not enabled.

It does not matter how you start running your script (from the Menu Run > Run, Clicking on the Run Toolbutton, or even setting a Shortcut key to the action is pressing that.)

I have seen this behavior in my own project and the IDE Demo. I have built the IDE Demo within the following environments: XE7 Pro, 10.2.3 (Tokyo) Pro, 10.3.3 (Rio) Community. And I have run the IDE Demo on Windows 7, 8 and 10. All with the same results.

To reproduce the problem:

  1. Launch IDE Demo.
  2. Edit Unit1 to match the code below.
  3. Click on the Run TToolbutton.

Once the script is running you will see that the Run button is not disabled and the Pause and Script Rest buttons are not Enabled.

But if you click on any of the menubar item, except About, while the script is running. This causes the UI to be updated. For some reason clicking on the About menubar item, does not do this.

After doing some research, I think I know that is causing this problem to happen. The TActionList.OnUpdate event only "Occurs when the application is idle so that the action list can update a specific action in the list."

It seems that for some reason, the Scripter Engine is allowing the application to become idle long enough for the ActionList.OnUpdate to be executed.

Test Code for Unit1:

uses
  Classes, Graphics, Controls, Forms, Dialogs,
  SysUtils, Unit2;

var
  MainForm: TForm2;
  i;
begin
  Application.ProcessMessages;
  MainForm := TForm2.Create(Application);
  try    
    MainForm.Show;
    for i := 1 to 60 do
    begin 
      Application.ProcessMessages;
      Sleep(100);
    end;
  finally
    MainForm.FreeOnRelease;
  end;
end;

Unfortunately that's how it works, actions rely on the main thread to be properly executed, the update methods of the actions are not executed in that situation.

So basically, what you are stating is. In the IDE Demo if the main thread is not executed in a specific way. The UI specific Buttons and Menu Items that should be automatically updated, enabled/disabled, during the execution of a script. Will not be updated, unless we select an item on the Main menu, because the code to do the enabling/disabling of those buttons and menu items is only executed during the ActionList OnUpdate event. Which only happens when the Application is considered at idle.

And yet, call that normal.

Well, after reading your reply. I had to go searching for some way to get the ActionList OnUpdate event to be executed. And what I ended up having to do. Is add a TTimer to the dIDEActions. Set it to have an time interval of 100 milliseconds and to be enabled by default. And then the OnTimer event procedure to be the following:

TTimer.OnTimer event:

procedure UpdateTimer(Sender: TObject);
var
  bHandled: Boolean;
  AValid: Boolean;
  ARunning: Boolean;
  APaused: Boolean;
begin
  AValid := IDEEngine1.ActiveFile <> nil;
  ARunning := AValid and IDEEngine1.Scripter.Running;
  APaused := AValid and IDEEngine1.Scripter.Paused;

  if AValid and (ARunning and not APaused) then
  begin
      alstMainActionsUpdate(acRun, bHandled);
  end;
end;

As you can see, the timer will only execute the ActionList OnUpdate procedure. While a script is currently running. Otherwise the procedure is executed only during the ActionList OnUpdate event.

This works, and with an interval of 100 milliseconds. It updates the UI with only an occasional perceived delay in the UI being updated.

1 Like