Welcome Guest.   Make a donation to an author on the site October 22, 2014, 10:32:00 AM  *

Please login or register.
Or did you miss your validation email?


Login with username and password (forgot your password?)
Why not become a lifetime supporting member of the site with a one-time donation of any amount? Your donation entitles you to a ton of additional benefits, including access to exclusive discounts and downloads, the ability to enter monthly free software drawings, and a single non-expiring license key for all of our programs.


You must sign up here before you can post and access some areas of the site. Registration is totally free and confidential.
 
Learn about the DonationCoder.com microdonation system (DonationCredits).
   
   Forum Home   Thread Marks Chat! Downloads Search Login Register  
Pages: [1]   Go Down
  Reply  |  New Topic  |  Print  
Author Topic: Remove Flicker from Splash Screen  (Read 3181 times)
sukhjinder
Participant
*
Posts: 13


View Profile Give some DonationCredits to this forum member
« on: March 28, 2008, 02:52:43 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/
Logged
wraith808
Supporting Member
**
Posts: 6,416



"In my dreams, I always do it right."

see users location on a map View Profile WWW Read user's biography. Give some DonationCredits to this forum member
« Reply #1 on: March 28, 2008, 12:51:10 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:
[copy or print]
        [DllImport("user32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

Then you want to call
[copy or print]
LockWindowUpdate(this.Handle);
before your splash screen code, wrap the code in a try ... finally, and in the finally block, use the call
[copy or print]
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  embarassed
Logged

sukhjinder
Participant
*
Posts: 13


View Profile Give some DonationCredits to this forum member
« Reply #2 on: March 29, 2008, 11:32:03 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:52 AM by sukhjinder » Logged
sukhjinder
Participant
*
Posts: 13


View Profile Give some DonationCredits to this forum member
« Reply #3 on: March 29, 2008, 11:43:09 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
Logged
wraith808
Supporting Member
**
Posts: 6,416



"In my dreams, I always do it right."

see users location on a map View Profile WWW Read user's biography. Give some DonationCredits to this forum member
« Reply #4 on: March 29, 2008, 12:37:47 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.
[copy or print]
      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.

[copy or print]
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.
Logged

sukhjinder
Participant
*
Posts: 13


View Profile Give some DonationCredits to this forum member
« Reply #5 on: March 29, 2008, 10:31:01 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/letsyo/screenshots.html
Logged
Pages: [1]   Go Up
  Reply  |  New Topic  |  Print  
 
Jump to:  
   Forum Home   Thread Marks Chat! Downloads Search Login Register  

DonationCoder.com | About Us
DonationCoder.com Forum | Powered by SMF
[ Page time: 0.075s | Server load: 0.2 ]