AwesomeForm - 可能是最好的窗体扩展。






1.53/5 (11投票s)
2007年3月27日
4分钟阅读

37879

683
它是一个窗体,用“弄脏”的下面内容图像来绘制自己的背景。它是半透明的,并且只支持 GDI+。

引言
所以,我前几天突然有个想法,我真的希望我项目中的一个窗体的背景是半透明的。遗憾的是,.NET 2.0 不支持此功能。看起来 .NET 3.0 似乎支持,但我还没更新到那么新,所以我不得不自己动手。总之,过了一段时间,我弄出了点东西,现在就分享出来。
正如你从图片中看到的,效果相当不错。我往示例应用中添加了一个按钮和一个 DateTimePicker!哦,这是为了让你看到,与设置窗体的 Opacity 值不同,使用这个窗体时,上面的控件的 Opacity 不会受到影响。
背景
起初,我非常兴奋,因为我发现 `Form` 类有一个 `Opacity` 成员。然后,当我尝试使用 `Opacity` 来达到我想要的效果时,我很沮丧。我很沮丧,因为将此值设置为 50% 意味着窗体上的每个控件的透明度也变为 50%。这完全不是我想要的!
使用代码
代码使用起来非常简单。你知道当你开始一个新的 Windows Forms 项目时,它会创建一个名为 Form1.cs 的文件吗?要使用这段代码,你只需要让 `Form1` 继承自 `AwesomeForm` 而不是 `System.Windows.Forms.Form`。当然,还要确保编译器能找到我的代码。如果你不知道这是什么意思,可以看看示例代码。它很直接。
它是如何工作的?
许多人已经被说服,认为我通过仅使用 GDI+ 来实现这一点是一位天才。不幸的是,我不是天才,我只是有个想法,然后找到了一些好的代码示例。
我想指出的第一个代码示例是 Google Talk 风格的 Windows Form,它让我萌生了制作自己的 `Form` 的想法。它比我的项目完整得多,所以如果你正在寻找那样的东西,我强烈推荐它。是的,我知道,我的甚至没有最大化按钮。也许有一天吧……
我找到的最有用的代码示例可能来自 tommy.blog。任何尝试用 .NET 来截屏的人都见过很多烦人的 Interop 代码,而这本应是一个非常简单的功能。好吧,它其实可以很简单。
g.CopyFromScreen(this.Left, region.Top, 0, 0, region.Size);
哇!这只需要一行 C# 代码!没有 Interop,你唯一需要的是一个 `Graphics` 对象和一个你想要捕获的区域!
所以,下面是我用来获取窗体下方屏幕内容的代码。它很简单,并且基于上述的截屏方法,但有一个技巧。你能发现吗?
private Bitmap GetBackground()
{
Bitmap rval = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(rval);
Point loc = this.Location;
this.Opacity = 0;
g.CopyFromScreen(loc.X, loc.Y, 0, 0, rval.Size);
this.Opacity = 1;
using (SolidBrush sb = new SolidBrush(Color.FromArgb(208, this.BackColor)))
g.FillRectangle(sb, new Rectangle(0, 0, rval.Width, rval.Height));
return rval;
}
没错,要获取窗体下方的屏幕内容,我们必须先隐藏窗体!我通过将 `Form` 的 `Opacity` 设置为 0 来实现,使其完全透明,然后截屏,再将其恢复为 1。我的第一个想法是设置 `Visible = false`,但这显然是个糟糕的主意。程序会从任务栏消失,这很烦人,并且无法拖动窗体,因为每次窗体制图时都会变得不可见,从而取消了拖动操作。
如果你想在常规 `Form` 中使用这段代码,它也能工作,但你必须稍微调整一下数字才能使其看起来正确。我使用 `loc` 作为截屏的地点,并且因为我使用的是无边框 `Form`,所以我可以直接使用窗体的位置。如果你使用的是常规窗体,这将不起作用。我感觉我在这里遗漏了什么愚蠢的东西,但由于我不在常规窗体中使用它,所以我没太担心。
问题
目前有一些性能问题。不过没关系,因为这是第一个版本,而且我今天才开始做。最明显的问题是,当你在桌面上拖动窗口时,更新有点慢,但也不是太糟糕。另外,我还没有实现任何在窗口后面的屏幕内容独立于窗口发生变化时的重绘功能。所以,比如你最小化了一个在这个窗口下面的窗口,这个窗口仍然会显示那个窗口的内容,直到它决定重绘自己为止。