Windows 上的 Windows XP 灰度关机效果(使用 Windows Forms)






4.45/5 (7投票s)
如何使用 C# 和 .NET 在 Windows Forms 中创建 Windows 关机效果。
引言
以下代码将在 Windows Forms 中创建一个灰度 Windows 关机效果。
算法
- 通过捕获窗体截图来创建 Windows 窗体的位图图像。
- 将位图转换为灰度图。
- 将面板控件的背景图像设置为灰度位图,并将其
Dock
属性设置为Fill
。
使用代码
创建 Windows 窗体的位图图像
.NET 中没有直接的方法可以将 Windows 窗体屏幕捕获到位图中;因此,我们必须使用 gdi32.dll 的 BitBlt
函数。BitBlt
函数执行从指定源设备上下文到目标设备上下文的像素矩形颜色数据的位块传输。
//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;
}
将位图转换为灰度位图
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;
}
将面板控件的背景图像设置为灰度图像,并将其 Dock 属性设置为 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;
}
}
关注点
我的代码缺少两点,稍加努力就可以改进。我希望在下次更新中实现。首先,彩色位图到灰度图的转换是立即完成的。我们可以通过将背景图像设置为中间灰度图像来产生渐变过渡。其次,代码在单个线程中运行,因此消息框在过渡完成后才会出现。通过多线程方法,我们可以在不同的线程上实现灰度过渡。