Other Software > Developer's Corner
Remove Flicker from Splash Screen
sukhjinder:
Creating Spalsh Screen from an Image in C#
Hi I need to create a Splash Screen from an Image file. The Splash Screen form should be of the same dimensions as the image file. The program should hide the Splash Screen when my MainForm is displayed.
Here is what I'm doing
class SplashScreen : Form
{
Image splashImage;
public SplashScreen()
{
this.TopMost = true;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = this.TransparencyKey = Color.White;
Image img = Bitmap.FromFile("splash.png");
Bitmap b = new Bitmap(img);
b.MakeTransparent(b.GetPixel(1,1));
this.BackgroundImage = splashImage = (Image) b;
this.Size = this.splashImage.Size;
}
}
class MainForm : Form
{
public static void main(String[] args)
{
// Some Code
SplashScreen splash = new SplashScreen();
splash.Show();
MainForm mainForm = new MainForm();
mainForm.Shown += delegate(object o, EventArgs ev)
{
splash.Hide(); //Hide and Dispose the Splash Form When mainForm is shown for the first Time
splash.Dispose();
mainForm.GetFocus();
};
// More Code
}
}
The Splash Image to be used can be downloaded from http://sukhjinder.cn/splash.png
With the above code I do get the splash screen and the behaviour as expected but before the splash screen is drawn I see a Black Rectangle flashing, with same dimensions as the splash image.
Please suggest. If you have a different approach please go ahead. All I want is to see a nice Splash Screen
Thanks
Sukhjinder
http://sukhjinder.cn/
wraith808:
What you're going to need to do is lock the window update.
in the SplashScreen, add a uses to use System.Runtime.Interopservices.
Then add the following code to your class:
--- --- [DllImport("user32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
Then you want to call
--- ---LockWindowUpdate(this.Handle);
before your splash screen code, wrap the code in a try ... finally, and in the finally block, use the call
--- ---LockWindowUpdate(IntPtr.Zero);
This should work... let me know if you need further explanation... didn't have time to test the actual code block right now :-[
sukhjinder:
Wow, It works wonderfully well.
But the Splash Image shows up randomly on the screen. I want it to appear centered.
Here is my code
public SplashScreen()
{
try
{
LockWindowUpdate(this.Handle);
this.TopMost = true;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = this.TransparencyKey = Color.White;
Image img = Bitmap.FromFile(LetsYoConfig.SplashFileName);
Bitmap b = new Bitmap(img);
b.MakeTransparent(b.GetPixel(1,1));
this.BackgroundImage = splashImage = (Image) b;
this.Size = this.splashImage.Size;
}
finally
{
LockWindowUpdate(IntPtr.Zero);
}
}
As you can see I have Splash Screen's start position as Centered (this.StartPosition = FormStartPosition.CenterScreen;) but it is still having random positions.
Please advice
Thanks
My Media Player
http://sukhjinder.cn/letsyo
Sorry about the delay in replying
sukhjinder:
My Workaround
+ Set the Splash Screen's StartPosition to Manual
+ Set Splash Screen's Location to Center of the Screen
+ Call LockWindowUpdate
+ Rest of the code
Code is
public SplashScreen()
{
try
{
Image img = Bitmap.FromFile(LetsYoConfig.SplashFileName);
SetSplashScreenPosition(img.Size.Width, img.Size.Height);
LockWindowUpdate(this.Handle);
this.TopMost = true;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = this.TransparencyKey = Color.White;
Bitmap b = new Bitmap(img);
b.MakeTransparent(b.GetPixel(1,1));
this.BackgroundImage = splashImage = (Image) b;
this.Size = this.splashImage.Size;
}
finally
{
LockWindowUpdate(IntPtr.Zero);
}
}
void SetSplashScreenPosition(int w, int h)
{
this.StartPosition = FormStartPosition.Manual;
Rectangle ScreenRect = Screen.PrimaryScreen.Bounds;
this.Location = new Point((ScreenRect.Width - w) / 2, (ScreenRect.Height - h) / 2);
}
If you see a better solution then please advice
Thanks
Sukhjinder
http://sukhjinder.cn/letsyo
wraith808:
All you have to do is set the properties that you are setting to be *before* the lock window update. I didn't notice this, but since they're after and some of the properties affect drawing, they're being ignored.
Put these before the lock window update.
--- --- this.TopMost = true;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
The reason that your 'workaround' works, is because of the same reason- it's before the lockwindowupdate.
And the LockWindowUpdate should be *outside* of the try...finally block. Always put what you're trying to catch outside- if something else happens to kill your app before you get to the initial LockWindowUpdate, you'll be trying to unlock without having locked. Not that this is necessarily going to do something bad... but it's not a good practice.
--- ---public SplashScreen()
{
this.TopMost = true;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterScreen;
LockWindowUpdate(this.Handle);
try
{
Image img = Bitmap.FromFile(LetsYoConfig.SplashFileName);
this.BackColor = this.TransparencyKey = Color.White;
Bitmap b = new Bitmap(img);
b.MakeTransparent(b.GetPixel(1,1));
this.BackgroundImage = splashImage = (Image) b;
this.Size = this.splashImage.Size;
}
finally
{
LockWindowUpdate(IntPtr.Zero);
}
}
That should fix your problem.
Navigation
[0] Message Index
[#] Next page
Go to full version