topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday March 29, 2024, 5:45 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: Remove Flicker from Splash Screen  (Read 7181 times)

sukhjinder

  • Participant
  • Joined in 2007
  • *
  • Posts: 13
    • View Profile
    • Donate to Member
Remove Flicker from Splash Screen
« on: March 28, 2008, 02:52 AM »
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

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,186
    • View Profile
    • Donate to Member
Re: Remove Flicker from Splash Screen
« Reply #1 on: March 28, 2008, 12:51 PM »
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

  • Participant
  • Joined in 2007
  • *
  • Posts: 13
    • View Profile
    • Donate to Member
Re: Remove Flicker from Splash Screen
« Reply #2 on: March 29, 2008, 11:32 AM »
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

« Last Edit: March 29, 2008, 11:39 AM by sukhjinder »

sukhjinder

  • Participant
  • Joined in 2007
  • *
  • Posts: 13
    • View Profile
    • Donate to Member
Re: Remove Flicker from Splash Screen
« Reply #3 on: March 29, 2008, 11:43 AM »
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

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,186
    • View Profile
    • Donate to Member
Re: Remove Flicker from Splash Screen
« Reply #4 on: March 29, 2008, 12:37 PM »
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.

sukhjinder

  • Participant
  • Joined in 2007
  • *
  • Posts: 13
    • View Profile
    • Donate to Member
Re: Remove Flicker from Splash Screen
« Reply #5 on: March 29, 2008, 10:31 PM »
My Final solution

public SplashScreen()
      {
         
         this.TopMost = true;
         this.ShowInTaskbar = false;
         this.FormBorderStyle = FormBorderStyle.None;
         this.StartPosition = FormStartPosition.CenterScreen;
         
         Image img = Bitmap.FromFile(LetsYoConfig.SplashFileName);
         this.Size = img.Size;

         LockWindowUpdate(this.Handle);
         
         try
         {
            this.BackColor = this.TransparencyKey = Color.White;
            
            Bitmap b = new Bitmap(img);
            this.BackgroundImage = splashImage = (Image) b;
         }
         finally
         {
            LockWindowUpdate(IntPtr.Zero);
         }
      }

Everything works as expected.
Thank you.

I have some more issues relating to drawing custom controls for my Opensource Mediaplayer LetsYo. If you are intersted and can donate some time of yours please visit my project home page http://sukhjinder.cn/letsyo. Screenshots at http://sukhjinder.cn...syo/screenshots.html