lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Catching exceptions thrown in OnInit()


From: Greg Chicares
Subject: Re: [lmi] Catching exceptions thrown in OnInit()
Date: Wed, 28 Jun 2006 20:12:55 +0000
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

On 2006-6-28 19:13 UTC, Vadim Zeitlin wrote:
> On Wed, 28 Jun 2006 19:00:26 +0000 Greg Chicares <address@hidden> wrote:
[...]
> GC> /// The msw implementation of wxSafeShowMessage() uses ::MessageBox()
> GC> /// with a null parent, which adds an undesirable extra "task" to the
> GC> /// alt-Tab order, yet doesn't disable the application's top window.
> GC> ///
> GC> /// If MB_TASKMODAL is specified, then the extra "task" is still
> GC> /// added, but all of the application's top windows are disabled.
> GC> /// Unfortunately, MB_TASKMODAL is in effect ignored unless the parent
> GC> /// is null.
> GC> ///
> GC> /// If the main top window (the one returned by wxApp::GetTopWindow())
> GC> /// is used as the messagebox's parent, then the extra "task" is not
> GC> /// added, but only the parent is disabled. Any other top windows the
> GC> /// application may have are not disabled.
> GC> ///
> GC> /// The extra "task" seeming to be the worse evil, this implementation
> GC> /// specifies a non-null parent wherever possible. MB_TASKMODAL is
> GC> /// nevertheless specified as well, though its beneficial effect is
> GC> /// realized only if no parent can be found.
> 
>  I'm not sure I understand the logic here: why is the extra task so evil? I
> believe the possibility to do something (potentially catastrophic) in a
> non-disabled window while the program is in an unstable state is a much
> worse evil. IOW, I think wxSafeShowMessage() should continue to use NULL as
> parent window argument but should also use MB_TASKMODAL.

Experimenting with ::MessageBox(0, ..., ..., MB_TASKMODAL)....

Suppose a "safe" messagebox pops up and I decide to write an email
about it. I go to my email program, start writing, then want to go
back to the application to copy the error message. Now I see two
icons for that application in the taskbar, which seems confusing;
I don't think many programs work that way. Anyway, I click on the
first icon, and...where's the error message? I don't see it. The
application looks like it's active, but I can't interact with it
in any way: even clicking its close box does nothing, though it
appears that everything is enabled. You and I know that this is
just a disabled top window, but not everyone realizes that.

At this point, some users would just say our application "crashed".
I know I can get to the messagebox by clicking the second icon on
the taskbar, which is the only one that shows up with "alt-Tab"
(though the "alt-Tab" display doesn't use the application icon).
But some users might not realize that.

Using a non-null HWND whenver possible means that when I focus the
application by any means whatsoever, I see the messagebox on top
of the application, which just looks right to me, and the "top"
window under the messagebox is disabled. Not only is it in fact
disabled, it's also visibly disabled: its title bar is grayed,
and I can't find any way to make it gain focus from the messagebox.
For an application that has only one top window, isn't this ideal?

I'd think we could at least do this whenever there is only one top
window. And isn't it fairly rare (though of course not unknown) to
have more than one?

However, if there is more than one top window, then yes, I guess
the user could do something catastrophic. In that case, however,
is it possible to disable every top window "manually" in wx until
the messagebox is dismissed? Even if it's a bother, still it's
code that need be written only once, and then everyone can benefit.
If, that is, it's actually possible; I haven't looked at this in a
while and don't remember whether we can get a list of top windows
from msw.

Worst of all is what happens with some other combination of
parameters that I don't remember exactly, but the behavior was
that, once you navigated temporarily to another program, the
messagebox was obscured by the screen and could be refocused only
by moving the top window aside.

No, wait--one could argue that ::wxSafeShowMessage() is even worse
than that, in cvs as of 20060605 at least. I just experimented with
that, and it exhibits both undesirable behaviors. The messagebox is
in a separate "task", the main window can hide it, and the top
window isn't disabled. I tried doing something that seemed safe in
the top window, and the program abended.

> GC> void safe_message_alert(char const* message)
> GC> {
> GC> #if !defined LMI_MSW
> GC>     std::fputs(message, stderr);
> GC>     std::fputc('\n', stderr);
> GC>     // Flush explicitly. C99 7.19.3/7 says only that stderr is
> GC>     // "not fully buffered", not that it is 'unbuffered'. See:
> GC>     //   http://sourceforge.net/mailarchive/message.php?msg_id=10388832
> GC>     //   http://sourceforge.net/mailarchive/message.php?msg_id=10826040
> GC>     std::fflush(stderr);
> GC> #else  // defined LMI_MSW
> 
>  Interesting. I can't access these links right now ("We're Sorry. The
> SourceForge.net Website is currently down for maintenance. We will be back
> shortly") but I thought that "not fully buffered" means either "unbuffered"
> or "line buffered" (i.e. flushed on newline) so this fflush() seems to be
> unnecessary. OTOH it surely does no harm.

I think I remember what they say. This is a recurring MinGW problem
report. Some people expect anything written to stderr to appear
immediately and unconditionally, even in a case like
  cerr << "Some message with no newline";
  abort();
or
  cerr << "Some message with no newline";
  code_that_causes_a_segfault();
Probably one of those links shows the gcc msw maintainer explaining
that such a hope goes beyond what the C or C++ standard requires.

There's another recurring problem report, with MSYS instead of MinGW
gcc (the shell, not the compiler) that displays similar symptoms but
has a different cause, IIRC. But both are fixed by flushing the
standard streams explicitly, which is necessary anyway in case of an
abend, so I figure it's always a good idea in a safe-message function.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]