Script Dialog while loop not running some commands

Could anyone explain to me why the following code does not result in anything being written to the script log please?

function OnClick(clickData)
{
    var dlg = DOpus.Dlg;
    dlg.template = "dialog1";
    dlg.detach = true;
	dlg.Show();

    while (true) {
		var msg = dlg.GetMsg();
			
		if (!msg.result) break;

		DOpus.Output("Script never runs this command");
    }
	
}

Because after the break any remaining code in the while loop will not be executed (it won't just prevent the next iteration of the loop, it immediately exits the loop).
If you move the DOpus.Output before the break, it will be executed.

The 'break' only triggers when the user closes the dialog. I tried what you suggested though:

Changed to this:

    while (true) {
		var msg = dlg.GetMsg();
			
		DOpus.Output("Script never runs this command");

		if (!msg.result) break;
    }

Now the script log receives the text AFTER the break; occurs (ie, the user closes the window). In my mind it should be continually writing to the log until the break occurs.

This basic button illustrates what I mean - open the script log before clicking the button:

Test.dcf (1.4 KB)

Opus is trying to be smart and optimized, so it only runs your while loop when there are events to process. To illustrate this please set your dialog property "Resizable" to "True" and try the code below: you'll see that your message is being logged only when there are some events such as you resizing the window, or clicking the button etc.

image

function OnClick(clickData)
{
    var dlg = clickData.func.Dlg;
    dlg.template = "dialog1";
    dlg.detach = true;	
	dlg.want_resize = true;
	dlg.Show();

    var msg = true;
    while (msg == true) {
		msg = dlg.GetMsg();
		DOpus.Output("event: " + msg.event);
		DOpus.Output("Script never runs this command");
    }	
}
1 Like

Thanks - that makes more sense.

It just means I can't get my dialog to constantly monitor the source lister to see if the user selects a different file.

Actually there is a way to achieve this with timers, but it's not recommended by GPSoft to have add-ins that run forever.

See some very old examples:

vbscript:

jscript:

Cheers. I was just looking at timers and thinking how ugly a solution that would be :slight_smile:

Adding to what Bytespiller was saying, the dlg.GetMsg() call will block until there is actually an event to return, or the window is closed.

Using timers on dialogs is fine and supported if you need the dialog to do something while it's open. i.e. The stuff in Jon's Dialog.SetTimer/Dialog.KillTimer example? post is completely fine.

Having things like OnStartup events in script add-ins which run infinite loops and never return is definitely not supported (i.e. Lister title bar clock ) and could result in other scripts/events never being run, or Opus windows freezing, or the installer not shutting down Opus to install updates, and so on. Events should do things quickly and then finish, since something else that needs to happen may be blocked until they're done.

Ah. Thanks for the additional info Leo.

1 Like