Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / January 2007

Tip: Looking for answers? Try searching our database.

Stupid VS2005/ .NET 2.0 splash screen restrictions. Is there a solution.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Kevin - 24 Jan 2007 13:28 GMT
I have just moved from 1.1, where I had my splash screen to a tee, to
2.0 where I find it impossible to get a satisfactory solution and its
driving me mad!

This is how a splash screen SHOULD work (and did in 1.1) when you load
a program (MICROSOFT, please take note!!!):
Splash screen appears
Login screen appears, user enters credentials.
If the login was successful the login box disappears, and the main form
starts loading.  Whilst it is loading (which can take a few seconds) it
spits out messages to the splash screen (e.g. "retrieving accounts",
"populating listboxes" etc etc)
once the Main form has finished initialising it should appear BEHIND
the splash screen.
The splash screen should then disappear.

The whole time the splash screen should remain responsive with no
unpainted areas etc.  It is also useful to show a "please wait..." with
an increasing/decreasing number of full stops or a progress bar to show
the user that the program is doing things.
In 1.1 I achieved this by creating the splash screen on a different
thread to the main one and then calling delegates to update the message
etc.

Unfortunately in .NET 2.0 this has changed.  With the built in methods
for showing the splash screen, it basically shows the splash screen for
a predetermined amount of time and then it disappears and then creates
the main form.  Only then can you initialise the main form, at which
point the user is confronted with a blank screen whilst the
initialisation occurs.  No good.

With my old 1.1 way in 2.0, the program complains about crossthread
exceptions all the time because the splash screen is created on a
different thread.  Turning them off (with
control.checkforillegalcrossthreadenabled = false)causes random
crashes, and isnt an ideal solution anyway.

So how can I do it?  I need the splash screen to be responsive to
painting the whole time.  I have tried putting a thread on it which
updates it every 250 milliseconds, and then calls Application.DoEvents.
This works fine as long as nothing else is happening, but as soon as I
initialise my main form these stop as they get held up in the message
queue.

This example does a lot of what I am after:
http://www.codeproject.com/useritems/CustomSplashScreen.asp

However, it does not allow the ability to add a login screen as there
is no message pump.

Please can someone help me as I am going mad here.  Its such a simple
thing I am trying to do and yet it seems so hard!!!!
Thanks
Kevin
Stephany Young - 24 Jan 2007 21:36 GMT
So your prime gripe appears to be that MS arbitrarily fixed some 'bugs' that
allowed you to make illegal cross-thread calls in Framework 1.1? If that is
not what you mean then that is certainly how your post reads.

If you want to use your 'splash screen' and an 'early dialog' (login) before
your 'main form' is shown then simply make it so.

Uncheck the project setting that precludes you from doing this and put your
own code in place.

Your code from VB.NET 2003 will work with few modifications except that you
MUST craft your delegates and delegate handlers to avoid cross-thread calls.

>I have just moved from 1.1, where I had my splash screen to a tee, to
> 2.0 where I find it impossible to get a satisfactory solution and its
[quoted text clipped - 50 lines]
> Thanks
> Kevin
Bill Angus - 25 Jan 2007 07:09 GMT
I think there are a couple of different ways to do what you
want. I believe you could use a delegate function to update the
"splash_screen_form" from the other "main" form at different points as
main's initialization subroutine progresses. There is an
example of such a single-thread approach in the help file. I believe it
is in the progress bar example code... but the issue is the same.
One needs a progress-bar-dialog or splash-screen-dialog to get re-painted
properly and perhaps to remain
responsive to a control, while a lengthy process is going on. I can
post an example, but it would be just about a copy of what is in the
progressbar example code in the docs. NB it is necessary to make a call to
application.doevents() within the UIdelegate.
>I have just moved from 1.1, where I had my splash screen to a tee, to
> 2.0 where I find it impossible to get a satisfactory solution and its
[quoted text clipped - 50 lines]
> Thanks
> Kevin
Kevin - 25 Jan 2007 09:32 GMT
Thanks for your replies guys:

