Click here to Skip to main content
Click here to Skip to main content

Fading Forms In and Out

By , 13 Aug 2007
Rate this:
Please Sign up or sign in to vote.
Screenshot - FadeForm.jpg

Introduction

Disclaimer: I am not the first to make a form fader, but I couldn't find one that did exactly what I wanted and so I created this.

I have had need in the past to cause my forms to perform fade transitions from one opacity to another. It was usually on load, close and window state changes. I finally decided to bring it all together in a nice, extendable Form. The FadeForm...

  • fades in on open.
  • fades out on close.
  • partially fades out on focus lost.
  • fades in on focus.
  • fades out on minimize.
  • fades in on restore.
  • must not annoy the user. Smile | :) A form fader definitely has that potential.

Using the Code

To use FadeForm, just extend it instead of Form and you are ready to go.

public class Form1 : FadeForm
{
     ...
}

It is defaulted to use the fade-in from nothing on open and out to nothing on close. It will also fade to 85% opacity when not the active window. You can set it to whatever you want, however.

//This would set the form with its default values.
this.ActiveOpacity=1;
this.InactiveOpacity=.85;
this.MinimizedOpacity=0;

You may, from time to time, want to disable the fade effect.

this.DisableFade(); //Turn off fade effects
this.EnableFadeDefaults(); //Turns on fade effects

You can also change the transition time.

this.FadeTime=1; //1 sec transition

You can also do a one-time fade to any value.

this.TargetOpacity=.25; //Fades the form to 25% opacity

Points of Interest

The opening and focus change events were easy to deal with. It was appropriate to use the built-in event listeners.

public FadeForm()
{
    ...
    this.timer.Tick += new System.EventHandler(this.timer_Tick);
    
    this.Deactivate += new System.EventHandler(this.FadeForm_Deactivate);
    this.Activated += new System.EventHandler(this.FadeForm_Activated);
    this.Load += new System.EventHandler(this.FadeForm_Load);
}

private void FadeForm_Load(object sender, EventArgs e)
{
   this.Opacity = minimizedOpacity;
   this.TargetOpacity = activeOpacity;
}

private void FadeForm_Deactivate(object sender, EventArgs e)
{
    this.TargetOpacity = inactiveOpacity;
}

private void FadeForm_Activated(object sender, EventArgs e)
{
    this.TargetOpacity = activeOpacity;
}

The minimize and close events where a little trickier because the actions had to be postponed until the fade transition was complete. I had to override WndProc in order to catch the request for those actions and postpone the action until the transition was done.

private const int WM_SYSCOMMAND = 0x112;
private const int WM_COMMAND = 0x111;
private const int SC_MINIMIZE = 0xF020;
private const int SC_RESTORE = 0xF120;
private const int SC_CLOSE = 0xF060; 

// Intercepts WindowMessages before they are processed.
protected override void WndProc(ref Message m)
{
    if (m.Msg==WM_SYSCOMMAND||m.Msg == WM_COMMAND) 
    {
        //Fade to zero on minimze
        if (m.WParam == (IntPtr)SC_MINIMIZE) 
        { 
            heldMessage = m;
            this.TargetOpacity = minimizedOpacity;
            return;
         }

         //Fade in if the window is restored from the taskbar
         else if (m.WParam == (IntPtr)SC_RESTORE 
           && this.WindowState == FormWindowState.Minimized) 
         { 
             base.WndProc(ref m);  
             this.TargetOpacity = activeOpacity;
             return;
         }

         //Fade out if the window is closed.
         else if (m.WParam == (IntPtr)SC_CLOSE) 
         { 
             heldMessage = m; 
             this.TargetOpacity = minimizedOpacity;
             return;
         }
     }
     base.WndProc(ref m);
}

Once that was done, all I had to do was perform the transitions.

//Performs fade increment.
private void timer_Tick(object sender, EventArgs e)
{
    double fadeChangePerTick = timer.Interval * 1.0 / 1000 / fadeTime;

    //Check to see if it is time to stop the timer
    if (Math.Abs(targetOpacity - this.Opacity) < fadeChangePerTick)
    {
        //There is an ugly black flash if you set the Opacity to 1.0
        if (targetOpacity == 1) this.Opacity = .999;
        else this.Opacity = targetOpacity;
        
        //Process held Windows Message.
        base.WndProc(ref heldMessage);
        heldMessage = new Message();
        
        //Stop the timer to save processor.
        timer.Stop();
    }
    else if (targetOpacity > this.Opacity) this.Opacity += fadeChangePerTick;
    else if (targetOpacity < this.Opacity) this.Opacity -= fadeChangePerTick;
}

