Introduction
The following code will create a gray scale Windows Shutdown effect for Windows Forms.
Algorithm
- Create a bitmap image of the Windows form by capturing the screenshot of form.
- Convert the bitmap into grayscale.
- 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.
[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)
{
Graphics g = frm.CreateGraphics();
Size s = frm.Size;
Bitmap formImage = new Bitmap(s.Width, s.Height, g);
Graphics mg = Graphics.FromImage(formImage);
IntPtr dc1 = g.GetHdc();
IntPtr dc2 = mg.GetHdc();
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)
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++)
{
for (int j = 0; j < original.Height; j++)
{
Color originalColor = original.GetPixel(i, j);
int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59)
+ (originalColor.B * .11));
Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);
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)
{
panel1.BackgroundImage = MakeGrayscale(GetFormImage(this));
panel1.Visible = true;
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.