Detect and close blocking dialogs

J

Joel

Guest
I am trying to automate some actions using SKILL code. However,
certain actions can cause modal dialog that block the execution of a
function until someone manually closes it (or if I use -nograph I have
I set up a timeout mechanism or kill the process using the OS).

I was wondering if there was a way to get the handle of the currently
blocking dialog box in order to close the form and allow the script to
continue? For example, I can use hiGetCurrentWindow() and
hiGetCurrentForm() to get the handle of windows and forms, but neither
one of these seems to return the handle of a modal dialog. Perhaps
there is a hiGetCurrentDialog() or similar function that I just
haven't seen in the documentation?

Alternatively, is there a way to prevent modal dialogs in general?

Thank you in advance.

Joel
 
I am trying to automate some actions using SKILL code. However,
certain actions can cause modal dialog that block the execution of a
function until someone manually closes it (or if I use -nograph I have
I set up a timeout mechanism or kill the process using the OS).

I was wondering if there was a way to get the handle of the currently
blocking dialog box in order to close the form and allow the script to
continue? For example, I can use hiGetCurrentWindow() and
hiGetCurrentForm() to get the handle of windows and forms, but neither
one of these seems to return the handle of a modal dialog. Perhaps
there is a hiGetCurrentDialog() or similar function that I just
haven't seen in the documentation?

Alternatively, is there a way to prevent modal dialogs in general?

Thank you in advance.

Joel
The modal dialog appearing probably means that you've been using functions intended for interactive
use. A procedural function shouldn't block the interface, as its name implies.


Stéphane
 
True. I have found that the tasks I want to perform sometimes require
using functions that are interactive because the equivalent procedural
function doesn't exist.

One example is an implementation taken from a previous post that
triggers CDF callbacks in order to change the value of a CDF
parameter. I have found that some callbacks can trigger modal
dialogs. I have other examples as well and you are right, they
involve trying to automate tasks that are designed to be interactive.
As such I need to add some interaction like the ability to close
dialog boxes.

Joel


The modal dialog appearing probably means that you've been using functions intended for interactive
use. A procedural function shouldn't block the interface, as its name implies.

Stéphane
 
Joel wrote, on 02/13/08 16:31:
True. I have found that the tasks I want to perform sometimes require
using functions that are interactive because the equivalent procedural
function doesn't exist.

One example is an implementation taken from a previous post that
triggers CDF callbacks in order to change the value of a CDF
parameter. I have found that some callbacks can trigger modal
dialogs. I have other examples as well and you are right, they
involve trying to automate tasks that are designed to be interactive.
As such I need to add some interaction like the ability to close
dialog boxes.

Joel


The modal dialog appearing probably means that you've been using functions intended for interactive
use. A procedural function shouldn't block the interface, as its name implies.

Stéphane
Joel,

Callbacks which raise dialog boxes are bad, bad, things. If you are going to
write CDF callbacks, they should:

a) not compute derived values which are used in pcells or simulation (see my
"Dangers of CDF callbacks" solution on sourcelink)
b) be quick
c) not interact with the user (as this prevents them from being called
interactively).

However, if you're unlucky enough to have to use somebody else's badly written
callbacks, you can solve your original problem using hiRegTimer. For example:

procedure(myDontShowDBox()
; schedule an OK button press on the dialog box when the UI toplevel
; returns - or rather 0 tenths of a second after it returns.
hiRegTimer("hiDBoxOK(myDBOX)" 0)
; display the modal (blocking) dialog box
hiDisplayAppDBox(?name 'myDBOX ?dboxText "Blocking" ?dialogStyle 'modal)
)

Regards,

Andrew.
 
However, if you're unlucky enough to have to use somebody else's badly
written callbacks, you can solve your original problem using hiRegTimer.
For example:

procedure(myDontShowDBox()
; schedule an OK button press on the dialog box when the UI toplevel
; returns - or rather 0 tenths of a second after it returns.
hiRegTimer("hiDBoxOK(myDBOX)" 0)
; display the modal (blocking) dialog box
hiDisplayAppDBox(?name 'myDBOX ?dboxText "Blocking" ?dialogStyle 'modal)
)
Works if you know the dbox's name. If you have access to the code that creates the dialog, then you
can certainly find out.

If not... I couldn't find any way of getting a handle to the current dialog which wouldn't qualify
for a "hack" appelation. Seems dialogs are not windows or forms eithers.


Specifically, after some playing around, I found there's a variable called _dboxList which holds the
current dialog's handle. So this might do the trick

when( boundp('_dboxList) && _dboxList hiDBoxOK(_dboxList) )


At least it works here... Of course, that's a very very bad thing to do but if it can help :)


Stéphane
 
S. Badel wrote, on 02/14/08 11:49:
However, if you're unlucky enough to have to use somebody else's badly
written callbacks, you can solve your original problem using
hiRegTimer. For example:

procedure(myDontShowDBox()
; schedule an OK button press on the dialog box when the UI toplevel
; returns - or rather 0 tenths of a second after it returns.
hiRegTimer("hiDBoxOK(myDBOX)" 0)
; display the modal (blocking) dialog box
hiDisplayAppDBox(?name 'myDBOX ?dboxText "Blocking" ?dialogStyle
'modal)
)

Works if you know the dbox's name. If you have access to the code that
creates the dialog, then you can certainly find out.

If not... I couldn't find any way of getting a handle to the current
dialog which wouldn't qualify for a "hack" appelation. Seems dialogs are
not windows or forms eithers.


Specifically, after some playing around, I found there's a variable
called _dboxList which holds the current dialog's handle. So this might
do the trick

when( boundp('_dboxList) && _dboxList hiDBoxOK(_dboxList) )


At least it works here... Of course, that's a very very bad thing to do
but if it can help :)


Stéphane
You can easily find out the dialog box name by turning on everything in the
Options->Log Filter and seeing what it says.

I really wouldn't recommend the "hack" that Stéphane suggests, since that is
very likely to be version dependent. I'm quite impressed you found it though ;-)

Andrew.
 
You can easily find out the dialog box name by turning on everything in
the Options->Log Filter and seeing what it says.
That's one point for you :)

Of course, unless the dialog handle was explicitly meant to be shared by the code's author, this is
actually making use of a private variable. And it could change after updating your software,
design kit or whatever it came with. So in the end doesn't really make a code more portable or robust...

Still I agree that it's a less dirty solution. And it does solve the initial problem, I guess ?


Stéphane
 
You can easily find out the dialog box name by turning on everything in the
Options->Log Filter and seeing what it says.

I really wouldn't recommend the "hack" that Stéphane suggests, since that is
very likely to be version dependent. I'm quite impressed you found it though ;-)

Andrew.
Thank you very much guys!

Andrew, I completely agree with your comments here and elsewhere about
CDF callbacks. I had implemented exactly what you suggested using
hiRegTimer in a few of the cases I came across. My current approach
had been to run the SKILL code. When it fails due to a blocking
dialog, look at the log messages to determine the name of the dialog.
I then register a timer to close the dialog box (if it appears) before
calling the function that triggered it. Repeat as necessary (which
actually wasn't that often, but a nuisance nonetheless).
Unfortunately, this apprach doesn't scale very well and I was looking
for a better solution.

Stéphane, your "hack" code worked! Thank you very much for taking the
time to figure that out. I am a little uncomfortable relying on a
private variable and I acknowledge the cautions against using it.
Obviously it would be much better if there was a public function that
returned the handle for the current dialog box like there is for
windows and forms. But there isn't and for now, as you point out, it
works.

Thank you again for your help!

Joel
 

Welcome to EDABoard.com

Sponsor

Back
Top