]VSE} MessageBox is a Process Hog 
Author Message
 ]VSE} MessageBox is a Process Hog

I have some automated test code to exercise my MVC code.
I need to open a Modal Dialog, do some things to it, then continue.
Since a Modal Dialog "takes over" the thread, I've had to do some
workarounds. I use the following generic method to handle this:
-------------
dialog: blockToOpenADialog
onOpenDo: blockToRunOnTheDialogAndCloseItWhenDone

  |activeDialog semaphore |
  semaphore := Semaphore new.

  [blockToOpenADialog value.
  semaphore signal] forkAtHigherPriority.  "Open the dialog in a separate
fork. It will start, then wait on a close"

  activeDialog := Notifier activeMainWindow owner.   "get the active dialog
and send it to the block"
  blockToRunOnTheDialogAndCloseItWhenDone value: activeDialog.
  semaphore wait
-----------
This method is part of the test code and does the following for me:

blockToOpenADialog is a block that opens a modal dialog window.
The Notifier activeMainWindow owner just finds the top window, which
gets around the method blocking and allows me to get a handle on the
open ModalDialog window.
blockToRunOnTheDialogAndCloseItWhenDone is a block that takes
the modal dialog window as an argument, acts on it, then closes it.

The #forkAtHigherPriority is a simple method to fork a new Process
to execute a BlockClosure at one level higher priority than the
current Process.

So my test code calls this method to open a modal dialog window,
run some operations on it, closes the window, then continues.

I fork the ModalDialog open so that I do not block the current method.
I semaphore this process so that I can get the "front" window (which
is the ModalDialog), do something to it, close it, then continue. I also
have to make sure that the current method does not finish until the
ModalDialog has been opened, operated on, then closed.

For example, I may need to open the Prompter, type in a string, select
OK, and continue. I would write something like:

self
    dialog: [Prompter confirm: 'Save Project?'
    onOpenDo: {:modalDialog | modalDialog closeWithReply: true]

where I have added a method #closeWithReply: to the Prompter class
that selects OK and closes the window.

This works fine with my DialogWindows, ViewManagers, Prompters, etc.

It craps out with the MessageBox. The MessageBox uses the UserDLL
to call the native Windows API to show a message box. Something within
this call "takes over" the current thread. In other words, the
blockToOpenADialog value method ends up at an #evaluateWithoutInterrupts
call and the thread is blocked. (I think.)

I've tried everything I can think of to get control back from the
"MessageBox confirm:" method. I have forked blocks at topPriority.
I have tried all sorts of semaphore configurations. No can do.
The de{*filter*} is useless and the semaphores wind up blocking
the entire image and requiring a ctrl-alt-del.

I can keep hammering trial-and-error, but I'm ignorant and don't know
how to proceed. I've thought about using MessageDialog objects rather
than MessageBox objects, but the former are ugly unless I can figure
out how to change fonts, etc, etc.

I want to do this right, once and for all.

How can I fork a "MessageBox confirm:" method and regain control
while this window is open?

Thanks in advance.



Wed, 18 Jun 1902 08:00:00 GMT  
 ]VSE} MessageBox is a Process Hog
On Sat, 11 Mar 2000 06:34:04 GMT, "Richard MacDonald"

Quote:

>I want to do this right, once and for all.

>How can I fork a "MessageBox confirm:" method and regain control
>while this window is open?

I'm not certain, but I think this might be the deal. If the dialog is
open modal, your process is stopped. Since VSE threads aren't windows
threads but instead just programmed threads inside your process, the
VM itself stops while the dialog is open.

If this theory is true, then there's no way to do what you're trying
to do. OTOH, maybe you don't need to do it anyway. Aren't you pretty
sure that the message box works?

Ron Jeffries
http://www.XProgramming.com
Meditation is futile.  You will be aggravated.



Wed, 18 Jun 1902 08:00:00 GMT  
 ]VSE} MessageBox is a Process Hog


Quote:
> On Sat, 11 Mar 2000 06:34:04 GMT, "Richard MacDonald"

> >I want to do this right, once and for all.

> >How can I fork a "MessageBox confirm:" method and regain control
> >while this window is open?

> I'm not certain, but I think this might be the deal. If the dialog is
> open modal, your process is stopped. Since VSE threads aren't windows
> threads but instead just programmed threads inside your process, the
> VM itself stops while the dialog is open.

That is what I am afraid of. I could always roll my own MessageBox from
the MessageDialog or something, but I hate to do that.

Quote:
> If this theory is true, then there's no way to do what you're trying
> to do. OTOH, maybe you don't need to do it anyway. Aren't you pretty
> sure that the message box works?

Yes, but the message box is part of a particular use case of the
application which I am testing. and this is part of my automated test
suite, so I want it to run unsupervised. I could work around this via
writing a different "test" method for the Controller, but I'm trying to
avoid this.


Wed, 18 Jun 1902 08:00:00 GMT  
 ]VSE} MessageBox is a Process Hog