It is interesting to notice that the opacity is never actually 1. That was a hack on my part to keep the window from flashing black. I am not sure what the cause of this is, but the fix was easy, so I may never know.

You can see that I stop the timer after I reach my target opacity. You may wonder how it gets started. Every time I set TargetOpacity, the set method starts the timer. There's no sense running the timer and wasting processor power when you don't need it.

private double TargetOpacity
{
    set
    {
        targetOpacity = value;
         if (!timer.Enabled) timer.Start();
    }
    get 
    { 
        return targetOpacity; 
    }
}

I think I made it about as easy as possible. I always like to adhere to the KISS principle: Keep it simple, stupid.

Thoughts

I plan to add a Notify(int n) method that will oscillate the opacity n times in order to get the user's attention. I also think it would be nice to give a choice between mouseover-based and focus-based transitions.

History

  • 13 August, 2007 -- Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nicholas Seward
Instructor / Trainer
United States United States
I am a mechanical engineer that works as a high school math teacher in Mulberry, Arkansas. I use programming as one way to keep my mind sharp.

Comments and Discussions

 
Generalblack flash Pinmemberroundy7215-Mar-09 9:23 
GeneralRe: black flash PinmemberNicholas Seward15-Mar-09 15:49 
I still don't know why the black flash happens. I suspect that windows uses a lightweight rendering engine when dealing with opaque forms and then transitions to the heavy weight one when rendering transparent forms. If that was in fact true it would make it very problematic for windows to double buffer the display while the new engine was starting up. If anybody can point me to a resource that will provide a definite answer for why a black flash occurs, I am still very curious. The .999 hack, while simple, has got to increase the cpu usage. (I assume transparent forms are harder to display.)
 
Nicholas Seward

GeneralRe: black flash PinmemberAtanas Palavrov1-Apr-09 16:37 
GeneralRe: black flash PinmemberAtanas Palavrov12-May-09 9:14 
GeneralRe: black flash [modified] PinmemberNicholas Seward12-May-09 10:13 
GeneralRe: black flash PinmemberAtanas Palavrov14-May-09 3:54 
GeneralRe: black flash PinmemberNicholas Seward14-May-09 5:49 
GeneralSystem ERROR Occured in Application Pinmembercoolpul6-Sep-08 2:50 
General.999 opacity and layout execution time Pinmembernukefusion26-Nov-07 4:10 
GeneralGeneral Comments Pinmemberchris17522-Aug-07 2:25 
GeneralRe: General Comments PinmemberNicholas Seward26-Aug-07 7:05 
GeneralRe: General Comments Pinmemberchris17527-Aug-07 1:13 
GeneralRe: General Comments PinmemberNicholas Seward27-Aug-07 4:46 
GeneralRe: General Comments Pinmemberchris17527-Aug-07 8:44 
GeneralRe: General Comments PinmemberNicholas Seward27-Aug-07 10:25 
GeneralRe: General Comments Pinmemberchris17527-Aug-07 8:54 
QuestionDoes it work with VB .Net ? PinmemberPatrice Dargenton22-Aug-07 0:26 
AnswerRe: Does it work with VB .Net ? PinmemberNicholas Seward26-Aug-07 6:58 
GeneralRe: Does it work with VB .Net ? PinmemberPatrice Dargenton27-Aug-07 1:54 
GeneralMDI child PinmemberWindows M15-Aug-07 4:10 
GeneralRe: MDI child PinmemberNicholas Seward16-Aug-07 14:42 
GeneralRe: MDI child PinmemberWindows M16-Aug-07 21:56 
GeneralCool... Pinmemberdgauerke13-Aug-07 8:41 
GeneralRe: Cool... PinmemberNicholas Seward13-Aug-07 19:04 
GeneralRe: Cool... Pinmemberddmccrory16-Aug-07 1:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 13 Aug 2007
Article Copyright 2007 by Nicholas Seward
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid