Re: Splash Screen - My Nemesis

"Eames, Andrew" <[email protected]> Thu, 26 Jul 2007 09:29:34 -0400
Newsgroups gmane.comp.windows.devel.dotnet.winforms
Message-ID <[email protected]>
I would first put together a clear statement of *exactly* what the
problem is (rather than vague hand waving) before trying to solve it.

In .NET 2.0, Forms have a Shown event which is raised exactly once after
a form is displayed for the first time. This is often a good time to
display errors 
  Andrew

-----Original Message-----
From: Discussion forum for developers using Windows Forms to build apps
and controls [mailto:[email protected]] On Behalf Of
Brady Kelly
Sent: Thursday, July 26, 2007 9:23 AM
To: [email protected]
Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis

I've only experience it now for the first time where I actually do
something
UI centric (except populating controls) in Load.  What do you guys
recommend
I do?  Set a timer and do the stuff I need to exception handle after
Load?

> -----Original Message-----
> From: Discussion forum for developers using Windows Forms to build
apps
> and controls [mailto:[email protected]] On Behalf Of
> Daniel Barla-Szabo
> Sent: 26 July 2007 15:05 PM
> To: [email protected]
> Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
>
> > handling exceptions in the Load ...  don't do it, it's unpredictable
>
> Same experience here - unpredictable...  quite frustrating the first
> time you run into it :)
>
>
> -----Original Message-----
> From: Discussion forum for developers using Windows Forms to build
apps
> and controls [mailto:[email protected]] On Behalf Of
> Greg Robinson
> Sent: 26 July 2007 01:58 PM
> To: [email protected]
> Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
>
> I am not going to argue with you.  Contact MS and listen to their
> feedback
> on handling exceptions in the Load.
>
> I may have said it the wrong way, but we saw all kinds of problems
with
> handling exceptions in the Load event handler when we first started
> working
> with .NET 5+ years ago.  We ended up calling MS and were pretty much
> told
> don't do it, it's unpredictable.
>
>
> -----Original Message-----
> From: Discussion forum for developers using Windows Forms to build
apps
> and controls [mailto:[email protected]]On Behalf Of
> Brady Kelly
> Sent: Thursday, July 26, 2007 7:54 AM
> To: [email protected]
> Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
>
>
> Now I've heard it all.  Just what do you think this code will do:
>
>         private void Form1_Load(object sender, EventArgs e)
>         {
>             try
>             {
>                 MakeDoodoo();
>             }
>             catch (Exception ex)
>             {
>                 MessageBox.Show(ex.Message);
>             }
>         }
>         private void MakeDoodoo()
>         {
>             throw new Exception("Just ignore me!");
>         }
>
>
>
> > -----Original Message-----
> > From: Discussion forum for developers using Windows Forms to build
> apps
> > and controls [mailto:[email protected]] On Behalf
Of
> > Greg Robinson
> > Sent: 26 July 2007 13:29 PM
> > To: [email protected]
> > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
> >
> > Exception Handling is ignored in the Load.
> >
> >
> >
> > -----Original Message-----
> > From: Discussion forum for developers using Windows Forms to build
> apps
> > and controls [mailto:[email protected]]On Behalf
Of
> > Brady Kelly
> > Sent: Wednesday, July 25, 2007 4:49 PM
> > To: [email protected]
> > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
> >
> >
> > Thank you so much Andrew!  This is the first code I've found tonight
> > that
> > worked a anything like it should, and I all wanted to do was 'whip
out
> a
> > splash screen quickly' for a small side project.  Whew!
> >
> > However, I have one problem: I'm using the splash screen to show
while
> I
> > query a database during the form load event handler.  If I get an
> error
> > in
> > this method, the splash screen simply hangs.  I tried adding a
static
> > Abort() method to the Splash class, which works but I still get
> > different
> > behaviours in the IDE and compiled.
> >
> > First, in the IDE, I get my desired MessageBox, but it the compiled
> app
> > there is none.  Here is my use of your code:
> >
> >         private void SearchGrid_Load(object sender, EventArgs e)
> >         {
> >             try
> >             {
> >                 SplashManager.Show(this, typeof(SplashScreen), new
> > TimeSpan(0, 0, 0, 0, 500));
> >                 InitControls();
> >             }
> >             catch (Exception ex)
> >             {
> >                 LogException(ex);
> >                 SplashManager.Abort();
> >                 MessageBox.Show(this, ex.Message, "Startup Error",
> > MessageBoxButtons.OK, MessageBoxIcon.Warning);
> >                 Close();
> >             }
> >             finally
> >             {
> >                 Cursor = Cursors.Default;
> >             }
> >         }
> >
> >
> >
> > > -----Original Message-----
> > > From: Discussion forum for developers using Windows Forms to build
> > apps
> > > and controls [mailto:[email protected]] On
Behalf
> Of
> > > Eames, Andrew
> > > Sent: 25 July 2007 21:52 PM
> > > To: [email protected]
> > > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis
> > >
> > > I too found a lot of incorrect ways to implement a splash screen.
> Many
> > > of the public domain implementations I looked at had subtle bugs
> > and/or
> > > race conditions in them too. I ended up writing the following code
> > which
> > > you are welcome to borrow
> > >   Andrew
> > >
> ----------------------------------------------------------------------
> > --
> > > ---------------------------------------------------------------
> > >   /// <summary>
> > >   /// Class that manages a splash screen
> > >   /// </summary>
> > >   public class SplashScreen
> > >   {
> > >     SplashScreen(Form parentForm, Type splashType, TimeSpan
> timeSpan)
> > >     {
> > >       parentForm_ = parentForm;
> > >       splashType_ = splashType;
> > >       timeSpan_ = timeSpan;
> > >       culture_ = CultureInfo.CurrentCulture;
> > >       parentForm.Shown += new EventHandler(OnParentShown);
> > >       Thread t = new Thread(new ThreadStart(SplashThread));
> > >       t.Start();
> > >     }
> > >
> > >     // This is the entry point for the thread that the splash
screen
> > > runs on
> > >     void SplashThread()
> > >     {
> > >       Thread.CurrentThread.CurrentCulture =
> > > Thread.CurrentThread.CurrentUICulture = culture_;
> > >       splashForm_ = (Form)Activator.CreateInstance(splashType_);
> > >       splashForm_.TopMost = true;
> > >       splashForm_.ShowInTaskbar = false;
> > >       splashForm_.FormBorderStyle =
FormBorderStyle.FixedToolWindow;
> > //
> > > prevents appearing in alt-TAB
> > >       splashForm_.StartPosition = FormStartPosition.CenterScreen;
> > >       splashForm_.HandleCreated += delegate {
> > > splashHandleCreated_.Set(); };
> > >       using (System.Windows.Forms.Timer timer = new
> > > System.Windows.Forms.Timer())
> > >       {
> > >         timer.Interval = (int)timeSpan_.TotalMilliseconds;
> > >         timer.Tick += delegate { timerExpired_ = true;
> MaybeClose();
> > };
> > >         timer.Start();
> > >         Application.Run(splashForm_);
> > >       }
> > >     }
> > >
> > >     void MaybeClose()
> > >     {
> > >       // We don't close the splash screen until both the timer has
> > > expired and the main form has shown itself
> > >       if (timerExpired_ && shown_)
> > >       {
> > >         // Note: We activate the parent form *before* closing the
> > splash
> > > form, otherwise the windows paint
> > >         // in a distracting way
> > >         try
> > >         {
> > >           parentForm_.Invoke(new foo(delegate {
> > parentForm_.Activate();
> > > }));
> > >         }
> > >         catch (InvalidOperationException)
> > >         {
> > >           // In case the parent has closed already!!
> > >         }
> > >         splashForm_.Close();
> > >         splashHandleCreated_.Close();
> > >       }
> > >     }
> > >     /// <summary>
> > >     /// Executed on the splash form thread
> > >     /// </summary>
> > >     void OnParentShown()
> > >     {
> > >       shown_ = true;
> > >       MaybeClose();
> > >     }
> > >
> > >     /// <summary>
> > >     /// Raised on the thread of the main form
> > >     /// </summary>
> > >     /// <param name="sender"></param>
> > >     /// <param name="e"></param>
> > >     void OnParentShown(object sender, EventArgs e)
> > >     {
> > >       parentForm_.Shown -= new EventHandler(OnParentShown);
> > >       // If the parent shows itself really quickly, its possible
> that
> > > the splash screen has
> > >       // not yet created its window, which is why we use this
event
> > >       splashHandleCreated_.WaitOne();
> > >       // Note we need to use BeginInvoke to avoid a potential
> deadlock
> > > since
> > >       // the splash form may Invoke an activate right back at us
> > >       splashForm_.BeginInvoke(new foo(OnParentShown));
> > >     }
> > >
> > >     /// <summary>
> > >     ///
> > >     /// </summary>
> > >     /// <param name="parentForm"></param>
> > >     /// <param name="splashType"></param>
> > >     /// <param name="time"></param>
> > >     public static void Show(Form parentForm, Type splashType,
> TimeSpan
> > > time)
> > >     {
> > >       new SplashScreen(parentForm, splashType, time);
> > >     }
> > >
> > >     TimeSpan timeSpan_;
> > >     Type splashType_;
> > >     Form parentForm_;
> > >     Form splashForm_;
> > >     CultureInfo culture_;
> > >     ManualResetEvent splashHandleCreated_ = new
> > ManualResetEvent(false);
> > >     bool shown_;
> > >     bool timerExpired_;
> > >   }
> > >
> > >   delegate void foo();
> > >
> > > -----Original Message-----
> > > From: Discussion forum for developers using Windows Forms to build
> > apps
> > > and controls [mailto:[email protected]] On
Behalf
> Of
> > > Brady Kelly
> > > Sent: Wednesday, July 25, 2007 3:39 PM
> > > To: [email protected]
> > > Subject: [DOTNET-WINFORMS] Splash Screen - My Nemesis
> > >
> > > Yes, I've just spent hours trying various examples that don't
work,
> > and
> > > I've
> > > just realised why people Callout actually _sell_ splash screen
> > products.
> > > My
> > > biggest grip so far is that in the compiled app, not in the IDE,
my
> > main
> > > window, from which I display my splash screen, always appears in
the
> > > background.
> > >
> > >
> > >
> > > My code is outrageously simple, with no status updates or
anything:
> > >
> > >
> > >
> > >         public SearchGridForm()
> > >
> > >         {
> > >
> > >             InitializeComponent();
> > >
> > >             splashScreen = new SplashScreen();
> > >
> > >             splashThread = new Thread(new
ThreadStart(ShowSplash));
> > >
> > >             splashThread.Start();
> > >
> > >         }
> > >
> > >
> > >
> > >         private void ShowSplash()
> > >
> > >         {
> > >
> > >             splashScreen.ShowDialog();
> > >
> > >         }
> > >
> > >
> > >
> > >         private void SearchGrid_Load(object sender, EventArgs e)
> > >
> > >         {
> > >
> > >             try
> > >
> > >             {
> > >
> > >                 Cursor = Cursors.WaitCursor;
> > >
> > >                 InitControls();
> > >
> > >             }
> > >
> > >             finally
> > >
> > >             {
> > >
> > >                 Cursor = Cursors.Default;
> > >
> > >                 splashThread.Abort();
> > >
> > >             }
> > >
> > >         }
> > >
> > >
> > > --


-- 
BEGIN-ANTISPAM-VOTING-LINKS
------------------------------------------------------

Teach CanIt if this mail (ID 9064002) is spam:
Spam:
http://mail-gw.cognex.com/canit/b.php?c=s&i=9064002&m=99f9fdc77e22
Not spam:
http://mail-gw.cognex.com/canit/b.php?c=n&i=9064002&m=99f9fdc77e22
Forget vote:
http://mail-gw.cognex.com/canit/b.php?c=f&i=9064002&m=99f9fdc77e22
------------------------------------------------------
END-ANTISPAM-VOTING-LINKS