Re: Splash Screen - My Nemesis
Greg Robinson <[email protected]> Thu, 26 Jul 2007 07:28:37 -0400
| Newsgroups | gmane.comp.windows.devel.dotnet.winforms |
|---|---|
| Message-ID | <[email protected]> |
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 > ------------------------------------------------------ > > NOTE: This message was trained as non-spam. If this is wrong, > please correct the training as soon as possible. > > Teach CanIt if this mail (ID 9056513) is spam: > Spam: > http://mail-gw.cognex.com/canit/b.php?c=s&i=9056513&m=08b08c6e418b > Not spam: > http://mail-gw.cognex.com/canit/b.php?c=n&i=9056513&m=08b08c6e418b > Forget vote: > http://mail-gw.cognex.com/canit/b.php?c=f&i=9056513&m=08b08c6e418b > ------------------------------------------------------ > END-ANTISPAM-VOTING-LINKS