Stephany: I dont have a problem that MS have fixed the cross-thread
'bug', although it is very annoying that it breaks my splash screen.  I
do have a gripe that a) their built in method for splash screens is
absolute tripe, and b) they seem to have left me with no way to create
a form on a different thread that continuously updates whilst the main
GUI thread is busy.  This was possible in 1.1 even if it wasnt
'correct'.  I think you have missed my point; essentially what I need
is two GUI threads.  I do have my own main module (which is the startup
method) that creates a splash screen, login screen, then the main form
etc, but what I am saying is the splash screen becomes upresponsive
whilst the main for is being created and initialised (because the GUI
thread is too busy creating the main form to repaint the splash
screen).  My 1.1 code will not work with 2.0 no matter how many
delegates and invokes I use.

Bill: Thanks for your reply, I know the example you are talking about
but I dont think it helps me here.

To summarise, essentially what I require is two GUI threads, which does
not seem to be possible.

Thanks again
Kevin
Jon Skeet [C# MVP] - 25 Jan 2007 20:48 GMT
> Thanks for your replies guys:
>
> Stephany: I dont have a problem that MS have fixed the cross-thread
> 'bug', although it is very annoying that it breaks my splash screen.

Your splash screen was broken beforehand - you were just being lucky.
You were doing things you were explicitly told not to do in the
documentation.

> To summarise, essentially what I require is two GUI threads, which does
> not seem to be possible.

You can have two GUI threads - but you need to be careful with them,
that's all.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Kevin - 26 Jan 2007 10:45 GMT
Thanks for your reply Jon, much appreciated.

I have posted a sample solution to:
http://www.kevinandkiran.com/splash_screen_tester.zip
It is in VB.

This is essentially my current solution, although interestingly I get
errors in different places to my actual program.
This seems to work about 90% of the time, although I am getting the
occaisional "Cross-thread operation not valid:" exceptions on line 40
(Label2.Text &= ".") of FormSplash, despite the fact that I have
invoked it.

I have also had to comment out line 21
(frmSplash.SetOwnerThreaded(frmMain)) of modMain as this too is causing
the exception.  Strangely though my actual program allows this.

Line 11 should also really be frmLogin.ShowDialog(frmSplash) instead of
frmLogin.ShowDialog() so that the login screen appears in front of the
splash screen.  Again, my program allows this.

Thanks again
Kevin
Jon Skeet [C# MVP] - 26 Jan 2007 21:49 GMT
> Thanks for your reply Jon, much appreciated.
>
[quoted text clipped - 8 lines]
> (Label2.Text &= ".") of FormSplash, despite the fact that I have
> invoked it.

I suspect that problem is because you've got a race condition - you can
end up calling InvokeRequired (and changing the status message) before
you've called ShowDialog - in other words, before you start the message
loop for that thread. You're also *creating* the splash screen on a
different thread to the one you're starting it on - that, again, sounds
like a bad idea.

There's also the problem that you're never running a message loop for
the splash screen as far as I can see.

I'm not an expert on this topic, but I would suggest that:

1) You only create a GUI control on the thread you're going to run it
on
2) You call Application.Run before calling Show.

> I have also had to comment out line 21
> (frmSplash.SetOwnerThreaded(frmMain)) of modMain as this too is causing
> the exception.  Strangely though my actual program allows this.

That sounds like a really bad idea (calling it, I mean). Setting the
owner of one form to be a form which has a different message thread
can't be a good idea, IMO.

> Line 11 should also really be frmLogin.ShowDialog(frmSplash) instead of
> frmLogin.ShowDialog() so that the login screen appears in front of the
> splash screen.  Again, my program allows this.

Hmm... not sure on this one.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Kevin - 29 Jan 2007 09:35 GMT
ok, thanks for looking Jon.
Kevin

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.