Re: Splash Screen - My Nemesis
Peter Osucha <[email protected]> Wed, 25 Jul 2007 16:32:16 -0400
| Newsgroups | gmane.comp.windows.devel.dotnet.winforms |
|---|---|
| Message-ID | <[email protected]> |
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(); } }