Re: Splash Screen - My Nemesis
Brady Kelly <[email protected]> Wed, 25 Jul 2007 22:55:22 +0200
| Newsgroups | gmane.comp.windows.devel.dotnet.winforms |
|---|---|
| Organization | Chase Software |
| Message-ID | <[email protected]> |
Peter, I don't mind the main form not showing until the splash screen goes away, but until trying Andrew's example my main form was going to the background _when_ the splash screen went away. So the user would be watching the splash, and then, if I'm lucky[1], looking for the main form behind something else. [1] I'm not lucky - I've even been briefed to deploy only a single file as the client worries about users clicking the wrong files to runt the app. > -----Original Message----- > From: Discussion forum for developers using Windows Forms to build apps > and controls [mailto:[email protected]] On Behalf Of > Peter Osucha > Sent: 25 July 2007 22:49 PM > To: [email protected] > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis > > OK, then at least I'm calling it correctly. Perhaps I didn't understand > what Brady desired (which I thought was that the main form not show even > in the background until the splash screen went away). > > Thanks for the confirmation of the call, though. > > Peter > > > -----Original Message----- > From: Discussion forum for developers using Windows Forms to build apps > and controls [mailto:[email protected]] On Behalf Of > Eames, Andrew > Sent: Wednesday, July 25, 2007 4:39 PM > To: [email protected] > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis > > Yes - There's only 1 public method so only 1 way to use it:) > > e.g. > > parentForm = new MainForm(); > SplashScreen.Show(parentForm,typeof(mySplashScreen),TimeSpan.FromSeconds > (3)); > Application.Run(paentForm); > > Andrew > > -----Original Message----- > From: Discussion forum for developers using Windows Forms to build apps > and controls [mailto:[email protected]] On Behalf Of > Peter Osucha > Sent: Wednesday, July 25, 2007 4:32 PM > To: [email protected] > Subject: Re: [DOTNET-WINFORMS] Splash Screen - My Nemesis > > Andrew, > > Anytime I see a splash screen example, I look at it closely (hence, my > jumping in to this discussion). To be honest, I can't figure out how to > use the code you suggest below. > > It is apparent (I think!) that the intent is to call the static method > of this class to show the splash screen, presumably from the Main() > method of the application. That doesn't seem to work for me however. > Is that the intent? > > Peter > > -----Original Message----- > From: Discussion forum for developers using Windows Forms to build apps > and controls [mailto:[email protected]] On Behalf Of > Eames, Andrew > Sent: Wednesday, July 25, 2007 3: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(); > > } > > }