Hi,
It is a common question yet there is no answer for it.
My application uses a splash screen, I copied its code from a sample. In VS it works fine, after the closing of splash screen the main form gets focused. Starting from Explorer, only the splash screen is visible, the main form remains in the background.
The splash screen is called from the constructor of the main form and started on a separate thread. After the main form did its job, the splash screen is closed. The code of it:
Code Snippet
public MyApp() (
InitializeComponent(); Thread th = new Thread(new ThreadStart(DoSplash)); th.Start(); DoLoadingJob(Jobs.RedirectSatellite); MethodInvoker mi = new MethodInvoker(CloseSplash); Thread.Sleep(1000); splash.Invoke(mi); th = null; splash = null; Application.DoEvents(); this.Focus();
}
By using the method above the main form remains in background. I found/conducted a semi-solution by using API functions with P/Invoke. Here is the code:
Code Snippet
this.TopMost = true; SetForegroundWindow(this.Handle); SwitchToThisWindow(this.Handle, true); this.TopMost = false;
The result: I have a visible main form with blinking notification on tray of resetting active window. Marvellous and very ugly. So can anyone tell the proper way of how to dispose splash screen and bring main form back?
|
| nologin Saturday, March 01, 2008 1:05 AM |
| andriscs wrote: |
No, my VS looks different.
Here it is.
| |
Code Snippet
private void Form1_Load(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.CenterScreen;
this.splash.Show();
this.Activated += new EventHandler(Form1_Activated);
}
void Form1_Activated(object sender, EventArgs e)
{
this.splash.t_Tick(sender, e);
}
public Form1()
{
InitializeComponent();
this.SuspendLayout();
this.StartPosition = FormStartPosition.CenterScreen;
this.ResumeLayout();
}
Code Snippet
private void SplashScreen_Load(object sender, EventArgs e)
{
// code removed
}
private void PositionWindow()
{
this.StartPosition = FormStartPosition.CenterScreen;
}
internal void t_Tick(object sender, EventArgs e)
{
this.Close();
}
The splash form's position will depend upon how your Form1 is positioned.
Rudedog |
| Rudedog2 Saturday, March 01, 2008 3:04 PM |
This shows keeping the splash screen responsive while it is shown:
Code Snippet
Form2 SplashScreen = new Form2();
int minimunDisplayTime = 5000;
private void Form1_Load(object sender, EventArgs e)
{
SplashScreen.Show();
DateTime startTime = DateTime.Now;
int cnt = 0;
do
{
System.Threading.Thread.Sleep(100);
//Simulates performing time consuming process.
cnt++;
Application.DoEvents();
} while (cnt < 10);
int timeDisplayed = (DateTime.Now - startTime).Milliseconds;
if (timeDisplayed < minimunDisplayTime)
{
do
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
timeDisplayed += 100;
} while (timeDisplayed < minimunDisplayTime );
}
SplashScreen.Close();
}
|
| JohnWein Saturday, March 01, 2008 9:59 PM |
I use this in my main form.
Code Snippet
private void Form1_Load(object sender, EventArgs e)
{
SplashScreen splash = new SplashScreen();
// do place here, place above lineoutside of thismethod
this.splash.ShowDialog();
}
I use this for the SplashScreen;
Code Snippet
private void SplashScreen_Load(object sender, EventArgs e)
{
Timer t = new Timer();
t.Interval = 3000;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
this.Close();
}
Rudedog |
| Rudedog2 Saturday, March 01, 2008 3:28 AM |
It could work I guess but I believe that a splash screen needs to be shown until the loading job is finished. In my case it can be from 5 second to ten thousand seconds. Calibrating a timer for it is not an option as I don't know how long the loading job runs. In your case I guess it is just a design element showing it for 3 seconds (I guess most of the times splash screen hides initial loading of the main form).
|
| nologin Saturday, March 01, 2008 10:23 AM |
Have you tried to set the Splash screen in the project properties instead of writing your own code?
|
| Ralf de Kleine XCESS Saturday, March 01, 2008 10:39 AM |
What do you mean by that? I didn't set anything in the Properties, the calling code is in the main form's constructor.
|
| nologin Saturday, March 01, 2008 10:46 AM |
Ok,
What i'm trying to say is this
1. Set your Form1 as Startup form in your application properties 2. Set your Splashscreen as Splash screen in your application properties
This way you dont have to work with threading and when the Form1 form is ready loading(page_load) the Splashscreen closes automaticaly.
|
| Ralf de Kleine XCESS Saturday, March 01, 2008 10:57 AM |
Well, I found 12 tabs in project properties, none of them contained anything about splash screen. One occurence of Startup object is found and I can choose between Not set and MyApp.Program. Can you exactly tell which menu and tab to look for?
|
| nologin Saturday, March 01, 2008 11:12 AM |
Which version of vs are you using? image |
| Ralf de Kleine XCESS Saturday, March 01, 2008 11:47 AM |
I am using Microsoft Visual Studio 2008 Team System. Though my project is C# and yours is VB, does it matter?
|
| nologin Saturday, March 01, 2008 11:58 AM |
Just checking...
Have you seen the image and does it help you?
|
| Ralf de Kleine XCESS Saturday, March 01, 2008 12:05 PM |
No, my VS looks different. Here it is. |
| nologin Saturday, March 01, 2008 12:08 PM |
Hmm the problem is the difference between VB and C#. The splashscreen property is only available for VB, to bad. Sorry that I can't be of more help.
|
| Ralf de Kleine XCESS Saturday, March 01, 2008 12:22 PM |
| andriscs wrote: |
No, my VS looks different.
Here it is.
| |
Code Snippet
private void Form1_Load(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.CenterScreen;
this.splash.Show();
this.Activated += new EventHandler(Form1_Activated);
}
void Form1_Activated(object sender, EventArgs e)
{
this.splash.t_Tick(sender, e);
}
public Form1()
{
InitializeComponent();
this.SuspendLayout();
this.StartPosition = FormStartPosition.CenterScreen;
this.ResumeLayout();
}
Code Snippet
private void SplashScreen_Load(object sender, EventArgs e)
{
// code removed
}
private void PositionWindow()
{
this.StartPosition = FormStartPosition.CenterScreen;
}
internal void t_Tick(object sender, EventArgs e)
{
this.Close();
}
The splash form's position will depend upon how your Form1 is positioned.
Rudedog |
| Rudedog2 Saturday, March 01, 2008 3:04 PM |
If you want to show a splash screen while your main form is loading, show the splash screen in the beginning of the load event of the main formusing Show, not ShowDialog. At the end of the load event, close the splash screen. |
| JohnWein Saturday, March 01, 2008 4:52 PM |
| JohnWein wrote: |
|
If you want to show a splash screen while your main form is loading, show the splash screen in the beginning of the load event of the main formusing Show, not ShowDialog. At the end of the load event, close the splash screen.
| |
I had already posted that tip using Show, not ShowDialog.
What if you want the splash screen to be visible for a minimum amount of time?
I use the earlier code to show for 3 seconds.
If the application is not ready, I don't care.
The user waits. He knows the app is starting up. |
| Rudedog2 Saturday, March 01, 2008 5:24 PM |
So you tell me to paste the original code to the Load method of my main form? I did it and now my splash screen is not visible. I read that constructor is the first that runs and Load is executed later, and it is not recommended to use threads in contructors. This code shows nothing:
Code Snippet
private void GUI_Load(object sender, EventArgs e) { splash = new Splash(); splash.Show();
DoTheJob();
splash.Close();
} |
| nologin Saturday, March 01, 2008 6:46 PM |
If you want the splash screen to display for a minimum time, don't exit the load event until that time has elapsed:
Code Snippet
Form2 SplashScreen = new Form2();
int minimunDisplayTime = 5000;
private void Form1_Load(object sender, EventArgs e)
{
SplashScreen.Show();
DateTime startTime = DateTime.Now;
//Do time consuming processing
TimeSpan timeDisplayed = DateTime.Now - startTime;
if (timeDisplayed.Milliseconds < minimunDisplayTime)
System.Threading.Thread.Sleep(minimunDisplayTime - timeDisplayed.Milliseconds);
}
|
| JohnWein Saturday, March 01, 2008 7:21 PM |
| JohnWein wrote: |
|
If you want the splash screen to display for a minimum time, don't exit the load event until that time has elapsed:
Code Snippet
Form2 SplashScreen = new Form2();
int minimunDisplayTime = 5000;
private void Form1_Load(object sender, EventArgs e)
{
SplashScreen.Show();
DateTime startTime = DateTime.Now;
//Do time consuming processing
TimeSpan timeDisplayed = DateTime.Now - startTime;
if (timeDisplayed.Milliseconds < minimunDisplayTime)
System.Threading.Thread.Sleep(minimunDisplayTime - timeDisplayed.Milliseconds);
}
| |
John,
I use the timer because my splash has a progress bar. When the thread sleeps, so does the progressbar. I found the timer method kept the progress bar alive, so I use that method.
..And thanks for that thread timeout snippet....
Rudedog |
| Rudedog2 Saturday, March 01, 2008 8:56 PM |
This shows keeping the splash screen responsive while it is shown:
Code Snippet
Form2 SplashScreen = new Form2();
int minimunDisplayTime = 5000;
private void Form1_Load(object sender, EventArgs e)
{
SplashScreen.Show();
DateTime startTime = DateTime.Now;
int cnt = 0;
do
{
System.Threading.Thread.Sleep(100);
//Simulates performing time consuming process.
cnt++;
Application.DoEvents();
} while (cnt < 10);
int timeDisplayed = (DateTime.Now - startTime).Milliseconds;
if (timeDisplayed < minimunDisplayTime)
{
do
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
timeDisplayed += 100;
} while (timeDisplayed < minimunDisplayTime );
}
SplashScreen.Close();
}
|
| JohnWein Saturday, March 01, 2008 9:59 PM |
|
| Rudedog2 Saturday, March 01, 2008 10:39 PM |