Solved

ShowModal doesn't return to calling window

Posted on 2011-03-25
10
472 Views
Last Modified: 2012-05-11
We have an app written in Delphi 7 that is used by about 1400 users. In a small number of cases (5 or 6) the program is not behaving properly when performing a ShowModal. We have the situation where the main form does
FormA.ShowModal;
then FormA does
FormB.ShowModal
then FormB does
FormC.ShowModal

You would expect then that when FormC does a Close, it should return to FormB. However what these users are getting is FormA is shown and FormB is buried underneath FormA.

Two questions then: Can anyone explain why this is happening on a limited number of machines?

Is there an easy way round it in the code? I've thought of putting Show for the calling form after every instance of AnotherForm.ShowModal but I'm not convinced this would work and as the overall project is more than a million lines long it would be a tedious task.

I believe in all cases the users concerned have Win XP Prof.
0
Comment
Question by:ChrisJonesLycos
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
10 Comments
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 35213666
this is a bug
i have never been able to pinpoint the exact cause

some workaround have been developed over the years
also some can be found here on EE:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_26286057.html
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_23461413.html
0
 

Author Comment

by:ChrisJonesLycos
ID: 35213727
Hi Geert. I think in theory your timer solution would work great. However I think what with the 100s of occurrences of ShowModal we have in the project it's a very big step to take. Also (like most developers) I'm a bit scared of rolling something like that to 1400 users (like 100 hours to roll it out) and then find that produces a different bug.

If I knew why Windows was doing this I could convince those specific users to change something in their system. Telling them it's a bug in Windows when all their colleagues don't have this problem is more than most of them are willing to believe.
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 35213801
I didn't say it's a bug in windows ... :)

i'm not exaclty sure where the bug is located
i know of other programs showing this problem written in Delphi (like toad from quest software)


as far as rollout and changing lots of forms is concerned ...
i share your anxiety to change for so many users.

a decade ago i started inheriting every form (shown to the end user) from a form class of my own
sort of a base form class
and providing ShowModal and procedures like such with a wrapper of my own

instead of having this:
type
  TFormXYZ = class(TForm)
    // etc
  end;

i have :
type
  TFormXYZ = class(TEndUserFormCategory)
  end;

I have only 4 or 5 different Categories
The work you have to do the first is indeed enormous.
But the time you save when a vendor introduces a new (not so nice) bug is also enormous

for instance: you have only 200 forms in your app X
you would have to check all 200 of those forms for the bug
I change 2, 3 maybe 4 of those base class forms

One other thing, if you have so many users, you need a better deployment system
Here we have some 400+ applications used among 3500 users
It takes us 1 click of a button to deploy a new version of a application
We used to do this manually until i was fed up with copying and created a deployment app

Every app starts with a shortcut
loader.exe %serverpath%\appname
>The loader looks for the app on the shared location,
>checks the size of the exe, checks the crc, if different, copies the new exe locally
>checks for any configuration changes for the registry
>starts the exe locally

only users restarting the app, will get the new version
> off course, later on we built in a messaging system to force a certain app to restart for all users

one other option is using a deployment tool, like LANDesk
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:FireW0lf
ID: 35213808
I dont use Delphi, but I've had similar issues in other prog languages (with a Modal from a Modal from a Modal), and this is how I got around it:

When opening a Modal window, send it the hWnd of the calling window. Then when it's closed, simply set the calling hWnd as the Focussed window and bring to front

Only adds a couple of lines to the code
0
 
LVL 37

Accepted Solution

by:
Geert Gruwez earned 500 total points
ID: 35213818
i think if you implement my timer solution in the main form
it should fix the problem
0
 
LVL 4

Expert Comment

by:FireW0lf
ID: 35213825
Oh, and just use the SetActiveWindow/SetFocus API calls to do the work for you
0
 

Author Closing Comment

by:ChrisJonesLycos
ID: 35213857
I think I'm going to go for Geert's timer solution as it's the simplest of all and probably the least risky in terms of introducing new bugs. Thanks.
0
 
LVL 25

Expert Comment

by:epasquier
ID: 35214183
I concur that this is a bug that happens with Delphi 5 & 7, pretty much the same kind of happens as in the expression "sh#t happens" ...

As far as I know, no-one ever found the reason, except maybe the guy who finally fixed it in Delphi code... Or they just got lucky and the problem disappeared by changing some other things.

If someone have leads on the reason, I'm interested.
0
 
LVL 22

Expert Comment

by:8080_Diver
ID: 35215907
Got to the party late; however, I will still add my $0.02. ;-)

This is why I use a slightly different approach from many (if not most) Delphi developers with regard to showing additional forms.  I put a completely public function (and, sometimes, overloaded it for slightly different circumstances) in the unit that contains the secondary function (i.e. the one being shown modally).  

By having that function in that unit:
I decouple the form from all other forms that may call it;
If I need to modify the code that performs the immediate actions of showing the form and then closing the form and returning to the calling form, I only have to do that in one place;
I only have to remember to Release the form in one place;
If I need to provide slightly different parameters for setting up the form, I can do so and I can make sure that it doesn't impact the rest of the calls to the form.

The major reason I started doing this was so that I could more readily reuse forms.  However, once I got started with it, I realized that decoupling the forms is important for even more reasons, one of which is in regard to rectifying the problem you site.
0
 
LVL 22

Expert Comment

by:8080_Diver
ID: 35215949
P.S. Most of my forms, I have also gotten in the habit of passing the identity of the calling form so that I can, among other things, execute a CallingForm.SetFRocus; and, if need be, a CallingForm.Show after the unit's form has been released..
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The password reset disk is often mentioned as the best solution to deal with the lost Windows password problem. In Windows 2008, 7, Vista and XP, a password reset disk can be easily created. But besides Windows 7/Vista/XP, Windows Server 2008 and ot…
It’s been over a month into 2017, and there is already a sophisticated Gmail phishing email making it rounds. New techniques and tactics, have given hackers a way to authentically impersonate your contacts.How it Works The attack works by targeti…
This video Micro Tutorial explains how to clone a hard drive using a commercial software product for Windows systems called Casper from Future Systems Solutions (FSS). Cloning makes an exact, complete copy of one hard disk drive (HDD) onto another d…
Windows 8 comes with a dramatically different user interface known as Metro. Notably missing from the new interface is a Start button and Start Menu. Many users do not like it, much preferring the interface of earlier versions — Windows 7, Windows X…

735 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question