Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows XP Grayscale Shutdown Effect in Windows Forms

0.00/5 (No votes)
15 Apr 2009 1  
How to create a Windows Shutdown effect in Windows Forms using C# and .NET.

shutdown-form.JPG

Introduction

The following code will create a gray scale Windows Shutdown effect for Windows Forms.

Algorithm

  1. Create a bitmap image of the Windows form by capturing the screenshot of form.
  2. Convert the bitmap into grayscale.
  3. Set the background image of a panel control to the grayscale bitmap and set its Dock property to Fill.

Using the code

Create a bitmap image of the Windows form

There is no direct way in .NET to capture a Windows form screen into a bitmap; therefore, we have to use the BitBlt function of gdi32.dll. The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.

//necessary function to create bitmap of form
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hWnd);

[DllImport("user32.dll", ExactSpelling = true)]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, 
       int nWidth, int nHeight, IntPtr hSrcDC, 
       int xSrc, int ySrc, int dwRop);

private Bitmap GetFormImage(Form frm)
{
    //get graphics object of the form
    //pixel of the object will be copied to the bitmap

    Graphics g = frm.CreateGraphics();
    Size s = frm.Size;

    //create blank bitmap of the size of form
    Bitmap formImage = new Bitmap(s.Width, s.Height, g);

    //create graphic object of the bitmap
    //the copied pixel will be transferred to this object
    Graphics mg = Graphics.FromImage(formImage);

    //get handles of the source and destinatio graphics objects
    //this handle will be used in BitBlt function
    IntPtr dc1 = g.GetHdc();
    IntPtr dc2 = mg.GetHdc();

    //here goes the function that will transfer 
    //bits block from form graphics object to bitmap
    BitBlt(dc2, 0, 0, frm.ClientRectangle.Width, 
           frm.ClientRectangle.Height, dc1, 0 , 0 , 13369376);

    g.ReleaseHdc(dc1);
    mg.ReleaseHdc(dc2);
    return formImage;
}

Convert the bitmap into a grayscale bitmap

public static Bitmap MakeGrayscale(Bitmap original)
{
    //make an empty bitmap the same size as original
    Bitmap newBitmap = new Bitmap(original.Width, original.Height);
    for (int i = 0; i < original.Width; i++)
    {
        for (int j = 0; j < original.Height; j++)
        {
            //get the pixel from the original image
            Color originalColor = original.GetPixel(i, j);
            //create the grayscale version of the pixel
            int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59)
                + (originalColor.B * .11));
            //create the color object
            Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
            //set the new image's pixel to the grayscale version
            newBitmap.SetPixel(i, j, newColor);
        }
    }
    return newBitmap;
}

Set the background image of a Panel control to the grayscale image and set its Dock property to Fill

private void btnExit_Click(object sender, EventArgs e)
{
    //set the background image of the panel with grey scale form image
    panel1.BackgroundImage = MakeGrayscale(GetFormImage(this));
    panel1.Visible = true;

    //dock this panel to fill the entire form
    panel1.Dock = DockStyle.Fill;

    if (DialogResult.Yes == MessageBox.Show("Do you want to Exit", 
                            "Exit Windows", MessageBoxButtons.YesNo))            
        Application.Exit();
    
    else
    {
        panel1.BackgroundImage = null;
        panel1.Visible = false;
    }
}

Points of interest

My code lacks two things, and with a little effort, this can be improved. I hope to do it in my next update. First, the transition from the color bitmap to the grayscale is done at once. We can produce a gradual transition by setting the background image to intermediate grayscale images. Second, the code runs in a single thread so the message box appear after the transition is done. With a multithreading approach, we can achieve the grayscale transition on a different thread.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here