Re: Bug in win xp: Auto-detaching modeless dialog.

From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 10/24/04


Date: Sun, 24 Oct 2004 01:48:52 -0400

As already pointed out, XP and 2000 have different ways of dealing with non-responding
windows; XP is far more sophisticated. There is no reason to expect a buggy program to
behave the same way on different platforms. The program is wrong, and a platform is free
to implement whatever it feels like to handle a defective program.

Replacing the sleep with a long computation says that the program is still deeply flawed;
don't do this. It won't work, and you will get bad behavior. Fix the program so it does
not do lengthy computations that block the GUI.

If painting while the structures will cause problems, then your program has other bugs. It
should not be trying to paint while structures are being modified, or, more to the point,
structures which are being modified should not be used for painting. You have to assume
that paint operations can happen at an time, without warning, and build your program to
deal with this.

Destroying the dialog is important whether there is a bug or not. All that happens is an
incorrect program becomes more incorrect if the dialog object is not deleted.

Long loops that block the message pump will "work", but you won't like the effects on the
GUI or the user.

Essentially XP is defined to do somehting special with non-responding programs. 2000 did
not do this. The secret is to not create programs that violate fundamental guidelines.
Write a program that violates the guidelines, and expect bad behavior. Microsoft does NOT
specify what is going to happen when you violate the guidelines, and therefore they are
free to do whatever they want to compensate for the failure to follow them.
                                                joe

On 23 Oct 2004 03:46:32 -0700, ril@op.pl (Ril) wrote:

>Thanx for the reply, but what you wrote is not the point. This program
>is intended to be only a bug demonstration, and to be as simple as
>possible. Normally I don't write in this style. In this program I
>don't care about anything that happens _after_ the bug occured,
>because it is irrelevant. I'm curious why the bug occures and how to
>avoid it.
>
>I used the CAboutDlg class instead of CDialog and used String::Format
>instead of itoa. but it didn't help.
>
>> I don't even know what "detatch" means, since there is no technical description of the
>> word "detach" in the Windows API with respect to windows.
>It's not an API term! It's a human description of the effect.
>
>> But with a deeply flawed
>> structure like you show here, any malfunction dealing with the GUI is not even worthy of
>> discussion. You have such a fundamental design flaw that nothing else matters.
>I don't think that windows API cares about design flaws. And using
>itoa can't affect this bug. Whether the style of the program is good
>or not, it should behave in the same way in Win XP and Win 2000
>
>>
>> The whole loop with a sleep in it is a colossal blunder. You have tied up the message pump
>> so the dialog is dead, dead, dead; the GUI is blocked, etc.
>And the message pump should be tied up wheather I use Win XP or Win
>2000, wheather I start from VS or not.
>
>
>> Fix the problem of sleeping in a loop that blocks the GUI first, and then you have something worth
>> talking about.
>If I replace sleeping with some time consuming calculations then the
>problem remains (you can just use ActiveSleep procedure). And I have
>to do it in this way, because this dialog is intended to show the
>progress. My program does some time consuming calculations and from
>time to time it has to indicate that another step of the calculation
>was made. All of those things must be done without passing the control
>to main program loop. I cannot allow WM_PAINT to the main program
>loop, because painting while internal data structures are being
>updated in the calculation process can lead to unpredictable results.
>
>
>> For example, the correct approach would be to put the modeless dialog variable as a
>> member variable of the CDialogTestView class, and create the dialog, and go away, having
>> set a timer:
>Normally I would update the caption after some part of calculation is
>done, not every 100ms.
>
>> Note that you need to make sure your modeless dialog has a PostNcDestroy handler
>Destoying the dialog box happens after the bug occured so it is
>irrelevant.
>
>>
>> You have to stop thinking like a console app programmer and start thinking like a Windows
>> programmer. Be very, very suspicious every time you think about writing a > Sleep()
>Sleep was just to make the code simply.
>
>>Long loops that block
>> the message pump but interact with the user are also suspect.
>But they should work.
>
>
> Either make them threads, or
>> drive them from events that don't block the message pump. Asynchronous, event-driven
>> programming is the paradigm of choice. You are using synchronous, procedural programming,
>> and it just doesn't fit the Windows model.
>If I need to make synchronous, procedural calculations then I don't
>want to make the things more complicated. I just don't want win xp to
>do some strange things with a blocked message loop.
>
>Ril
>ril@op.pl

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm