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