When the MessageBox is open the VSE thread is blocked on the api call.
However the user.dll sets up a separate message loop so that messages like
wmPaint will be processed by VSE. This also includes wmTimer messages, so
with this knowledge you might set up a work around as follows:
- set up a timer that will call some method a short time after the messagebox
is opened.
- in the event procedure, you will have to stop the timer and close the
messagebox.
- to close the messagebox you can read the article "Q181934 HOWTO: Create a
Timed MessageBox" from the msdn knowledge base which essentially calls
PostQuitMessage to simulate the end of the process. This call is read by the
user.dll message loop and first closes the messagebox and reposts the wmQuit
message to the main message queue. Now you have the opportunity to remove
this unwanted wmQuit from the main message queue so that your normal windows
are not closed. Since the messagebox is closed the normal VSE thread now
continues its work.
This sounds extremely complicated, and still has the problem that you will
not be able to define any return value in case it is of any meaning such as
with MessageBox>>confirm:

A much simpler all Smalltalk solution might be to modify the MessageBox>>open
method to first fire a Notification which has an inst var. If this
notification is not catched anywhere you proceed as normal, if it is catched,
you can set the instVar to a non nil value and check this and proceed without
actually opening the messagebox, as follows:

Notification subclass: #ReallyOpenMessageBox
 instanceVariableNames: 'value'
 ...

MessageBox>>open

exc := ReallyOpenMessageBox new.
exc signal.
exc value == nil ifFalse: [ ^exc value ].
...<continue with original method>

and the catching code looks like this

[ ..."do anything here."
   result := MessageBox confirm: 'do you want this result'.
   "MessageBox might be opened directly here or deeply buried in other
methods
    called from here"
  ... ]
  on: ReallyOpenMessageBox do: [ :e | e value: true
         "this sets the return value - in case it is needed" ].

You will face the same problems for FileDialog and others.
Manfred

Quote:
> > I'm not certain, but I think this might be the deal. If the dialog is
> > open modal, your process is stopped. Since VSE threads aren't windows
> > threads but instead just programmed threads inside your process, the
> > VM itself stops while the dialog is open.

> That is what I am afraid of. I could always roll my own MessageBox from
> the MessageDialog or something, but I hate to do that.



Wed, 18 Jun 1902 08:00:00 GMT  
 ]VSE} MessageBox is a Process Hog

Quote:

>> I'm not certain, but I think this might be the deal. If the dialog is
>> open modal, your process is stopped. Since VSE threads aren't windows
>> threads but instead just programmed threads inside your process, the
>> VM itself stops while the dialog is open.

>That is what I am afraid of. I could always roll my own MessageBox from
>the MessageDialog or something, but I hate to do that.

Might be messy, but I think rolling your own window to do this is probably
the easiest and simplest solution.  The message box is a blocking api
function and it doesn't sound like there is anything you need from a native
API message box that is critical to your application.

Ian

----------------------------------------------------------------------------

----------------------------------------------------------------------------



Wed, 18 Jun 1902 08:00:00 GMT  
 ]VSE} MessageBox is a Process Hog
Thanks for everyone's help.
I was able to get a Timer to trigger an event which bypasses the
MessageBox thread. By some awful hacking, I was even able to
get at the MessageBox instance (the Notifier methods don't work,
but the MessageBox allInstances first does :-). But I still cannot
get the dialog to close and I don't feel up to a native Windows
investigation.

So the Controller gets a new method called #deleteWithoutPrompt
which is stored in the Test package. Simplest hack and its time to
move on.

Thanks again for everyone's interest.


Quote:

> >> I'm not certain, but I think this might be the deal. If the dialog is
> >> open modal, your process is stopped. Since VSE threads aren't windows
> >> threads but instead just programmed threads inside your process, the
> >> VM itself stops while the dialog is open.

> >That is what I am afraid of. I could always roll my own MessageBox from
> >the MessageDialog or something, but I hate to do that.

> Might be messy, but I think rolling your own window to do this is probably
> the easiest and simplest solution.  The message box is a blocking api
> function and it doesn't sound like there is anything you need from a
native
> API message box that is critical to your application.

> Ian

> --------------------------------------------------------------------------
--

> --------------------------------------------------------------------------

--


Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. VSE - MessageBox - help button

2. VAST: Stopped processes during display of Messageboxes

3. VSE 3.11 and Inter-process communication

4. Forking a Process in VSE for OS/2

5. VSE - API-call from user interface process ...

6. backslash processing, am I on crack here?

7. VSE Porting Tool Project - Looking for VSE customer contacts for porting study

8. VSE - Join the VSE mailing list!

9. Problems with migration VSE for OS/2 to VSE for Windows NT

10. VSE: Interest in REXX-Binding for VSE-OS2 ?

11. LE/VSE COBOL and DFSORT/VSE's Year2000 Features

12. LE/VSE COBOL and DFSORT/VSE's Year 2000 Features

 

 
Powered by phpBB® Forum Software